Nginx_Lua_Module扩展的安装与配置_适用于Ubuntu系统

2018年10月08日 99 字 教程整理


Lua 是一个简洁、轻量、可扩展的脚本语言,也是号称性能最高的脚本语言,用在很多需要性能的地方,比如:游戏脚本,nginx,wireshark的脚本。很多应用程序使用Lua作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。
Lua原生支持的数据类型非常之少,它只提供了nil、数字(缺省是双精度浮点数,可配置)、布尔量、字符串、表、子程序、协程(coroutine)以及用户自定义数据这8种。但是其处理表和字符串的效率非常之高,加上元表的支持,开发者可以高效的模拟出需要的复杂数据类型(比如集合、数组等)。Lua是一个动态弱类型语言,支持增量式垃圾收集策略。有内建的,与操作系统无关的协作式多线程(coroutine)支持。它还可以用于嵌入式硬件,不仅可以嵌入其他编程语言,而且可以嵌入微处理器中。

Nginx采用模块化的架构,官方版本的Nginx中大部分功能都是通过模块方式提供的,比如Http模块、Mail模块等。通过开发模块扩展Nginx,可以将Nginx打造成一个全能的应用服务器,这样可以将一些功能在前端Nginx反向代理层解决,比如登录校验、js合并、甚至数据库访问等等。

但是,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。

Nginx_Lua_Module是一个Nginx第三方模块,通过将Lua解释器集成进Nginx的配置中,支持引用Lua脚本文件/代码段实现业务逻辑,从而极大增强了Nginx的能力。由于lua的紧凑、快速以及内建协程,所以在保证高并发服务能力的同时极大地降低了业务逻辑实现成本。
Nginx+Lua是一个非常好的组合,它允许使用一个高性能的脚本语言扩展Nginx。Nginx有很多方法是自带的,但是使用Lua没有限制的。

本文将介绍ngx_lua的安装与配置过程。

0.1. 下载及安装Lua

进入Lua项目官网下载中心: http://luajit.org/download.html ,选择即将安装的版本下载到自定义路径中:

0.1.1. 下载Lua主程序压缩包

输入如下命令,下载对应的包文件:

wget -c http://luajit.org/download/LuaJIT-2.0.5.tar.gz

0.1.2. 解压及安装

包文件下载完成后,解压压缩包:

tar xzvf LuaJIT-2.0.5.tar.gz

解压完成后,进入安装包主目录,执行make指令安装:

cd <安装包目录>
make install PREFIX=<即将安装Lua主程序的路径>

如:

cd LuaJIT-2.0.5
make install PREFIX=/usr/local/LuaJIT-2.0.5

0.1.3. 配置Lua环境变量

vim /etc/profile 命令编辑 /etc/profile 文件,添加 LUAJIT_LIBLUAJIT_INC 变量:

export LUAJIT_LIB=/usr/local/LuaJIT-2.0.5/lib
export LUAJIT_INC=/usr/local/LuaJIT-2.0.5/include/luajit-2.0

输入 source /etc/profile 命令使环境变量立即生效。

0.2. 获取 ngx_devel_kit 部件安装包

输入 wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz 下载ngx_devel_kit 安装文件压缩包。

下载完成后,输入 tar -xzvf v0.3.0.tar.gz 解压。

0.3. 获取 lua-nginx-module 部件安装包

输入 wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz 下载lua-nginx-module 部件压缩包。
下载完成后,输入 tar -xzvf v0.10.8.tar.gz 解压。

0.4. 配置Nginx-configure

假设Nginx已安装完成,现在需要重新集成 ngx_devel_kitlua-nginx-module 两个模块。
进入Nginx程序路径,输入 ./sbin/nginx -V ,查看并记录Nginx的configure参数:

在当前的配置参数之后追加 add-module 信息,将ngx_devel_kitlua-nginx-module 集成入配置参数,如:

./configure --prefix=/usr/local/nginx  --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/lua-nginx-module-0.10.8

接下来进入Nginx安装文件路径,以上述configure参数重新make:

cd /usr/local/src/nginx-1.11.3/
make clean

./configure --prefix=/usr/local/nginx  --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/lua-nginx-module-0.10.8

