博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
生产环境中 Ngx_lua 使用技巧和应用的范例
阅读量:6658 次
发布时间:2019-06-25

本文共 6650 字,大约阅读时间需要 22 分钟。

Lua的性能超牛的,这个不需要再啰嗦了。。。


Nginx_lua的适用场景


  1. 网络I/O 阻塞时间远高于CPU 计算占用时间、同时上游资源非瓶颈(可伸缩)的网络应用,如高性能网络中间层、HTTP REST 接口服务等;

  2. 期望简化系统架构,让服务向Nginx 同质化的Web 站点;

优势:

  • 同步非阻塞I/O 形式直观易懂,并发服务能力强

  • CPU、内存运行开销低

  • 同Nginx 结合度高,可方便粘合现有Nginx 模块功能

劣势:

  • 属于新技术方案,Lua 相比于PHP、Ruby 等广泛使用的开发

  • 语言,周边附属设施尚不够健全,需要时间积累

安装就简单过一遍,其实大家用openresty就行啦。。。  作者已经做了很多的调优。。。

还是推荐大家用 openresty。。。 最少在测试环境下用这个,可以省去很多找模块,折腾模块的时间。。。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1
.下载nginx
wget http:
//nginx.org/download/nginx-1.2.2.tar.gz
2
.安装gcc
sudo apt-
get 
install gcc
3
.下载LuaJIT
wget http:
//luajit.org/download/LuaJIT-2.0.0-beta10.tar.gz
4
. 安装LuaJIT
tar -xzvf  LuaJIT-
2.0
.
0
-beta10.tar.gz
cd LuaJIT-
2.0
.
0
-beta10
make && sudo make install
5
.下载 ngx_devel_kit(在这个页面找:https:
//github.com/simpl/ngx_devel_kit/tags)
wget https:
//github.com/simpl/ngx_devel_kit/tarball/master -O simpl-ngx_devel_kit.tar.gz
6
.下载最新的 lua-nginx-module(在这个页面找:https:
//github.com/chaoslawful/lua-nginx-module/tags)
 
wget https:
//github.com/chaoslawful/lua-nginx-module/tarball/master -O lua-nginx-module.tar.gz
7
.下载pcre
wget ftp:
//ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.gz
tar -xzvf pcre-
8.31
.tar.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
 
./configure && make(如果报“compile: unrecognized option `-DHAVE_CONFIG_H'”,请安装sudo apt-
get 
install build-essential)
sudo make install
8
.下载echo模块
wget https:
//github.com/agentzh/echo-nginx-module/tarball/master -O echo-nginx-module.tar.gz
 
tar -xzvf echo-nginx-module.tar.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
7
. 解压nginx,ngx_devel_kit, lua-nginx-module
tar -xzvf nginx-
1.2
.
2
.tar.gz
tar -xzvf simpl-ngx_devel_kit.tar.gz
 
tar -xzvf lua-nginx-module.tar.gz
8
.安装
sudo apt-
get 
install openssl libssl-dev
sudo apt-
get 
install libtool
cd  nginx-
1.2
.
2
export LUAJIT_LIB=/usr/local/lib/
export LUAJIT_INC=/usr/local/
include
/luajit-
2.0
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
./configure --user=www-data --group=www-data --
with
-debug --
with
-http_gzip_static_module --
with
-http_ssl_module  --
with
-http_stub_status_module --
with
-http_realip_module \
--prefix=/usr/local/nginx \
    
--add-module=../simpl-ngx_devel_kit-4192ba6/ \
  
--add-module=../chaoslawful-lua-nginx-module-b771a2e/\
    
--add-module=../agentzh-echo-nginx-module-8042c62/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
make -j2
sudo make install

一定要注意他的执行顺序

  1. Rewrite phase.

  2. Access phase.

  3. Content phase.

详细的步骤:

1
2
3
4
5
6
7
8
1
.init_by_lua  上下文http  ngx启动时执行
2
. set_by_lua  上下文 server, server 
if
, location, location 
if
3
.rewrite_by_lua 上下文  http, server, location, location 
if
4
.access_by_lua 上下文 http, server, location, location 
if
5
.content_by_lua 上下文   location, location 
if
6
.header_filter_by_lua 上下文   http, server, location, location 
if
7
.body_filter_by_lua 上下文 http, server, location, location 
if
8
.log_by_lua 上下文 http, server, location, location 
if

咱们再过滤post、get请求或者是触发了某个access、rewrite,如果发现恶意和违规的侵入的话,可以发邮件报警,好让我们第一时间收到邮件的信息。。。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
location 
= 
/
smtp {
        
default_type 
"text/plain"
;
        
content_by_lua '
            
local smtp 
= 
require(
"socket.smtp"
)
            
local 
from 
= 
"<ruifengyunceshi@163.com>"
            
local  rcpt 
= 
{"",}
            
local   mesgt 
= 
{
            
headers 
= 
{
            
to 
= 
"", 
-
- 
收件人
            
subject 
= 
"This is Mail Title"
            
},
        
body 
= 
"This is  Mail Content."
    
}
     
local  r, e 
= 
smtp.send{
        
server
=
"smtp.163.com"
,
        
user
=
"",
        
password
=
"",
        
from 
= 
from
,
        
rcpt 
= 
rcpt,
        
source 
= 
smtp.message(mesgt)
      
}
    
if 
not 
r then
        
ngx.say(e)
    
else
        
ngx.say(
"send ok!"
)
    
end
    
';
    
}

lua这东西挺怪的,他的双引号和单引号是有很大区别的,我到现在也没搞明白,啥区别,反正用双引号就对了。。。有事error.log报错的话,改成单引号试试。。

好点的方法是  先在lua的环境中跑一边,ok后,在放到ngx_lua里面。

Lua有丰富的接口的方案,不只是给别人提供的接口,还有他自己访问别的接口所用的模块。


如果你的同事那边已经有个高性能的socket接口,那你就别麻烦他改成rest模式了。。。 毕竟socket对socket速度很快的。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
location /cosocket {
        
default_type 
"text/plain"
;
        
content_by_lua '
        
local sock = ngx.socket.tcp()
        
sock:settimeout(
1000
)
        
local ok, err = sock:connect(
"127.0.0.1"
12000
)
        
if 
not ok then
            
ngx.say(
"failed to connect: "
, err)
            
return
        
end
        
local bytes, err = sock:send(
"flush_all"
)
        
ngx.say(bytes,err)
        
if 
not bytes then
            
ngx.say(
"failed to send query: "
, err)
            
return
        
end
       
local line, err = sock:receive()
        
if 
not line then
            
ngx.say(
"failed to receive a line: "
, err)
            
return
        
end
        
ngx.say(
"result: "
, line)
        
';
      
}
                                                                                                                                                                                                                                                                                                                                                                                       
    
}
}


对于给别人的mysql查询,给账号密码不合适,和一个小权限的账号密码也不合适。

这种情况,我们要是求高性能的话,可以用lua配置cjson做成rest接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
location /select2 {
content_by_lua '
local mysql = require 
"resty.mysql"
local db,err = mysql:
new
()
if 
not db then
ngx.say(
"failed to instantiate mysql: "
,err)
return
end
db:set_timeout(
1000
)
local ok,err,errno,sqlstate = db:connect{
host = 
"127.0.0.1"
,
port = 
3306
,
database = 
"niubi"
,
user = 
"ruifengyun"
,
password = 
""
,
max_package_size = 
1024
}
if 
not ok then
ngx.say(
"failed to connect: "
, err, 
": "
, errno, 
" "
, sqlstate)
return
end
ngx.say(
"connected to mysql."
)
res,err,errno,sqlstate = db:query(
"select username,password from users where id="
..ngx.
var
.arg_id)
if 
not res then
ngx.say(
"bad result: "
, err, 
": "
, errno, 
": "
, sqlstate, 
"."
)
return
end
local cjson = require 
"cjson"
ngx.say("result: “,cjson.encode(res))
';
}


咱们既然知道了 lua的强大之处, 可以从lua里面搞负载均衡。

往redis里面 扔两个key   比如 web1 8.8.8.111  web2 8.8.8.222

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
server {
  
listen 
80
;
  
server_name _;
  
server_name_in_redirect off;
  
port_in_redirect off;
  
root /root/html;
  
location / {
    
set 
$upstream 
""
;
    
rewrite_by_lua '
      
local routes = _G.routes
      
-- setup routes cache 
if 
empty
      
if 
routes == nil then
        
routes = {}
        
ngx.log(ngx.ALERT, 
"Route cache is empty."
)
      
end
      
-- 
try 
cached route first      local route = routes[ngx.
var
.http_host]
      
if 
route == nil then
        
local redis  = require 
"redis"
        
local client = redis.connect(
"localhost"
6379
)
        
route        = client:
get
(ngx.
var
.http_host)
      
end
      
if 
route ~= nil then
        
ngx.
var
.upstream = route
        
routes[ngx.
var
.http_host] = route
        
_G.routes = routes
      
else
        
ngx.exit(ngx.HTTP_NOT_FOUND)
      
end
    
';
    
proxy_buffering             off;
    
proxy_set_header            Host $host;
    
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
    
proxy_redirect              off;
    
proxy_connect_timeout       
10
;
    
proxy_send_timeout          
30
;
    
proxy_read_timeout          
30
;
    
proxy_pass                  http:
//$upstream;
  
}
}

用lua 对cookie的控制


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
header_filter_by_lua '
        
t = {}
        
if 
ngx.
var
.http_cookie then
            
s = ngx.
var
.http_cookie
            
for 
k, v 
in 
string.gmatch(s, 
"(%w+)=([%w%/%.=_-]+)"
do
                
t[k] = v
            
end
        
end
                                                   
        
p = ngx.req.get_uri_args()
                                                   
        
if 
not t.uid and p.uid then
            
expires = ngx.cookie_time(
4523969511
)
            
ngx.header[
"Set-Cookie"
] = {
"uid=" 
.. p.uid ..
"; expires=" 
.. expires .. ";
        
end
                                                   
';
 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1252501,如需转载请自行联系原作者
你可能感兴趣的文章
↑构建高可用LVS + keepalived+httpd和双主模型的keepalived方案↑
查看>>
Ubuntu iptalbes 保存配置
查看>>
python—memcached启动脚本
查看>>
struts和struts2的区别
查看>>
linux lvm+raw设备 表空间可用空间测试
查看>>
第 8 章 容器网络 - 059 - 安装配置 flannel
查看>>
Javascript学习之Function对象详解
查看>>
04+罗潇潇+罗潇第三次作业
查看>>
Laravel开发环境配置
查看>>
学习与认知方法
查看>>
分析和排查系统故障
查看>>
linux计划任务的管理
查看>>
linux (debian 8) 设置开机自动挂载
查看>>
浏览器过程
查看>>
构造和析构的基础知识
查看>>
交换机的端口安全
查看>>
哪些人学Python更容易?
查看>>
squid代理
查看>>
java调用opencc,将简体中文转换成繁体
查看>>
Linux基本权限UGO
查看>>