最近,遇到一個問題,就是我們CMS系統制作的產品頁面和產品列表頁面,發布到nginx服務器上,因為業務要求,客戶看到的鏈接必須是短鏈接,當前的做法就是在nginx的配置中通過rewrite的方式做的。這個是靜態的做法,當業務要修改短鏈接或者有新產品發布的話,就存在問題,要運維人員去修改nginx的配置文件,若這個運維忘記了或者改錯了,或者業務運營人員找不到運維人員,會是什么效果?404唄。
針對這個問題,我希望通過lua+nginx+redis的方式,動態的加載這些鏈接的映射關系。
openresty對lua以及nginx的諸多模塊都有很好的封裝,所以,我就要自己在測試環境下嘗試下,基於openresty的lua功能,首先就是部署openresty。
1. 下載openresty。從官網下載最新的版本。本博文案例用到的是openresty-1.11.2.2.tar.gz。
解壓縮,首先,因為openresty(確切的說,是nginx)依賴pcre做正則引擎,還有要用openssl做安全引擎。所以,先要安裝pcre和openssl。千萬注意,要用源碼,在安裝openresty的時候,通過--with-<module>指定源碼路徑。
1 [root@localhost openresty-1.11.2.2]# ./configure --prefix=/usr/local/openresty --with-pcre=/opt/pcre2-10.23 --with-openssl=/opt/openssl-1.1.0e 2 。。。。。。。 3 Configuration summary 4 + using PCRE library: /opt/pcre2-10.23 5 + using OpenSSL library: /opt/openssl-1.1.0e 6 + using system zlib library 7 8 nginx path prefix: "/usr/local/openresty/nginx" 9 nginx binary file: "/usr/local/openresty/nginx/sbin/nginx" 10 nginx modules path: "/usr/local/openresty/nginx/modules" 11 nginx configuration prefix: "/usr/local/openresty/nginx/conf" 12 nginx configuration file: "/usr/local/openresty/nginx/conf/nginx.conf" 13 nginx pid file: "/usr/local/openresty/nginx/logs/nginx.pid" 14 nginx error log file: "/usr/local/openresty/nginx/logs/error.log" 15 nginx http access log file: "/usr/local/openresty/nginx/logs/access.log" 16 nginx http client request body temporary files: "client_body_temp" 17 nginx http proxy temporary files: "proxy_temp" 18 nginx http fastcgi temporary files: "fastcgi_temp" 19 nginx http uwsgi temporary files: "uwsgi_temp" 20 nginx http scgi temporary files: "scgi_temp" 21 22 cd ../.. 23 Type the following commands to build and install: 24 gmake 25 gmake install
上面日志中可以看出來,我的pcre和openssl的版本。pcre是pcre2-10.23,openssl的版本是openssl-1.1.0e。
這時看上去一切ok,沒問題,可以依據提示信息,執行gmake了。
2. 執行gmake
。。。。。。。。。。。。。。。
install apps/openssl -> /opt/openssl-1.1.0e/.openssl/bin/openssl install ./tools/c_rehash -> /opt/openssl-1.1.0e/.openssl/bin/c_rehash gmake[3]: 離開目錄“/opt/openssl-1.1.0e” cc -c -I/opt/openresty-1.11.2.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g -O2 -DNDK_SET_VAR -DNDK_UPSTREAM_LIST -DNDK_SET_VAR -DNDK_SET_VAR -DNDK_SET_VAR -DLUA_DEFAULT_PATH='"/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua"' -DLUA_DEFAULT_CPATH='"/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so"' -DNDK_SET_VAR -I src/core -I src/event -I src/event/modules -I src/os/unix -I ../ngx_devel_kit-0.3.0/objs -I objs/addon/ndk -I ../ngx_lua-0.10.7/src/api -I /opt/pcre2-10.23 -I /opt/openssl-1.1.0e/.openssl/include -I objs \ -o objs/src/core/nginx.o \ src/core/nginx.c In file included from src/core/ngx_core.h:72:0, from src/core/nginx.c:9: src/core/ngx_regex.h:15:18: 致命錯誤:pcre.h:沒有那個文件或目錄 #include <pcre.h> ^ 編譯中斷。 gmake[2]: *** [objs/src/core/nginx.o] 錯誤 1 gmake[2]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake[1]: *** [build] 錯誤 2 gmake[1]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake: *** [all] 錯誤 2
gmake有問題,如上紅色的錯誤顯示,找不到pcre.h,我到/opt/pcre2-10.23/src下面看,的確沒有這個文件,莫非是版本的問題?我果斷的更換了一個pcre的版本,沒有用pcre2,選擇的是pcre-8.40.再次configure並gmake。
。。。。。。。。。。。。。。。
-o objs/src/os/unix/ngx_linux_sendfile_chain.o \ src/os/unix/ngx_linux_sendfile_chain.c cc -c -I/opt/openresty-1.11.2.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g -O2 -DNDK_SET_VAR -DNDK_UPSTREAM_LIST -DNDK_SET_VAR -DNDK_SET_VAR -DNDK_SET_VAR -DLUA_DEFAULT_PATH='"/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua"' -DLUA_DEFAULT_CPATH='"/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so"' -DNDK_SET_VAR -I src/core -I src/event -I src/event/modules -I src/os/unix -I ../ngx_devel_kit-0.3.0/objs -I objs/addon/ndk -I ../ngx_lua-0.10.7/src/api -I /opt/pcre-8.40 -I /opt/openssl-1.1.0e/.openssl/include -I objs \ -o objs/src/event/ngx_event_openssl.o \ src/event/ngx_event_openssl.c src/event/ngx_event_openssl.c: 在函數‘ngx_ssl_connection_error’中: src/event/ngx_event_openssl.c:2048:21: 錯誤:‘SSL_R_NO_CIPHERS_PASSED’未聲明(在此函數內第一次使用) || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ ^ src/event/ngx_event_openssl.c:2048:21: 附注:每個未聲明的標識符在其出現的函數內只報告一次 gmake[2]: *** [objs/src/event/ngx_event_openssl.o] 錯誤 1 gmake[2]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake[1]: *** [build] 錯誤 2 gmake[1]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake: *** [all] 錯誤 2
這次看來,沒有pcre的那個頭文件找不到的問題了,走的更遠一步了,這次報錯是openssl有問題,這個就不是那么簡單好查看了,去網絡上查看吧,找到原因,是因為openssl的API改動很大,對應openresty的使用,我選擇了老版本的openssl,將當前的1.1.0e版本的改成1.0.1u的了。再次configure並gamke。
。。。。。。。。。。。。。
objs/addon/src/ngx_http_rds_csv_output.o \ objs/ngx_modules.o \ -L/opt/openresty-1.11.2.2/build/luajit-root/usr/local/openresty/luajit/lib -Wl,-rpath,/usr/local/openresty/luajit/lib -Wl,-E -ldl -lpthread -lcrypt -L/opt/openresty-1.11.2.2/build/luajit-root/usr/local/openresty/luajit/lib -lluajit-5.1 -lm -ldl /opt/pcre-8.40/.libs/libpcre.a /opt/openssl-1.0.1u/.openssl/lib/libssl.a /opt/openssl-1.0.1u/.openssl/lib/libcrypto.a -ldl -lz \ -Wl,-E sed -e "s|%%PREFIX%%|/usr/local/openresty/nginx|" \ -e "s|%%PID_PATH%%|/usr/local/openresty/nginx/logs/nginx.pid|" \ -e "s|%%CONF_PATH%%|/usr/local/openresty/nginx/conf/nginx.conf|" \ -e "s|%%ERROR_LOG_PATH%%|/usr/local/openresty/nginx/logs/error.log|" \ < docs/man/nginx.8 > objs/nginx.8 gmake[2]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake[1]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2”
這次,沒有openssl的問題了。gmake的過程ok。
3. gmake install
。。。。。。。。。。 gmake[1]: 進入目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake -f objs/Makefile install gmake[2]: 進入目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” test -d '/usr/local/openresty/nginx' || mkdir -p '/usr/local/openresty/nginx' test -d '/usr/local/openresty/nginx/sbin' \ || mkdir -p '/usr/local/openresty/nginx/sbin' test ! -f '/usr/local/openresty/nginx/sbin/nginx' \ || mv '/usr/local/openresty/nginx/sbin/nginx' \ '/usr/local/openresty/nginx/sbin/nginx.old' cp objs/nginx '/usr/local/openresty/nginx/sbin/nginx' test -d '/usr/local/openresty/nginx/conf' \ || mkdir -p '/usr/local/openresty/nginx/conf' cp conf/koi-win '/usr/local/openresty/nginx/conf' cp conf/koi-utf '/usr/local/openresty/nginx/conf' cp conf/win-utf '/usr/local/openresty/nginx/conf' test -f '/usr/local/openresty/nginx/conf/mime.types' \ || cp conf/mime.types '/usr/local/openresty/nginx/conf' cp conf/mime.types '/usr/local/openresty/nginx/conf/mime.types.default' test -f '/usr/local/openresty/nginx/conf/fastcgi_params' \ || cp conf/fastcgi_params '/usr/local/openresty/nginx/conf' cp conf/fastcgi_params \ '/usr/local/openresty/nginx/conf/fastcgi_params.default' test -f '/usr/local/openresty/nginx/conf/fastcgi.conf' \ || cp conf/fastcgi.conf '/usr/local/openresty/nginx/conf' cp conf/fastcgi.conf '/usr/local/openresty/nginx/conf/fastcgi.conf.default' test -f '/usr/local/openresty/nginx/conf/uwsgi_params' \ || cp conf/uwsgi_params '/usr/local/openresty/nginx/conf' cp conf/uwsgi_params \ '/usr/local/openresty/nginx/conf/uwsgi_params.default' test -f '/usr/local/openresty/nginx/conf/scgi_params' \ || cp conf/scgi_params '/usr/local/openresty/nginx/conf' cp conf/scgi_params \ '/usr/local/openresty/nginx/conf/scgi_params.default' test -f '/usr/local/openresty/nginx/conf/nginx.conf' \ || cp conf/nginx.conf '/usr/local/openresty/nginx/conf/nginx.conf' cp conf/nginx.conf '/usr/local/openresty/nginx/conf/nginx.conf.default' test -d '/usr/local/openresty/nginx/logs' \ || mkdir -p '/usr/local/openresty/nginx/logs' test -d '/usr/local/openresty/nginx/logs' \ || mkdir -p '/usr/local/openresty/nginx/logs' test -d '/usr/local/openresty/nginx/html' \ || cp -R docs/html '/usr/local/openresty/nginx' test -d '/usr/local/openresty/nginx/logs' \ || mkdir -p '/usr/local/openresty/nginx/logs' gmake[2]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” gmake[1]: 離開目錄“/opt/openresty-1.11.2.2/build/nginx-1.11.2” mkdir -p /usr/local/openresty/site/lualib /usr/local/openresty/site/pod /usr/local/openresty/site/manifest ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/local/openresty/bin/openresty
這么看來,openresty安裝部署完畢,是不是要檢查一下,openresty能否啟用呢?先查看下openresty的文件目錄結構,如下,含有lua的組件,測試lua,后續就靠它了。
[root@localhost openresty]# ll 總用量 176 drwxr-xr-x. 2 root root 4096 3月 8 13:20 bin drwxr-xr-x. 6 root root 52 3月 8 12:08 luajit drwxr-xr-x. 6 root root 65 3月 8 13:20 lualib drwxr-xr-x. 11 root root 4096 3月 8 12:42 nginx drwxr-xr-x. 43 root root 4096 3月 8 12:08 pod -rw-r--r--. 1 root root 165176 3月 8 13:20 resty.index drwxr-xr-x. 5 root root 44 3月 8 12:08 site
4.驗證openresty是否安裝成功
[root@localhost sbin]# pwd /usr/local/openresty/nginx/sbin [root@localhost sbin]# ./nginx nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
報錯,地址被占用了,看到這個第一時間想到的是這個機器上安裝了基本版的nginx,於是乎,將openresty的nginx配置文件中listen的端口修改一下,不用默認的80,改成8090.重新啟動nginx。這次沒有地址被占用的錯誤了。在地址欄輸入地址http://localhost:8090, 看到下面的內容,OK,部署完畢!
到此,openresty部署完畢,總結一下,這里的坑無外乎兩點:
1》 openresty需要的pcre插件,不能用pcre2來代替。
2》 openssl的版本更替中,API的改動非常大,版本兼容有問題,openresty需要的openssl版本,一定要匹配。
解除上面兩個坑之后,我的部署其實變成了openresty-1.11.2.2 + pcre-8.40 + openssl-1.0.1u。