make -j2
make install

此时Nginx已成功集成lua-nginx-module, nginx.conf配置文件中可插入lua代码片段,进行更多性能配置。

make之后启动nginx的过程中可能会报错: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
这是因为编译时没有生成动态链接库,只能手动链接,具体步骤如下:

  1. vim /etc/ld.so.conf.d/libc.conf 命令,编辑libc.conf文件,追加Lua编译安装后的lib路径,如: /usr/local/LuaJIT-2.0.5/lib
  2. 运行 ldconfig 命令。
  3. 再次启动Nginx即可。

0.5. 在Nginx-conf文件中添加Lua脚本,辅助location配置

例:

0.5.1. nginx.conf(片段)

upstream www.vspnoa.tomcat_colony {    
    server localhost:8091;  
    server localhost:8092;  
    server localhost:8093;
    server localhost:8090;
    fair; 
}
upstream www.vspnoa.tomcat_approve_process_colony {    
    server localhost:8096;
    server localhost:8097;
    fair; 
}
upstream www.vspnoa.tomcat_finance_process_colony {    
    server localhost:8098;
    server localhost:8099;
    fair; 
}
upstream www.vspnoa.tomcat_colony_main_server {    
    server localhost:8090;
}

server {
    listen       80;
    server_name  localhost;

    location /VSPNOA/ {
        error_log logs/oa_request.log error;
        lua_code_cache on;
         #(配置请求体缓存区大小, 不配的话默认值:1k ) 
        client_body_buffer_size 128k;
        #设置客户端请求体最大值
        client_max_body_size 50m;

        proxy_set_header    Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;

        #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度;
        #上游服务器通信超时时间的配置factcgi_connect/read/send_timeout
        #Nginx 504 Gateway Time-out设置优化,避免频繁发生504错误
        fastcgi_connect_timeout 1200;
        fastcgi_send_timeout 600;
        fastcgi_read_timeout 600;
        fastcgi_buffer_size 256k;
        fastcgi_buffers 16 256k;
        fastcgi_busy_buffers_size 512k;
        fastcgi_temp_file_write_size 512k;
        fastcgi_intercept_errors on;

        if ($request_uri ~* ^/VSPNOA/$) {#只有域名,后面不跟任何东西
          proxy_pass  http://www.vspnoa.tomcat_colony_main_server;
          break;
        }
        if ($request_uri ~* ^/VSPNOA/(js|sources|img|images|font|css|Charts)/(.*)$) {
          #OA系统脚本文件储存路径
          root /;
          rewrite ^/VSPNOA/(.*)$ /var/PROJ_FILE_WAREHOUSE/oa_prod_scripts_and_pages/$1 break;
          break;
        }
        if ($request_uri ~* ^/VSPNOA/(bar_code|out_file_transitStation|file_download_station|file_transitStation|file_preview_scripts|oa_stamp_doc_attachment_file)/(.*)$) {
          #图片/附件储存路径
          root /var/PROJ_FILE_WAREHOUSE/;
          break;
        }
         if ($request_uri ~* ^/VSPNOA/(.*).+\.(jsp|html|htm)(.*)$) {
          #jsp/html/htm页面
          proxy_pass  http://www.vspnoa.tomcat_colony_main_server;
          break;
        }

     
        if ($request_uri ~* ^/VSPNOA/(.*).+\.(action|do)(.*)$) {
          set $action_proxy_pass http://www.vspnoa.tomcat_colony;
          # 使用lua 获取get/post参数
          lua_need_request_body  on; 
          rewrite_by_lua_file  conf/lua/get_params.lua;
          proxy_pass  $action_proxy_pass; 
          break;
        }
        if ($request_uri ~* ^/VSPNOA/(.*)$) {
          proxy_pass  http://www.vspnoa.tomcat_colony_main_server;
          break;
        }

        send_timeout 60;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    # 启用ngx_pagespeed    
    pagespeed on;    
    pagespeed FileCachePath /tmp/cache/ngx_pagespeed_cache;    
    # 禁用CoreFilters    
    pagespeed RewriteLevel PassThrough;    
    # 启用压缩空白过滤器    
    pagespeed EnableFilters collapse_whitespace;    
    # 启用JavaScript库卸载    
    pagespeed EnableFilters canonicalize_javascript_libraries; #谷歌被墙,并不确定这个设置有没有副作用 
    # 把多个CSS文件合并成一个CSS文件    
    pagespeed EnableFilters combine_css;    
    # 把多个JavaScript文件合并成一个JavaScript文件    
    pagespeed EnableFilters combine_javascript;    
    # 删除带默认属性的标签    
    pagespeed EnableFilters elide_attributes;    
    # 改善资源的可缓存性    
    pagespeed EnableFilters extend_cache;    
    # 更换被导入文件的@import,精简CSS文件    
    pagespeed EnableFilters flatten_css_imports;    
    pagespeed CssFlattenMaxBytes 5120;    
    # 延时加载客户端看不见的图片    
    pagespeed EnableFilters lazyload_images;    
    # 启用JavaScript缩小机制    
    pagespeed EnableFilters rewrite_javascript;    
    # 启用图片优化机制    
    pagespeed EnableFilters rewrite_images;    
    # 预解析DNS查询    
    pagespeed EnableFilters insert_dns_prefetch;    
    # 重写CSS,首先加载渲染页面的CSS规则    
    pagespeed EnableFilters prioritize_critical_css; 
    # 禁止pagespeed 处理WordPress的/wp-admin/目录(可选配置,可参考使用)
    pagespeed Disallow "*/wp-admin/*";
    # 禁止pagespeed 处理typecho的/admin/目录(可选配置,可参考使用)
    pagespeed Disallow "*/admin/*";

    location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; }
    location ~ "^/ngx_pagespeed_static/" { }
    location ~ "^/ngx_pagespeed_beacon$" { }
    location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
    location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }
}

