基于业务新增一个UDP服务的需求,需要通过Nginx反向代理到后端的微服务集群,查阅资料Nginx在1.9.0版本开始就增加了四层转发模块,但不会被默认编译,需要在编译的时候通过参数 --with-stream 开启,此文记录平滑更新Nginx的全过程,同时也适用于Nginx版本的平滑升级。
1、重新编译Nginx
首先拿到原来编译的参数,在原来基础上增加--with-stream
$ cd local/nginx/sbin && ./nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/home/admin/local/nginx-1.18.0 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_geoip_module=dynamic --with-http_flv_module --with-http_mp4_module --with-http_auth_request_module --with-http_stub_status_module
重新编译Nginx,注意不要make install,另外这里建议保持一致的Nginx版本。
$ cd tmp/nginx-1.18.0/
$ ./configure --prefix=/home/admin/local/nginx-1.18.0 --with-stream --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_geoip_module=dynamic --with-http_flv_module --with-http_mp4_module --with-http_auth_request_module --with-http_stub_status_module
$ make -j 4
2、替换二进制文件
备份旧的二进制文件
$ mv /home/admin/local/nginx/sbin/nginx /home/admin/local/nginx/sbin/nginx.old
将重新编译好的二进制文件拷到sbin目录
$ cp objs/nginx /home/admin/local/nginx/sbin/
测试是否兼容或报其他异常,nginx -V查看编译参数是否符合预期
$ cd /home/apps/local/nginx/sbin/ && ./nginx -t
nginx: the configuration file /home/admin/local/nginx-1.18.0/conf/nginx.conf syntax is ok
nginx: configuration file /home/admin/local/nginx-1.18.0/conf/nginx.conf test is successful
3、发送USR2信号
向master进程发送USR2信号后,Nginx首先会重命名它的进程文件为带.oldbin后缀,然后启动一个新的master进程和对应的worker进程,跟旧的进程一起处理请求,具体可以参考官方文档的说明。
After that USR2 signal should be sent to the master process. The master process first renames its file with the process ID to a new file with the .oldbin suffix, e.g. /usr/local/nginx/logs/nginx.pid.oldbin, then starts a new executable file that in turn starts new worker processes
4、发送WINCH信号
向旧的master进程发送WINCH信号后,它会优雅的关闭worker进程,最后只剩下新的worker进程处理请求。
到这一步后,需要结合观察业务是否异常,如有问题可以立即回滚,可以查看官方文档(http://nginx.org/en/docs/control.html),具体有两个选择:
- 发送HUP信号给旧的master进程,再发QUIT信号给新的master进程
- 直接发送TERM信号给新的master进程
5、发送QUIT信号
步骤4结合观察业务确认没有问题后,就可以发送QUIT信号给旧的master进程,至此旧的进程全部关闭,只剩下新进程处理请求。
6、UDP转发配置
nginx配置文件增加stream配置,注意stream模块跟http模块一样,需要配置在nginx的main context里。
stream {
upstream dns {
server 192.168.100.61:53;
server 192.168.100.62:53;
}
server {
listen 53 udp;
proxy_timeout 20s;
proxy_pass dns;
}
}