奶油葡萄重构(二)

前言

目前,奶油葡萄已经微服务化,并稳定运行在自建云服务上,总算可以抽点时间总结下这次遇到的坑了。

访问速度慢

在正式上云之前,我搭了个测试站跑在自建云上,网站功能都还挺正常,除了慢得离谱这个毛病。打开一个页面要好几十秒,和单机效果简直天差地别。

因为在个人开发环境的访问速度都很流畅,加上受 这篇文章 的影响,一开始我猜测是 Docker 镜像的打包问题,就疯狂地修改 Dockerfile 然后测试。可惜的是效果都不理想,依然很慢。

在绝望的时候突然想到,如果不是 Docker 镜像的问题,会不会是数据库和站点分离的原因。顺着这个思路,我写了个测试脚本,用来测试 include、数据库连接、数据库查询、写缓存的平均耗时

分别测试了站点在不同宿主机上的各项指标,然后发现居然是 VPS 间的网络通信问题。Vultr 同机房内的 VPS 通信还是很不错,不过跨机房延时就比较高了。对于一个需要多次查询数据库和缓存的页面,打开速度慢也是再正常不过。

解决方案也很直接,部署站点服务的时候,尽可能避开和数据库通信不佳的宿主机即可。测试了下单机和目前的性能,可以简单看看下表,单位均为秒。

原生 微服务
include 0.010151147842407 0.0071881542205811
db connect 0.087284803390503 0.0781989097595211
db read 0.033894205093384 0.026038122177124
cache write 0.000041699409484863 0.00085845947265625

对比可以看到,其实比较大的差别在于缓存的读写,然而由于缓存读写速度实在是太快了,微服务化之后页面的打开速度变化基本可以忽略不计。

流量跑高

微服务化之后,提供数据库服务和缓存服务的机器,一天就要 100 多 GB 的出口流量,基本上不到 10 天就可以把免费流量套餐用光。给 Vultr 提了工单,为什么同机房内的 VPS 间还要计流量,只是甩了我一个流量超了怎么计费的回复。

网上了解到,Vultr 同机房的 VPS 只有通过内网 IP 通信时,才不会计算流量。顿时陷入了纠结,如果要通过内网 IP 组集群,那现有的一些非 Vultr 的小鸡就搁置了,而且很多监控服务要搭在 Vultr 上,对现有的 VPS 配置要求就大大提高,月费用也高得不可接受。

节点加入 docker swarm 时,可以通过设置 advertise-addr 作为对外通信地址。灵机一动,把这个参数用域名替代,然后改 Vultr 机子的 hosts 文件,把域名映射到内网 IP,不就完美解决了?当然只是想得太美好,官方文档中并没有明确说到这样的操作。设置之后,流量还是照常跑高。

本来站点的代码是配置的 docker service 名作为数据库和缓存的连接,利用的是 docker swarm 的服务自发现机制。为了不让流量疯跑,只好将连接地址直接改成对应机子的内网 IP。

设置之后,目前流量已经稳定,感觉终于可以愉快地玩耍了。