1 背景
系统为Ubuntu18.08,Nginx的旧版本为1.14.0,升级新版本为1.21.4;服务器上正在运行着服务,因此采用平滑升级的方式进行nginx升级。非root用户
2 平滑升级
(1)在不停掉老进程的情况下,启动新进程。
(2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
(3)新进程接受新请求。
(4)老进程处理完所有请求,关闭所有连接后,停止。
这样就很方便地实现了平滑升级。一般有两种情况下需要升级Nginx,一种是确实要升级Nginx的版本,另一种是要为Nginx添加新的模块。
3 平滑升级命令
cd /mnt
# 下载nginx升级包
sudo wget http://nginx.org/download/nginx-1.21.4.tar.gz
# 解压升级包
sudo tar zxvf nginx-1.21.4.tar.gz
cd nginx-1.21.4/
# 查看当前版本得到编译参数
sudo /usr/sbin/nginx -V
# 参数:configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/**nginx-1.14.0**=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module
# 用上面编译参数,参数中的版本需要修改
sudo ./configure --prefix=/usr/local/nginx --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/nginx-1.21.4=. -fstack-protector-strong.......
# 执行这一步时可能会出现很多module找不到,可以尝试自己添加;找不到的话可以先将add-module及后面的路径地址删除,先执行下去。
# 编译make,千万别make install
sudo make
# make编译完后,在objs目录下就多了个nginx,这个就是新版本的程序了
# 备份原nginx文件
sudo mv /usr/sbin/nginx /usr/sbin/nginx-20211111
# 将新生成nginx执行文件复制到nginx/sbin下
sudo cp objs/nginx /usr/sbin/nginx
# 检测配置文件是否正确
sudo /usr/sbin/nginx -t
# 执行升级(通过拷贝替换的方式可以不执行这一步了)
make upgrade
# 执行完后
sudo /usr/sbin/nginx -V
# 到此就完成平滑升级。
参考文档:https://cloud.tencent.com/developer/article/1139955
4 升级过程中遇到的问题及解决方案
4.1 错误1:error: the HTTP rewrite module requires the PCRE library
错误信息:
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre= option.
解决:
# 需要安装pcre包。
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev
# 你可能还需要安装
sudo apt-get install openssl libssl-dev
参考链接:
https://blog.csdn.net/pengshengli/article/details/86694967
4.2 错误2:error: the HTTP gzip module requires the zlib library.
错误信息:
./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib= option.
解决:
# 找一个版本下载,解压、安装(安装前先configure)
http://zlib.net/
# 使用的是1.2.11
参考链接:
https://blog.csdn.net/pengshengli/article/details/86694967
https://www.jb51.net/article/80468.htm
4.3 错误3:error: the HTTP XSLT module requires the libxml2/libxslt libraries.
错误信息:
./configure: error: the HTTP XSLT module requires the libxml2/libxslt libraries.
You can either do not enable the module or install the libraries.
解决:
# 需要安装libxslt包。
sudo apt-get update
sudo apt-get install libxslt-dev
# 你可能还需要安装
sudo apt-get install libgd-dev # for the "error: the HTTP image filter module requires the GD library." error
sudo apt-get install libgeoip-dev # for the GeoIP package
参考链接:
https://stackoverflow.com/questions/57415360/configure-error-the-http-xslt-module-requires-the-libxml2-libxslt-libraries
https://cloud.tencent.com/developer/article/1401078
4.4 错误4:error: the HTTP image filter module requires the GD library.
错误信息:
./configure: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.
解决:
# 需要安装libxslt包。
sudo apt-get update
sudo apt-get install -y libgd-dev
# 如果在安装libgd-dev时提示找不到
# 在 vim /etc/apt/sources.list 中添加一行ubuntu 的镜像源
deb http://security.ubuntu.com/ubuntu trusty-security main
在升级Nginx1.18.0至1.22.0版本时执行 sudo apt-get install -y libgd-dev 这个命令时遇到了报错,
报错信息:
The following packages have unmet dependencies:
libgd-dev : Depends: libxpm-dev but it is not going to be installed
Depends: libx11-dev but it is not going to be installed
Depends: libxt-dev but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
执行 sudo apt-get install libxpm-dev libx11-dev libxt-dev 以安装缺少包,又遇到了新的报错,报错信息如下:
libx11-dev : Depends: libx11-6 (= 2:1.6.9-2ubuntu1.2) but 2:1.6.9-2ubuntu1.3 is to be installed
通过指定版本来解决
sudo apt-get install libx11-6=2:1.6.9-2ubuntu1.2
# 然后再次执行这个命令
sudo apt-get install libxpm-dev libx11-dev libxt-dev
参考链接:
https://blog.csdn.net/liuYinXinAll/article/details/88357669
https://stackoverflow.com/questions/57415360/configure-error-the-http-xslt-module-requires-the-libxml2-libxslt-libraries
https://cloud.tencent.com/developer/article/1401078
4.5 错误5:error: the GeoIP module requires the GeoIP library.
错误信息:
./configure: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.
解决:
# 需要安装libxslt包。
sudo apt-get update
sudo apt-get install libgeoip-dev
参考链接:
https://blog.csdn.net/liuYinXinAll/article/details/88357669
https://stackoverflow.com/questions/57415360/configure-error-the-http-xslt-module-requires-the-libxml2-libxslt-libraries
https://cloud.tencent.com/developer/article/1401078
4.6 错误6:[emerg] module “/usr/lib/nginx/modules/ngx_http_passenger_module.so” version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-passenger.conf:1
错误信息:执行 sudo /usr/sbin/nginx -t。因为服务器上使用passenger部署着rails的项目,因此遇到这个问题了。
nginx: [emerg] module "/usr/lib/nginx/modules/ngx_http_passenger_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-passenger.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
解决:
已安装了passenger相关模块(Installing Passenger + Nginx),需要重新添加ngx_http_passenger_module
passenger-config --nginx-addon-dir
# 添加 --add-module=/your path/passenger/ngx_http_passenger_module
sudo ./configure --prefix=/usr/local/nginx --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/nginx-1.21.4=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=/usr/share/passenger/ngx_http_passenger_module
# 重新编译
sudo make
sudo cp objs/nginx /usr/sbin/nginx
# 然后再次执行sudo /usr/sbin/nginx -t,可能会出现新的错误
# [emerg] module "ngx_http_passenger_module" is already loaded in /etc/nginx/modules-enabled/50-mod-http-passenger.conf:1
# 尝试修改50-mod-http-passenger.conf
sudo vim /etc/nginx/modules-enabled/50-mod-http-passenger.conf
# 注释掉 # load_module /usr/lib/nginx/modules/ngx_http_passenger_module.so;
参考链接:
https://stackoverflow.com/questions/10271332/can-i-add-passenger-support-to-a-existed-nginx-instead-of-rebuild-one
4.7 错误7:报其他错误module.so的版本问题
除了ngx_http_passenger_module.so外,其他模块可以从/mnt/nginx-1.21.4/objs/ 中拷贝指定的module 到/usr/share/nginx/modules/中
4.7.1 ngx_http_xslt_filter_module.so
错误信息:
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_xslt_filter_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-xslt-filter.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
解决:
# 备份旧的module
sudo mv /usr/share/nginx/modules/ngx_http_xslt_filter_module.so /usr/share/nginx/modules/ngx_http_xslt_filter_module.so.old
# 拷贝新的module
sudo cp objs/ngx_http_xslt_filter_module.so /usr/share/nginx/modules/ngx_http_xslt_filter_module.so
4.7.2 ngx_mail_module.so
错误信息:
nginx: [emerg] dlopen() "/usr/share/nginx/modules/ngx_mail_module.so" failed (/usr/share/nginx/modules/ngx_mail_module.so: undefined symbol: SSL_CTX_set_options) in /etc/nginx/modules-enabled/50-mod-mail.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
解决:
sudo mv /usr/share/nginx/modules/ngx_mail_module.so /usr/share/nginx/modules/ngx_mail_module.so.old
sudo cp objs/ngx_mail_module.so /usr/share/nginx/modules/ngx_mail_module.so
4.7.3 ngx_stream_module.so
错误信息:
nginx: [emerg] dlopen() "/usr/share/nginx/modules/ngx_stream_module.so" failed (/usr/share/nginx/modules/ngx_stream_module.so: undefined symbol: SSL_CTX_set_options) in /etc/nginx/modules-enabled/50-mod-stream.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
解决:
sudo mv /usr/share/nginx/modules/ngx_stream_module.so /usr/share/nginx/modules/ngx_stream_module.so.old
sudo cp objs/ngx_stream_module.so /usr/share/nginx/modules/ngx_stream_module.so
4.7.4 ngx_http_geoip_module.so
错误信息:
nginx: [emerg] dlopen() "/usr/share/nginx/modules/ngx_http_geoip_module.so" failed (/usr/share/nginx/modules/ngx_http_geoip_module.so: undefined symbol: SSL_CTX_set_options) in /etc/nginx/modules-enabled/50-mod-stream.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
解决:
sudo mv /usr/share/nginx/modules/ngx_http_geoip_module.so /usr/share/nginx/modules/ngx_http_geoip_module.so.old
sudo cp objs/ngx_http_geoip_module.so /usr/share/nginx/modules/ngx_http_geoip_module.so
5 最后
# 执行
sudo /usr/sbin/nginx -t
# 输出
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重新启动nginx
sudo /etc/init.d/nginx restart
6 补充
在2023/06/12对一台服务器进行nginx升级时(由1.14.0升级至1.21.4),遇到了新的问题,进行以下补充。
6.1
错误信息:
# 错误信息1
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-headers-more-filter
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-headers-more-filter/config was found
# 错误信息2
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-auth-pam
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-auth-pam/config was found
# 错误信息3
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-cache-purge
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-cache-purge/config was found
# 错误信息4
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-dav-ext
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-dav-ext/config was found
# 错误信息5
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-ndk
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-ndk/config was found
# 错误信息6
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-echo
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-echo/config was found
# 错误信息7
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-fancyindex
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-fancyindex/config was found
# 错误信息8
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/nchan
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/nchan/config was found
# 错误信息9
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-lua
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-lua/config was found
# 错误信息10
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/rtmp
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/rtmp/config was found
# 错误信息11
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-uploadprogress
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-uploadprogress/config was found
# 错误信息12
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-upstream-fair
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-upstream-fair/config was found
# 错误信息13
adding module in /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-subs-filter
./configure: error: no /build/nginx-YlUNvj/nginx-1.21.4/debian/modules/http-subs-filter/config was found
解决方案:
以上报错,我都是在执行 sudo ./configure –prefix=/usr/local/nginx –with-cc-opt=’-g -O2 -……. 时遇到的。先将 –add-module=…..及后面的路径地址删除,先执行下去。
6.2
错误信息:
# 错误信息1
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_geoip_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-geoip.conf:1
# 错误信息2
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_xslt_filter_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-xslt-filter.conf:1
# 错误信息3
nginx: [emerg] module "/usr/share/nginx/modules/ngx_mail_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-mail.conf:1
# 错误信息4
nginx: [emerg] module "/usr/share/nginx/modules/ngx_stream_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-stream.conf:1
# 错误信息5
nginx: [emerg] module "/usr/share/nginx/modules/ndk_http_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/10-mod-http-ndk.conf
# 错误信息6
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_auth_pam_module.so" version 1014000 instead of 1021004 in /etc/nginx/modules-enabled/50-mod-http-auth-pam.conf:1
解决方案:
以上的错误信息时在执行 sudo /usr/sbin/nginx -t 时遇到。
错误信息1~4:检查发现 编译之后的目录(/mnt/nginx-1.21.4/objs/)中有新的对应的xxx_module.so,因此将解决方式同4.7中的解决方案,用新的 xxx_module.so 替换原 /usr/share/nginx/modules/xxx_module.so。
错误信息5~6:我将对应的/etc/nginx/modules-enabled/xxxx.conf的引入改模块的地方先注释掉。
# 修改对应的配置文件
sudo vim /etc/nginx/modules-enabled/10-mod-http-ndk.conf
sudo vim /etc/nginx/modules-enabled/50-mod-http-auth-pam.conf
#注释掉引用这些模块的地方
6.3
错误信息:
# 错误信息
nginx: [alert] version 1.21.4 of nginx.pm is required, but 1.14.0 was found
解决:
以上的错误信息时在执行 sudo /usr/sbin/nginx -t 时遇到
在编制的目录objs/下找到新版的 nginx.pm 然后替换
# 找到编译之后的新的nginx.pm
find ./objs/ -name nginx.pm
# 找到其他的nginx.pm
find / -name nginx.pm
# 替换
替换完成再次执行 sudo /usr/sbin/nginx -t 可能会遇到新的报错:
nginx object version 1.14.0 does not match bootstrap parameter 1.21.4 at /usr/share/perl/5.26/XSLoader.pm line 114. Compilation failed in require. BEGIN failed--compilation aborted. nginx: [alert] perl_parse() failed: 2 nginx: configuration file /etc/nginx/nginx.conf test failed
这个报错信息没有找到解决方法,但是这个问题是由ngx_http_perl_module这个模块引起,所以我将引用这个模块的地方给注释掉,跳过了这个问题。需要明确服务器中没有使用该模块。