Openrestry 平滑重启(无reload,不重启nginx)

在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一定的轮询策略,将请求路由到后端一台指定的服务器上。

Openrestry 平滑重启(无reload,不重启nginx)_第1张图片

这样的架构是没有问题的, 但是我们这里考虑几个问题:
1) 业务频繁上下线问题:我们APP、业务系统平时更新的时候是直接覆盖文件,然后重启, 那这样会造成一些请求中断,如果是非核心逻辑那还好, 如果是核心逻辑,那请求中断,会影响一些数据一致性,比如资金, 交易,订单等。

2) 业务应用动态扩容与缩容,比如某个业务应用访问量大,要新增机器进行水平扩容或者缩容,那就需要修改nginx的配置,然后reload, 这样会中断连接。 虽然reload很快,但是还是会有一瞬间的请求中断。 如果某个应用配置了弹性伸缩策略,那么可能在短时间内多次频繁reload nginx,那么对线上其他应用将会导致不可预知的风险。
对于第一个问题,我们可以在请求量少的时候去更新, 但是这种在一些服务稳定的公司可用, 对于互联网企业,可能1-2天就一个版本, 2-3天就是一个大促, 如果每次都要等到凌晨1-2点去更新, 不太现实。
对于第二个问题,现有的方法和手段显然是不太好解决的。互联网公司运维的目标始终是自动化运维,不以自动化运维为目标的运维就不是互联网运维。

解决方案与对策的思考
操作nginx上下线,这里的确是一个难点,因为nginx本身并没有提供这些上下线API,需要openresty并配合一些第三方扩展来实现。例如:ngx_http_dyups_module 、 lua-upstream-nginx-module、ngx_dynamic_upstream等等。
但是这些nginx扩展组件的问题是无法将upstream中配置的server进行持久化(调用API之后,这些扩展会刷新nginx的内存,可以实现无reload、无重启,平滑扩容和缩容)
例如,使用ngx_http_dyups_module的API:

curl -d "server 127.0.0.1:8089;server 127.0.0.1:8088;" 127.0.0.1:8081/upstream/ip.haiziwang.com

因为这些插件无法持久化配置,所以我们还需要使用lua脚本进行持久化,或者开发nginx 的WEB程序管理配置文件。
核心步骤是:
1 修改nginx配置文件,并持久化到数据库
2 nginx -t 检查配置文件是否正确
3 调用ngx_http_dyups_module,在内存中刷新域名

以上步骤因为操作一共有3个步骤,可能会有某一个步骤执行失败。WEB管理程序需要保证以上步骤的幂等性。

openresty安装ngx_http_dyups_module的步骤为:

$ git clone git://github.com/yzprofile/ngx_http_dyups_module.git

# 将下载的模块移动到openrestry的根目录
$ mv ngx_http_dyups_module  /opt/openresty1.9.xx

#添加模块
$ ./configure --add-module=./ngx_http_dyups_module

#重新编译nginx 
$ make && make install

ok , 我们使用ngx_http_dyups_module的时候需要将proxy_pass配置成:http://$host(nginx内存中的一个变量)

server {
        listen       80;
        server_name  abc.haiziwang.com;
        location   / {
               #proxy_pass              http://abc.haiziwang.com;
               proxy_pass      http://$host;
               proxy_set_header        Host  abc.haiziwang.com;
               proxy_set_header        X-Real-IP $remote_addr;
               proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }  
}

server {
        listen 18080;
        location / {
            dyups_interface;
        }
    }

OK,然后我们调用API,就可以控制abc.haiziwang.com后端反向代理的服务器IP地址了,例如:

curl -d "server 172.172.177.75:5050;" 127.0.0.1:18080/upstream/abc.haiziwang.com
curl -i -X DELETE 127.0.0.1:18080/upstream/abc.haiziwang.com

你可能感兴趣的:(软件架构)