<服务>集成常用nginx模块的nginx——openresty
目录:
我选用openresty是因为需要给nginx添加nginx_lua的模块,首先openresty可以理解为已经添加了lua相关模块的nginx。
官方介绍
openresty汇聚了精良的Nginx模块,从而将Nginx有效的变为一个强大的web应用平台,使用lua脚本语言调动Nginx支持的各种C和Lua模块
openresty官方文档
https://openresty.org/cn/
安装openresty
下载
[root@why program]# wget https://openresty.org/download/openresty-1.11.2.3.tar.gz --no-check-certificate
--prefix=/usr/local/openresty
1.11.2.3版本是截止到17年5月13日,如果距离这天久远可以去官网下载最新的版本
安装依赖
[root@why program]# yum install readline-devel pcre-devel openssl-devel gcc
安装
[root@why program]# tar xf openresty-1.11.2.3.tar.gz
[root@why program]# cd openresty-1.11.2.3
[root@why openresty-1.11.2.3]# ./configure --prefix=/opt/openresty --with-luajit --without-http_redis2_module --with-http_iconv_module
[root@why openresty-1.11.2.3]# gmake
[root@why openresty-1.11.2.3]# gmake install
这样就安装完成了,和nginx编译类似,--with是添加模块,--without是不添加模块
可以看到安装了luajit和nginx
[root@why openresty-1.11.2.3]# cd /opt/openresty/
[root@why openresty]# ll
total 232
drwxr-xr-x 2 root root 4096 May 13 20:26 bin
drwxr-xr-x 6 root root 4096 May 13 20:26 luajit
drwxr-xr-x 6 root root 4096 May 13 20:26 lualib
drwxr-xr-x 6 root root 4096 May 13 20:26 nginx
drwxr-xr-x 43 root root 4096 May 13 20:26 pod
-rw-r--r-- 1 root root 210365 May 13 20:26 resty.index
drwxr-xr-x 5 root root 4096 May 13 20:26 site
nginx+lua
文档案例均来自https://github.com/openresty/lua-nginx-module#status,如果愿意摸索可以去直接去github自行实践。
nginx+lua的hello world
添加测试目录
测试目录是为了不修改原有的openresty,也可以直接修改openresty中nginx的配置文件
[root@why openresty]# mkdir test test/logs test/conf
[root@why openresty]# tree test/
test/
├── conf
└── logs
2 directories, 0 files
配置文件
[root@why openresty]# cd test/conf/
[root@why conf]# vi nginx.conf
worker_processes 1; #nginx worker 数量
error_log logs/error.log; #指定错误日志文件路径
events {
worker_connections 1024;
}
http {
server {
#监听端口,若你的端口已经被占用,则需要修改
listen 82;
location / {
default_type text/html;
content_by_lua_block {
ngx.say("HelloWorld")
}
}
}
}
ngx.say
是打印输出的意思
启动服务
[root@why conf]# /opt/openresty/nginx/sbin/nginx -p /opt/openresty/test/
[root@why conf]# ss -nlpt | grep 82
LISTEN 0 128 *:82 *:* users:(("nginx",17192,6),("nginx",17193,6))
通过浏览器访问
通过curl访问
[root@why conf]# curl 121.42.37.139:82
HelloWorld
[root@why conf]# curl 121.42.37.139:82 -i
HTTP/1.1 200 OK
Server: openresty/1.11.2.3
Date: Sat, 13 May 2017 13:09:14 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
HelloWorld
获取url变量
修改配置文件
location /nginx_var {
default_type text/html;
content_by_lua_block {
ngx.say(ngx.var.arg_a)
}
将url参数传递过来,通过ngx.var.arg_a使用传递来的参数a
检验
[root@why conf]# /opt/openresty/nginx/sbin/nginx -p /opt/openresty/test/ -s reload
[root@why conf]# curl 121.42.37.139:82/nginx_var?a=HelloWorld
HelloWorld
[root@why conf]# curl 121.42.37.139:82/nginx_var
nil
如果没有参数传递过来,就会返回nil,在lua中代表空
另一种获取方式
修改配置文件
location ~ ^/app/([-_a-zA-Z0-9/]+) {
set $path $1;
content_by_lua_block {
ngx.say(ngx.var.path)
}
}
检验
[root@why conf]# curl 121.42.37.139:82/app/HelloWorld
HelloWorld
[root@why conf]# curl 121.42.37.139:82/app
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.11.2.3</center>
</body>
</html>
流水线处理
location ~ ^/app/([-_a-zA-Z0-9/]+) {
set $path $1;
content_by_lua_block {
ngx.exec("/apps/"..ngx.var.path)
}
}
location /apps/a {
default_type text/html;
content_by_lua_block {
ngx.say("HelloWorld")
}
}
..
用于字符串连接
ngx.exec方法与下方的外部重定向使用的ngx.redirect是完全不同的,ngx.exec是纯粹的内部跳转并且没有引入任何额外http信号,第一个location处理完,交给第二个location处理。这样就可以做多层的过滤,根据各层的策略进行处理,可以用于不同的API或者下载请求。
需要注意的是,nginx的var内容需要仔细的进行过滤,否则会有很大的风险。
当然如果要执行lua脚本就使用content_by_lua_file /path/to/lua/app/root/$path.lua;
检验
[root@why conf]# /opt/openresty/nginx/sbin/nginx -p /opt/openresty/test/ -s reload
[root@why conf]# curl 121.42.37.139:82/app/a
HelloWorld
[root@why conf]# curl 121.42.37.139:82/app/b
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.11.2.3</center>
</body>
</html>
lua与nginx的location配合
内部调用
内部调用会使用在例如数据库,内部公共函数的统一接口,可以把它们放在统一的location中,并且设置为internal,可以让这个内部接口相对独立不受外界干扰。
修改配置文件
location = /sum {
internal; #内部调用
content_by_lua_block {
ngx.sleep(0.1) #暂停0.1秒,用于下面测试
local args = ngx.req.get_uri_args()
ngx.print(tonumber(args.a) + tonumber(args.b)) #对两个参数求和
}
}
location = /subduction {
internal;
content_by_lua_block {
ngx.sleep(0.1)
local args = ngx.req.get_uri_args()
ngx.print(tonumber(args.a) - tonumber(args.b)) #对两个参数求差值
}
}
location = /app/test_parallels {
content_by_lua_block {
local start_time = ngx.now()
local res1, res2 = ngx.location.capture_multi( {
{"/sum", {args={a=3, b=8}}},
{"/subduction", {args={a=3, b=8}}}
})
ngx.say("status:", res1.status, " response:", res1.body)
ngx.say("status:", res2.status, " response:", res2.body)
ngx.say("time used:", ngx.now() - start_time)
}
}
location = /app/test_queue {
content_by_lua_block {
local start_time = ngx.now()
local res1 = ngx.location.capture_multi( {
{"/sum", {args={a=3, b=8}}}
})
local res2 = ngx.location.capture_multi( {
{"/subduction", {args={a=3, b=8}}}
})
ngx.say("status:", res1.status, " response:", res1.body)
ngx.say("status:", res2.status, " response:", res2.body)
ngx.say("time used:", ngx.now() - start_time)
}
}
检验
[root@why conf]# curl 121.42.37.139:82/app/test_queue
status:200 response:11
status:200 response:-5
time used:0.20099997520447
[root@why conf]# curl 121.42.37.139:82/app/test_parallels
status:200 response:11
status:200 response:-5
time used:0.099999904632568
利用ngx.location.capture_multi函数可以直接完成两个请求并行执行,当两个请求没有相互依赖的情况下,可以大幅提高查询效率。上述的案例,两个无依赖的请求,各自是0.1s,顺序执行需要0.2s,但是通过并行执行可以在0.1s内完成两个请求。参考下图。
外部重定向
修改配置文件
[root@why conf]# cp nginx.conf nginx.conf.helloworld
[root@why conf]# vi nginx.conf
location = /foo {
content_by_lua_block {
ngx.say([[I am foo]])
}
}
location = / {
rewrite_by_lua_block {
return ngx.redirect('/foo');
}
}
通过curl查看
[root@why conf]# curl 127.0.0.1:82 -i
HTTP/1.1 302 Moved Temporarily
Server: openresty/1.11.2.3
Date: Sat, 13 May 2017 16:24:44 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: /foo
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>openresty/1.11.2.3</center>
</body>
</html>
[root@why conf]# curl 127.0.0.1:82/foo -i
HTTP/1.1 200 OK
Server: openresty/1.11.2.3
Date: Sat, 13 May 2017 16:24:49 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
I am foo
浏览器访问
通过lua,我们实现了rewrite功能,当访问127.0.0.1:82的时候,通过302的方式rewrite到127.0.0.1:/foo。并且外部重定向,可以是跨域名的实现,在CDN场景的大量下载应用,一般分为调度和存储两个重要环节,调度的话是根据请求方的IP地址,下载的文件等信息寻找最近最快的节点,应答跳转请求。
跨域名实现
修改配置文件
location = /foo {
content_by_lua_block {
ngx.say([[I am foo]])
}
}
location = / {
rewrite_by_lua_block {
return ngx.redirect('http://www.whysdomain.com');
}
}
浏览器查看
还有一些没看懂的案例,先提供链接,留作以后查看https://moonbingbing.gitbooks.io/openresty-best-practices/content/