1966年的电信法案,本来初衷是为了增加竞争,减少垄断。确实这个法案刚开始也增加了各种中小型企业的入局。美国电信行业的经营模式,是设备商贷款给服务商,然后服务商发展壮大了,再把利润返还给设备商去还贷款。就类似与华为贷款给移动公司去修基站。刚开始没有用户,等用的人多了,钱收回来了,华为的贷款自然就收回来了。这种模式导致的问题就是,中小型乱入以后,盲目扩张,设备商大量借款给他们,最后资不抵债,许多企业破产,导致上游的企业也那不回钱来,引发了大量的债务危机。 还有就是通信标准林立,各家都出台自己的通信标准,国家没有做好统一的把控。就导致大家研究的方向不统一。公司一旦破产,之前所做的努力可能都没办法再别的公司重新利用,一切都归零。还有就是,标准不统一,各自为战,都欧洲巨头或者其他的国家队进场的时候,无法做到有效对抗,最后难免衰退的命运。
使用ec2搭建的springboot的服务,偶尔会碰到一些问题,导致service挂掉。为了保证服务的可持续性,打算使用cloudwatch+lambda自动监视,实现service的自动重启。 cloudwatch,主要用来监视,报警,可以设置为5分钟内healthcheck ng的情况下,报警到sns。然后sns的通知,又可以是lambda的trigger。这样就可以让lambda去重启server了。
上次说了几个使用DI为前提的情况下的测试速度优化方案。这里想再总结下怎么通过不使用DI(Standalone模式)去进行测试。 然后这次总结的主要是Repository层面的Standalone模式的测试。需要实现Standalone模式,主要需要解决这么几个问题: 创建DataSource 创建EntityManager 创建DSLContext(如果使用了jooq) 实例化JpaRepository 创建DataSource可以参考下面这段代码,当然最好这些property可以从spring的配置文件里读取。 创建EntityManager的话,主要有两种方式,一种是带transacation的: 还有一种是不带transacation的: DSLContext的话,像下面这种方法比较简单: 最后,如果你使用了JpaRepository,那么就需要对它实例化才能使用: 在我的项目中,因为还使用了Customize的JpaRepository,所以这里还有另外一种写法:
最近有个项目,需要对接把系统的master数据同步到salesforce。第一次接触salesforce,认证这块儿也不是特别懂。查阅了官方的文档,因为这次对接是服务器到服务器端,最后发现有下面两种方式可以采用: Username-Password Flow Server-toServer Flow Username-Password Flow的话,实现起来比较简单,像下面这样指定grant_type=password类型,然后附上其他相关参数就能获得sessionId,后面的通信中,在header 里设置 Authorization: Bearer sessionId就OK了。但是,这个方式虽然简单,官方当前已经不推荐了。因为把账号密码放在get request的parameter中的做法实在是风险太大了。万一泄漏,整个salesforce账号都很危险。 所以,最后还是决定使用更安全的Server-to-Server Flow。这个用法相对来说也更加复杂一些。具体实现大概有这么几个步骤: 1. 创建并上传签名证书 创建电子签名,主要需要以下几个步骤:– 创建密钥– 创建公钥– 创建证书以上都可以通过openssl命令实现: 密钥的话,需要自己保存,只有自己有权限。打开文件的话,可以看到 —–BEGIN RSA PRIVATE KEY—–
1. profile跟property的mapping 启动Spring时,通过-Dspring.profiles.active指定有效的profile,然后spring就会找到相应的property。application.yml,这个是默认加载的文件。如果参数传递进来的profile是develop,那么spring会按照application.yml→application-develop.yml的顺序去下载配置文件。如果两个文件中有重复的key,后面的develop.yml的优先等级更高。 2. module间的包含关系 通过在配置文件中定义spring.profiles.include可以实现包含关系。一般这种应用场景如下:假设我们有如下几个module– web– batch– infraweb跟batch都调用了infra,那么如果我们在infra里面定义了property的话,同样也需要在web跟batch里面重复定义。为了避免这种情况,就可以通过include去包含其他module里面的property文件。 # web/batch # infra
多对一的时候,@OneToMany要写明关联entity侧的变量名 像这个例子里写的一样,@OneToMany(mappedBy = “user”) 要协商mappedBy = “user”,这个user对应的是UserApp的@ManyToOne的变量名称,如果不一致启动spring的时候会出错。 @OneToMany的变量要赋初始值 val userApps: List<UserApp>? = null如果没有初始值,启动spring的时候也会报错 相关联的Entity的JpaRepositroy的方法命名 像例子中的findByUserAppId,这个UserAppId,关联的是userApps的单数形式userApp,然后Id代表的是UserApp的Entity的主键。然后,还有一个重要的点,table里面的column,也必须命名为user_app_id,不然虽然能启动Spring,但是执行sql的时候会出错。
最近突然发现,一个测试居然要30分钟才能跑完。记得最早的时候也就十几分钟。随着test case越来越多,时间就越来越长了。要是按照这个增长幅度下去,明年估计跑完全部测试就要奔着1个小时去了。网上查了一些资料,然后尝试了很多,最后总结出来这么几个有效的方案: 尽量不要在不同class里面定义MockBean 测试时最花费时间的,其实是启动DI环境,尤其是使用了spring的web模块,启动一次基本要一分半左右。如果像下面这样,在不同的class里定义MockBean的话,执行一个测试class,Spring就会认为context发生了变化,会去重启DI环境。 像上面这种case,如果把MockBean定义到BaseTest里面,执行不同的TestClass,Spring也不会认为context发生了变化,只是会把数据rollback,而不会去重启DI环境。这样就能节省40%左右的时间。 减少@SpringTest的使用 @SpringTest很方便,启动DI环境时会加载所有的Bean,但是同样也十分浪费时间,如果你只想测试Controller,Repository的话,可以使用@WebMvcTest或者@DataJpaTest等,这样可以减少加载的Bean的数目,提高DI环境的启动速度。 明确每一层的作用,写代码时注意不要跃层 Controller:仅作validation和转发Repository:近作数据查询和更新操作Service:业务逻辑像这样把每层的责任范围都明确并严格执行。这样Controller的话基本就只写少量测试。然后Repository如果使用JPARepository的话,基本上只定义接口就可以,那么测试也比较少。重点基本都放到Service层了。如果严格按照上面的功能划分,那么Service就可以独立出来一个模块。然后有使用Repository的case,@DataJpaTest基本上就可以cover大部分测试了。 尽量减少DI的使用 DI固然有很多好处,很方便。但是最好不要滥用。同样的实装,如果不用DI,测试时就不用启动环境。速度就十分快了。其实极端一点,放弃JPARepository,使用jooq,所有的数据访问都通过DSLContext去实现,那么就完全可以做过不启动DI环境进行绝大部分Service层的测试。当然,是否采用这个策略要根据项目规模跟特点去判断。毕竟全都拿jooq写会增大代码量。对于小型web项目其实是不太适合的。 最后,记录下改善后的测试用时。隔个一年之后再回来看看,看那时测试用时会变成多久。 参考:https://spring.pleiades.io/spring-boot/docs/2.1.11.RELEASE/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests
前面有一篇文章提到硬盘使用率达到100%导致服务无法启动的问题。最后查出来是数据库的问题。但是当时没有做详细调查。这里简单写一下后续是如何解决这个问题的。 首先通过phpmyadmin打开数据库。具体如何访问phpmyadmin这篇文章有写。然后看了下bitnami_wordpress数据库,发现唯有wp_options这个表如此之巨大。有66G之多。 wp_options这个表,只有option_value是longtext,查看了下容量最大的前10条,并没有发现什么异样。 这就有点不知所措了。所以去网上搜了以下,确实也发现有碰到同样问题的。网上的处理一般有两个步骤:1. 安装 WP-Optimize 进行优化2. 删除 option_name like ‘%_transient_%’ 行 两个方法都尝试了以下。都没有成效。尤其是删除_transient_行,删除以后5分钟就又自动生成了(貌似类似于cache的东西)。最后没有办法,把wp_options表进行手动备份,发现只有1M多。mysql的具体存储机制尚不太清楚,估计是wp_options已经申请了太多的tablespace。所以干脆就drop掉table,然后把刚才手动备份的wp_options重新导入。这样wp_options的表空间就恢复到2M多了。
第一步找到以下文件 第二步修改文件,加入本地机器的global ip address到白名单中 第三部确认phpmyadmin的登陆密码 第四步通过 http://[パブリックIP]/phpmyadmin 地址登陆 参考:https://note.com/ryutakimuravc/n/nf41e6932ad8f
拿lightsail搭建的wordpress最近十分的不稳定。动不动就503错误。开始以为是某些plugin作妖。就尝试了一下隔断时间重启instance。通过lambda脚本跟定义cloudwatch上的rule可以简单的实现。lambda脚本如下: 刚开始的两天这个还算好用,可是又没过几天,连重启instance都不管用了。一直503状况不断。登陆进去查看了一下。打算重启下service来着。 但是重启不成功。disk usage 100% error。硬盘容量不够了。df -h 查看了一下,确实 / 路径下可用已经为0了。 然后,又打算sort head查下使用最多的路径。无奈du也不能用了。 这可怎么办才好。要不要尝试着增加个disk吧。但是查了几篇文章。发现新增disk必须新建目录。单是问题是我现在 / 目录下的东西还是100%。所以这个方案就放弃了。 剩下就是看删点什么东西了吧。尝试了数次,最后找到了apche存放log的地方。sudo rm -rf *.gz 删除了所有log的备份。这下解放了1个多G的空间。 然后重启service,一切就回复正常了。service重启完以后,又重新看了下最费硬盘容量的几个路径。发现这个mysql/data/bitnami_wordpress 自己就占据了67G。这应该就是罪魁祸首了。但是具体为什么占了这么多容量还不太清楚,下次有时间再继续分析。 参考:https://dev.classmethod.jp/articles/add-storage-to-lightsail/