nginx上將特定請求拒絕,並返回特定值。html
使用lua腳本,實現效果。node
nginx -V
配置一致,並新增兩個模塊ngx_devel_kit
,lua-nginx-module
)配置文件添加lua腳本:nginx
#匹配請求體裏的 hello=world時返回此變量和值 location /hello { rewrite_by_lua_block { ngx.req.read_body() local own_a = ngx.req.get_post_args()["hello"] if ( own_a == "world" ) then ngx.say("hello world") end } proxy_pass xxxx; }
#安裝lua-nginx模塊須要先安裝Luajit $ tar xf LuaJIT-2.0.4.tar.gz $ cd LuaJIT-2.0.4 $ make PREFIX=/usr/local/luajit $ make install PREFIX=/usr/local/luajit $ cat <<EOF > /etc/profile.d/luajit.sh export LUAJIT_LIB=/usr/local/luajit/lib export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0 EOF $ source /etc/profile.d/luajit.sh #判斷是否有庫函數連接 if [ ! -f /lib64/libluajit-5.1.so.2 ];then ln -s /usr/local/luajit/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2 fi #添加庫函數連接 if [ ! -f /lib64/libprofiler.so.0 ];then ln -sv /usr/local/lib/libprofiler.so.0.4.18 /lib64/libprofiler.so.0 || echo "/usr/local/lib/libprofiler.so.0.4.18 fasle,please check this" fi #可使用 ldd $(which /usr/local/nginx/sbin/nginx) 查看缺乏的庫文件
可在測試機(目標機器環境相同)編譯好最新的nginx二進制文件(
nginx -V
相同而且新增兩個模塊便可)。也可直接在目標機器上編譯,可是最後make install
不可執行,不然就覆蓋目標環境了。git
#將生成的nginx二進制文件替換至目錄機器 $ cd /usr/loca/nginx/sbin/ $ mv nginx{,_bak} #先備份老的 $ mv /home/install_nginx/src/nginx ./ #將新的移動過來 $ nginx -t #檢查配置,這一步很重要,一但報錯,說明nginx二進制文件編譯有問題,須要從新覈對環境信息並從新編譯 nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful $ nginx -s reload $ $ curl -d "hello=world" http://192.168.20.13/hello xxx #返回結果不是hello world,lua腳本配置未生效。此時老的配置並不影響
查看錯誤日誌:github
2019/10/08 17:25:22 [notice] 30580#0: signal process started 2019/10/08 17:25:22 [emerg] 22066#0: unknown directive "rewrite_by_lua_block" in /usr/local/nginx/conf/vhost/text.conf:41
未識別rewrite_by_lua_block
配置,說明lua腳本配置未生效。看來nginx -s reload
是不行,只能經過熱升級了。shell
nginx啓動時master進程會初始化每一個模塊的信息,reload只是從新開啓新的worker進程。因此新增模塊只能重啓或熱升級。服務器
信號 | nginx內置shell | 說明 |
---|---|---|
HUP | nginx -s reload | 重載配置文件 |
USR1 | nginx -s reopen | 從新打開日誌文件,配置mv,用作日誌切割 |
USR2 | - | 熱升級nginx程序 |
WINCH | - | 優雅的關閉相關的worker進程 |
QUIT | nginx -s squit | 優雅的中止nginx |
TERM,INT | nginx -s stop | 當即中止nginx |
nginx -s reload
執行後的nginx操做順序:curl
$ kill -USR2 `cat /tmp/nginx.pid` $ #執行完後查看進程,調接口都沒生效 ##查看error log 2019/10/08 17:25:41 [alert] 30599#0: execve() failed while executing new binary process "nginx" (2: No such file or directory)
上面的報錯: 找不到nginx命令。nginx程序依賴環境變量,而上一次啓動確定不是用絕對路徑啓動(nginx命令直接啓)。這種狀況就沒法作熱升級,只能
restart
了,restart
後配置即生效,接口調通了。函數
[root@node2013 vhost]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf #正確的啓動nginx
從新執行編譯nginx步驟,爲了升級服務器可執行文件,應首先將新的可執行文件替換舊文件。以後,USR2信號應發送到主進程。主進程首先將其具備進程ID的文件重命名爲帶有.oldbin後綴的新文件,例如 /tmp/nginx.pid.oldbin,而後啓動一個新的可執行文件,該文件又啓動新的工做進程:post
[root@node2013 vhost]# kill -USR2 `cat /tmp/nginx.pid` #發送熱升級信號 [root@node2013 vhost]# ps -ef | grep nginx root 31118 1 0 17:36 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nobody 31119 31118 0 17:36 ? 00:00:00 nginx: worker process nobody 31120 31118 0 17:36 ? 00:00:00 nginx: worker process nobody 31121 31118 0 17:36 ? 00:00:00 nginx: worker process nobody 31122 31118 0 17:36 ? 00:00:00 nginx: worker process root 31177 31118 0 17:36 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nobody 31178 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31179 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31180 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31181 31177 0 17:36 ? 00:00:00 nginx: worker process root 31185 30078 0 17:37 pts/0 00:00:00 grep --color=auto nginx [root@node2013 vhost]# ll /tmp/ total 12 -rw-r--r-- 1 root root 6 Oct 8 17:36 nginx.pid -rw-r--r-- 1 root root 6 Oct 8 17:36 nginx.pid.oldbin $ curl -d "hello=world" http://192.168.20.13/hello #正常返回結果,lua腳本生效。如未生效則直接發送`QUIT`信號給新的master進程。 hello world
以後,全部工做進程(舊的和新的)繼續接受請求。若是WINCH
或QUIT
信號發送到第一個主進程,它將向其工做進程發送消息,要求它們正常關閉,而後它們將開始退出:
[root@node2013 vhost]# kill -QUIT `cat /tmp/nginx.pid.oldbin` #優雅的退出進程 [root@node2013 vhost]# ps -ef | grep nginx #最後查看效果,只剩下新的master和其worker進程 root 31177 1 0 17:36 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nobody 31178 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31179 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31180 31177 0 17:36 ? 00:00:00 nginx: worker process nobody 31181 31177 0 17:36 ? 00:00:00 nginx: worker process root 31254 30078 0 17:38 pts/0 00:00:00 grep --color=auto nginx [root@node2013 vhost]#
nginx啓動須使用絕對路徑,否則沒法處理USR2
信號。
文檔連接:
nginx 安裝lua模塊: https://github.com/openresty/lua-nginx-module#installation
nginx 信號: http://nginx.org/en/docs/control.html
nginx main初始化:https://blog.csdn.net/time_change/article/details/78470901