使用lua脚本在nginx上处理网站简繁体转换逻辑
默认情况下Nginx不支持Lua模块,需要安装LuaJIT解释器,并且需要重新编译Nginx。
同时也建议使用openrestry,因为内置对Lua的支持。
环境准备
yum install -y gd-devel GeoIP GeoIP-devel google-perftools google-perftools-devel perl-devel perl-ExtUtils-Embed libxml2 libxslt-devel gperftools-devel gcc gcc-c++ make pcre-devel zlib-devel openssl-devel
安装前准备
mkdir -p /opt/softwares/nginx/ && cd /opt/softwares/nginx/
luajit
cd /opt/softwares/nginx # 进入到目录
wget --no-check-certificate https://luajit.org/download/LuaJIT-2.0.5.tar.gz -O luajit-2.0.5.tar.gz && tar xf luajit-2.0.5.tar.gz
cd LuaJIT-2.0.5 # 进入到源代码目录
make && make install PREFIX=/usr/local/luajit2 # 将编译结果放到 /usr/local/luajit2 目录
ngx_devel_kit
解压出来的文件将在nginx编译时指定目录
/opt/softwares/nginx/ngx_devel_kit-0.3.1
。
cd /opt/softwares/nginx # 进入到目录
wget --no-check-certificate https://github.com/simpl/ngx_devel_kit/archive/v0.3.1.tar.gz -O ngx_devel_kit-0.3.1.tar.gz && tar xf ngx_devel_kit-0.3.1.tar.gz
lua-nginx-module
解压出来的文件将在nginx编译时指定目录
/opt/softwares/nginx/lua-nginx-module-0.10.21
。
cd /opt/softwares/nginx # 进入到目录
wget --no-check-certificate https://github.com/openresty/lua-nginx-module/archive/v0.10.21.tar.gz -O lua-nginx-module-0.10.21.tar.gz && tar xf lua-nginx-module-0.10.21.tar.gz
lua-resty-core
cd /opt/softwares/nginx # 进入到目录
wget --no-check-certificate https://github.com/openresty/lua-resty-core/archive/v0.1.23.tar.gz -O lua-restry-core-0.1.23.tar.gz && tar xf lua-restry-core-0.1.23.tar.gz
cd lua-resty-core-0.1.23
make install PREFIX=/usr/local/lua/core
lua-resty-lrucache
cd /opt/softwares/nginx # 进入到目录
wget --no-check-certificate https://github.com/openresty/lua-resty-lrucache/archive/v0.11.tar.gz -O lua-resty-lrucache-0.11.tar.gz && tar xf lua-resty-lrucache-0.11.tar.gz
cd lua-resty-lrucache-0.11
make install PREFIX=/usr/local/lua/core
编译安装Nginx并加载模块
# 建立软链接, 不建立会出现share object错误
ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
# 加载lua库,加入到ld.so.conf文件
echo "/usr/local/luajit2/lib" >> /etc/ld.so.conf
ldconfig
wget http://nginx.org/download/nginx-1.22.0.tar.gz && tar xf nginx-1.22.0.tar.gz && cd nginx-1.22.0
export LUAJIT_LIB=/usr/local/luajit2/lib
export LUAJIT_INC=/usr/local/luajit2/include/luajit-2.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --add-module=/opt/softwares/nginx/ngx_devel_kit-0.3.1 --add-module=/opt/softwares/nginx/lua-nginx-module-0.10.21
make && make install
echo "export PATH=/usr/local/nginx/sbin:$PATH" >> /etc/profile && source /etc/profile
Nginx自启动脚本,下面的内容放在:/etc/init.d/nginx
。
#!/bin/bash
#
# Startup script for Nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
useradd -M -s /sbin/nologin nginx # 创建nginx用户
chkconfig --add nginx
chkconfig --list | grep nginx
chkconfig --level 2345 nginx on
service nginx start
安装opencc
yum install -y doxygen cmake
cd /opt/softwares/nginx
git clone https://github.com/BYVoid/OpenCC.git --depth 1 && cd OpenCC
make # See: https://github.com/BYVoid/OpenCC/issues/592
sudo make install
ln -s /usr/lib/libopencc.so /lib64/libopencc.so
仅对站点的text/html
文件内容替换 opencc-filter.lua
。
local content_type = ngx.header.content_type
local ffi = require('ffi')
local cc = ffi.load('opencc')
if string.match(content_type, 'text/html') then
ffi.cdef[[
typedef void* opencc_t;
opencc_t opencc_open(const char *configFileName);
int opencc_close(opencc_t opencc);
char* opencc_convert_utf8(opencc_t opencc, const char *input, size_t length);
void opencc_convert_utf8_free(char *str);
]]
local inst = cc.opencc_open('/usr/share/opencc/s2t.json')
local input = ngx.arg[1]
local res = cc.opencc_convert_utf8(inst, input, string.len(input))
ngx.arg[1] = ffi.string(res)
cc.opencc_convert_utf8_free(res)
cc.opencc_close(inst)
end
虚拟主机中使用
server {
listen 80;
server_name tw.curder.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/curder.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/curder.com/privkey.pem;
server_name tw.curder.com;
location / {
proxy_pass https://www.avatrade-world.hk;
body_filter_by_lua_file /etc/nginx/conf/vhosts/opencc-filter.lua;
}
location /lua {
set $test "hello,world";
content_by_lua '
ngx.header.content_type="text/html; charset=UTF-8;"
ngx.say(ngx.var.test)';
}
}
此时访问 https://tw.curder.com 站,则可以看到页面内容都转换成了繁体。