ngx_http_dyups_module实现web服务的平滑发布

背景

公司有很多项目是对外的,对于服务的高可用有一定的要求。

因为项目一直在持续迭代,会经常发布更新,在发布过程中的高可用目前还是空白,需要解决

目标

解决项目发布过程中的高可用

方案分析

目前项目中的服务主要有两种

1.内部微服务,走nacos做服务发现和注册

2.类似网关服务,直接对接nginx

其中1类服务,通过nacos服务发现和注册已经解决了发布过程中的高可用问题;所以需要解决的是直接对接nginx的这一类服务

2类服务其部署架构如下

为了高可用,通常有多个节点,每个节点的功能相同,在发布过程中,其中某个节点会不可用。

因此发布过程中的思路几乎就是在发布过程中动态更新nginx upstream设置,其可选方案大致如下

方案一
思路
优点
缺点

手动处理

发布前先手动修改nginx upstream并reload

发布完成之后再修改nginx upstream并reload

可靠

需要人工介入,效率低,且人是不可靠的

consul-template

通过consule自动监听服务,并通过consul-template动态修改ningx conf文件,reload

upstream变动自动完成,无需人工完成

nginx需要频繁reload,有性能风险

ngx_http_dyups_module

ngx_http_dyups_module 提供http接口,在发布过程中调用http接口更新upstream

1、upstream变动自动完成,无需人工完成

2、nginx无需reload

综上评估,最终决定选用方案3,即ngx_http_dyups_module方案

实施过程

安装过程

下载ngx_http_dyups_module

修改nginx源码

增加内容见下图

重新编译nginx

验证

新增配置文件 /opt/data/nginx/conf/vhost-server/upstream.conf,内容如下

新增配置文件 /opt/data/nginx/conf/vhost-server/ngx_http_dyups_module.conf

初始测试

返回内容如下

可以看到返回了2个节点

接下来测试服务可用性

可以看到服务正常

接下来验证删除upstream

看下upstream是否被删除

404,表示upstream不存在

再看下服务可用

返回502,所有没有可用的upstream

接下来,尝试更新upstream

再次查看upstream

已经有可用upstream,再次查看服务可用

服务恢复

证明方案可行

如何更新upstream

方案
思路
优点
缺点

jekins发布

更新jekins脚本,在服务重启前下掉节点,服务启动后加回节点

1、准确

1、发布和部署架构耦合,配置繁琐

2、如何判断服务已经启动,需要服务改造,提供服务检测接口

应用自动完成

1、通过应用中添加listener,在服务启动后自动注册

2、通过添加shutdownHooker,在服务销毁时下掉节点

1、和发布解耦

2、自动

1、无法解决kill -9时,无法下掉节点的问题

因为线上正常流程是不允许kill -9的,出于解耦的目的,此处选择方案二

应用改造

新增listener,监听应用启动和销毁事件

新增配置类

配置新增如下

服务启动过程日志如下

可以看到启动后有调用NginxRegistryListener.doRegistry注册服务

看下upstream情况

可以看到有一个端口8421的节点,表示服务启动后注册成功

接下来看销毁,日志如下

可以看到服务销毁前有调用NginxRegistryListener.doUnregistry下掉节点

再看下upstream节点情况

可以看到8421节点已经被摘除,证明方案可行

参考

https://github.com/yzprofile/ngx_http_dyups_module

最后更新于