通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布 (4)

可见负载均衡的列表中,9000端口的服务实例已经置为down,此时疯狂请求,只输出hello world by 127.0.0.1:9001,可见9000端口的服务实例已经不再参与负载。重新上线9000端口的服务实例:

curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10, "down":0}' :8510/v1/kv/upstreams/app/127.0.0.1:9000

再疯狂请求,发现hello world by 127.0.0.1:9000和hello world by 127.0.0.1:9001交替输出。到此可以验证动态负载均衡是成功的。此时再测试一下服务健康监测,通过kill -9随机杀掉其中一个服务实例,然后观察/upstream_status端点:

通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

疯狂请求,只输出hello world by 127.0.0.1:9001,可见9000端口的服务实例已经不再参与负载,但是查看Consul中9000端口的服务实例的配置,并没有标记为down,可见是nginx_upstream_check_module为我们过滤了异常的节点,让这些节点不再参与负载。

总的来说,这个相对完善的动态负载均衡功能需要nginx_upstream_check_module和nginx-upsync-module共同协作才能完成。

服务平滑发布

服务平滑发布依赖于前面花大量时间分析的动态负载均衡功能。笔者所在的团队比较小,所以选用了阿里云的云效作为产研管理平台,通过里面的流水线功能实现了服务平滑发布,下面是其中一个服务的生产环境部署的流水线:

通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

其实平滑发布和平台的关系不大,整体的步骤大概如下:

通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

步骤比较多,并且涉及到大量的shell脚本,这里不把详细的脚本内容列出,简单列出一下每一步的操作(注意某些步骤之间可以插入合理的sleep n保证前一步执行完毕):

代码扫描、单元测试等等。

代码构建,生成构建后的压缩包。

压缩包上传到服务器X中,解压到对应的目录。

向Consul发送指令,把当前发布的X_IP:PORT的负载配置更新为down=1。

stop服务X_IP:PORT。

start服务X_IP:PORT。

检查服务X_IP:PORT的健康状态(可以设定一个时间周期例如120秒内每10秒检查一次),如果启动失败,则直接中断返回,确保还有另一个正常的旧节点参与负载,并且人工介入处理。

向Consul发送指令,把当前发布的X_IP:PORT的负载配置更新为down=0。

上面的流程是通过hard code完成,对于不同的服务器,只需要添加一个发布流程节点并且改动一个IP的占位符即可,不需要对Nginx进行配置重新加载。笔者所在的平台流量不大,目前每个服务部署两个节点就能满足生产需要,试想一下,如果要实现动态扩容,应该怎么构建流水线?

小结

服务平滑发布是CI/CD中比较重要的一个环节,而动态负载均衡则是服务平滑发布的基础。虽然现在很多云平台都提供了十分便捷的持续集成工具,但是在使用这些工具和配置流程的时候,最好能够理解背后的基本原理,这样才能在工具不适用的时候或者出现问题的时时候,迅速地作出判断和响应。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjjwx.html