在nginx.conf中,引用了 conf/lua/get_params.lua 脚本:

lua_need_request_body  on; 
rewrite_by_lua_file  conf/lua/get_params.lua;

0.5.2. conf/lua/get_params.lua

local action_request_method = ngx.var.request_method
local action_url_param = nil  
local action_proxy_upstream = "www.vspnoa.tomcat_colony" 
local action_accpted_param_str = nil 

if "GET" == action_request_method then 
    action_accpted_param_str = ngx.req.get_uri_args() 
elseif "POST" == action_request_method then
    ngx.req.read_body()
    action_accpted_param_str = ngx.req.get_post_args() 
end

if action_accpted_param_str    ~= nil then
    action_url_param = action_accpted_param_str["url_param"] 
end 



if action_url_param    ~= nil then     
    if action_url_param  == "get_stf_mastered_element_type_selected_approve_prcs_unfinished_list_with_proj_budg_items"  then
        action_proxy_upstream = "www.vspnoa.tomcat_approve_process_colony"
    elseif action_url_param  == "batch_edit_approving_status"  then
        action_proxy_upstream = "www.vspnoa.tomcat_approve_process_colony" 
    elseif action_url_param  == "edit_approving_status_from_joint"  then
        action_proxy_upstream = "www.vspnoa.tomcat_approve_process_colony" 
    elseif action_url_param  == "revoke_approve"  then
        action_proxy_upstream = "www.vspnoa.tomcat_approve_process_colony" 
    elseif action_url_param  == "edit_approving_PRI"  then
        action_proxy_upstream = "www.vspnoa.tomcat_approve_process_colony"

    elseif action_url_param  == "edit_expense_element_cashier_payment_plan"  then
        action_proxy_upstream = "www.vspnoa.tomcat_finance_process_colony" 
    elseif action_url_param  == "edit_expense_element_cashier_payment_exec"  then
        action_proxy_upstream = "www.vspnoa.tomcat_finance_process_colony" 
    elseif action_url_param  == "batch_insert_and_refer_approving_fc_list"  then
        action_proxy_upstream = "www.vspnoa.tomcat_finance_process_colony" 
    end
end

ngx.var.action_proxy_pass=string.format("%s%s","http://",action_proxy_upstream);
-- ngx.log(ngx.INFO , "action_url_param: " , action_url_param);