Openresty最佳案例 | 第4篇:OpenResty常见的api
获取请求参数
vim /usr/example/example.conf
location /lua_var {default_type 'text/plain';content_by_lua_block {ngx.say(ngx.var.arg_a)}}
重新加载nginx配置文件: nginx -s reload
在浏览器上访问http://116.196.177.123/lua_var?a=323,浏览器显示:
323
在上述代码中,涉及到了2个api, 一是ngx.say(直接返回请求结果);二是ngx.var,它是获取请求的参数,比如本例子上的?a=323,获取之后,直接输出为请求结果。
获取请求类型
vim /usr/example/example.conf
location /lua_request{default_type 'text/html';lua_code_cache off;content_by_lua_file /usr/example/lua/lua_request.lua;}
vim /usr/example/lua/lua_request.lua ,添加一下代码:
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) dongx.say("[GET ] key:", k, " v:", v)
endngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) dongx.say("[POST] key:", k, " v:", v)
end
在上述例子中有以下的api:
ngx.req.get_uri_args 获取在uri上的get类型参数,返回的是一个table类型的数据结构。
ngx.req.read_body 读取body,这在解析body之前,一定要先读取body。
ngx.req.get_post_args 获取form表单类型的参数,返回结果是一个table类型的数据。
使用curl模拟请求:
curl ‘http://116.196.177.123/lua_request?a=323&b=ss‘ -d ‘c=12w&d=2se3’
返回的结果:
[GET ] key:b v:ss
[GET ] key:a v:323
[POST] key:d v:2se3
[POST] key:c v:12w
获取请求头
vim /usr/example/lua/lua_request.lua ,在原有的代码基础上,再添加一下代码:
local headers = ngx.req.get_headers()
ngx.say("headers begin", "<br/>")
ngx.say("Host : ", headers["Host"], "<br/>")
ngx.say("user-agent : ", headers["user-agent"], "<br/>")
ngx.say("user-agent : ", headers.user_agent, "<br/>")
for k,v in pairs(headers) doif type(v) == "table" thenngx.say(k, " : ", table.concat(v, ","), "<br/>")elsengx.say(k, " : ", v, "<br/>")end
end
重新加载nginx -s reload
使用curl模拟请求:
curl ‘http://116.196.177.123/lua_request?a=323&b=ss‘ -d ‘c=12w&d=2se3’
[GET ] key:b v:ss
[GET ] key:a v:323
[POST] key:d v:2se3
[POST] key:c v:12w
headers begin<br/>
Host : 116.196.77.157<br/>
user-agent : curl/7.53.0<br/>
user-agent : curl/7.53.0<br/>
host : 116.196.77.157<br/>
content-type : application/x-www-form-urlencoded<br/>
accept : */*<br/>
content-length : 12<br/>
user-agent : curl/7.53.0<br/>
获取http的其他方法
vim /usr/example/lua/lua_request.lua ,在原有的代码基础上,再添加一下代码:
ngx.say("ngx.req.http_version : ", ngx.req.http_version(), "<br/>")
--请求方法
ngx.say("ngx.req.get_method : ", ngx.req.get_method(), "<br/>")
--原始的请求头内容
ngx.say("ngx.req.raw_header : ", ngx.req.raw_header(), "<br/>")
--请求的body内容体
ngx.say("ngx.req.get_body_data() : ", ngx.req.get_body_data(), "<br/>")
ngx.say("<br/>")
重新加载nginx -s reload
使用curl模拟请求:
curl ‘http://116.196.177.123/lua_request?a=323&b=ss‘ -d ‘c=12w&d=2se3’
//....
ngx.req.http_version : 1.1<br/>
ngx.req.get_method : POST<br/>
ngx.req.raw_header : POST /lua_request?a=323&b=ss HTTP/1.1
Host: 116.196.77.157
User-Agent: curl/7.53.0
Accept: */*
Content-Length: 12
输出响应
vim /usr/example/example.conf,添加一个location,代码如下:
location /lua_response{default_type 'text/html';lua_code_cache off;content_by_lua_file /usr/example/lua/lua_response.lua ;}
vim /usr/example/lua/lua_response.lua 添加一下代码:
ngx.header.a="1"
ngx.header.b={"a","b"}
ngx.say("hello","</br>")
ngx.print("sss")
return ngx.exit(200)
上述代码中有以下api:
ngx.header 向响应头输出内容
ngx.say 输出响应体
ngx.print输出响应体
ngx.exit 指定http状态码退出
使用curl模拟请求, curl ‘http://116.196.177.123/lua_response‘ ,获取的响应体如下:
hello
sss
日志输出
在配置文件vim /usr/example/example.conf 加上以下代码:
location /lua_log{default_type 'text/html';lua_code_cache off;content_by_lua_file /usr/example/lua/lua_log.lua;}
vim /usr/example/lua/lua_log.lua ,加上以下代码:
local log="i'm log"
local num =10
ngx.log(ngx.ERR, "log",log)
ngx.log(ngx.INFO,"num:" ,num)
重新加载配置文件nginx -s reload
curl ‘http://116.196.177.123/lua_log‘
打开nginx 的logs目录下的error.log 文件:
tail -fn 1000 /usr/servers/nginx/logs/error.log
可以看到在日志文件中已经输出了日志,这种日志主要用于记录和测试。
日志级别:
ngx.STDERR — 标准输出
ngx.EMERG — 紧急报错
ngx.ALERT — 报警
ngx.CRIT — 严重,系统故障,触发运维告警系统
ngx.ERR — 错误,业务不可恢复性错误
ngx.WARN — 告警,业务中可忽略错误
ngx.NOTICE — 提醒,业务比较重要信息
ngx.INFO — 信息,业务琐碎日志信息,包含不同情况判断等
ngx.DEBUG — 调试
内部调用
vim /usr/example/example.conf 添加以下代码:
location /lua_sum{# 只允许内部调用internal;# 这里做了一个求和运算只是一个例子,可以在这里完成一些数据库、# 缓存服务器的操作,达到基础模块和业务逻辑分离目的content_by_lua_block {local args = ngx.req.get_uri_args()ngx.say(tonumber(args.a) + tonumber(args.b))}}
internal 关键字,表示只允许内部调用。使用curl模拟请求,请求命令如下:
$ curl ‘http://116.196.177.123/lua_sum?a=1&b=2‘
由于该loction是一个内部调用的,外部不能返回,最终返回的结果为404,如下:
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.11.2.4</center>
</body>
</html>
vim /usr/example/example.conf 添加以下代码:
location = /lua_sum_test {content_by_lua_block {local res = ngx.location.capture("/lua_sum", {args={a=3, b=8}})ngx.say("status:", res.status, " response:", res.body)}
}
上述的代码通过ngx.location.capture去调用内部的location,并获得返回结果,最终将结果输出,采用curl模拟请求:
$ curl ‘http://116.196.177.123/lua_sum_test‘
返回结果如下:
status:200 response:11
重定向
vim /usr
location /lua_redirect{default_type 'text/html';content_by_lua_file /usr/example/lua/lua_redirect.lua;
}
ngx.redirect("http://www.fangzhipeng.com", 302)
http://116.196.177.123/lua_redirect
共享内存
vim /usr/servers/nginx/cong/nginx.conf
在http模块加上以下:
lua_shared_dict shared_data 1m;
location /lua_shared_dict{default_type 'text/html';content_by_lua_file /usr/example/lua/lua_shared_dict.lua;}
local shared_data = ngx.shared.shared_data
local i = shared_data:get("i")
if not i theni = 1shared_data:set("i",i)
end
i = shared_data:incr("i",1)
ngx.say("i:",i)
多次访问 http://116.196.177.123/lua_shared_dict,浏览器打印:
i:1
i:2
i:3
i:4
i:5
OpenResty执行阶段的概念
以下内容来自于《openresty 最佳实践》
如上图所示,openresty的执行阶段分为
这样我们就可以根据我们的需要,在不同的阶段直接完成大部分典型处理了。
set_by_lua* : 流程分支处理判断变量初始化
rewrite_by_lua* : 转发、重定向、缓存等功能(例如特定请求代理到外网)
access_by_lua* : IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙)
content_by_lua* : 内容生成
header_filter_by_lua* : 响应头部过滤处理(例如添加头部信息)
body_filter_by_lua* : 响应体过滤处理(例如完成应答内容统一成大写)
执行阶段概念:
log_by_lua* : 会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其 他机器)
实际上我们只使用其中一个阶段content_by_lua* ,也可以完成所有的处理。但这样做,会让 我们的代码比较臃肿,越到后期越发难以维护。把我们的逻辑放在不同阶段,分工明确,代 码独立,后期发力可以有很多有意思的玩法。
Openresty最佳案例 | 第4篇:OpenResty常见的api相关推荐
- Openresty最佳案例 | 第3篇:Openresty的安装
我的服务器为一台全新的centos 7的服务器,所以从头安装openresty,并记录了安装过程中出现的问题,以及解决办法. 1.首先安装openresty cd /usr mkdir servers ...
- Openresty最佳案例 | 第9篇:Openresty实现的网关权限控制
简介 采用openresty 开发出的api网关有很多,比如比较流行的kong.orange等.这些API 网关通过提供插件的形式,提供了非常多的功能.这些组件化的功能往往能够满足大部分的需求,如果要 ...
- Openresty最佳案例 | 第8篇:RBAC介绍、sql和redis模块工具类
RBAC介绍 RBAC(Role-Based Access Control,基于角色的访问控制),用户基于角色的访问权限控制.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成&q ...
- Openresty最佳案例 | 第5篇:http和C_json模块
http客户端 Openresty没有提供默认的Http客户端,需要下载第三方的http客户端. 下载lua-resty-http到lualib目录下,使用以下的命令下载: cd /usr/examp ...
- Openresty最佳案例 | 第7篇: 模块开发、OpenResty连接Redis
Lua模块开发 在实际的开发过程中,不可能把所有的lua代码写在一个lua文件中,通常的做法将特定功能的放在一个lua文件中,即用lua模块开发.在lualib目录下,默认有以下的lua模块. lua ...
- Openresty最佳案例 | 第1篇:Nginx介绍
Nginx 简介 Nginx是一个高性能的Web 服务器,同时是一个高效的反向代理服务器,它还是一个IMAP/POP3/SMTP 代理服务器. 由于Nginx采用的是事件驱动的架构,能够处理并发百万级 ...
- Openresrt最佳案例 | 第2篇:Lua入门
什么是lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学(Po ...
- OpenResty 最佳实践
关注我的人都知道,我基本不在公号推文字消息,但这次我愿意为「温铭」破个例,他是 OpenResty 软件基金会主席,<OpenResty 最佳实践>作者,最近哥们开了个专栏讲 OpenRe ...
- OpenResty 最佳实践学习--实战演习笔记(4)
本篇简单记录openresty连接redis数据库和缓存的一些东西,也基本上是官网上的一些例子和知识,作为整理方便自己后续回顾! openresty连接redis 因为我本地服务器安装了redis,这 ...
最新文章
- python import问题
- C语言里最基础的关键字
- 分数诚可贵的飞鸽传书2012绿色版
- openlayers之obj.js提供的功能函数
- 360浏览器清除缓存_微信缓存清理教程
- 批量操作权限的页面展示
- kubernetes session回话保持
- LA 2218 Triathlon (Geometry, Half Plane Intersection)
- 利用kd树实现最近邻搜索
- CATIA V6二次开发——宏应用
- 经典上海弄堂线路攻略
- Python Socket联机自动匹配双人五子棋(含登录注册系统与界面,数据库连接,可作结课作业,可用于学习)
- 前端javaScript模板引擎之ArtTemplate
- JZOJ3426. 封印一击
- cc2640软件用c语言开发,CC2640R2FTI-RTOS 拿到 TI CC2640R2F 开发板 第三件事就是使用 TI-RTOS 创建 一个任务 和 使用 信号量 超时来闪烁 LED灯...
- unshift() 与shift() 方法
- 教你用键盘打出各种符号 如 ♠♣♥........
- ff14最新服务器人数,FF14第一波转服过后 现各服务器人口状况
- Springboot+Mybatis-plus实现增删改查功能超详细
- wiki的备份以及迁移方式
热门文章
- eclipse快捷键操作
- HDU 1011-Starship Troopers(树形背包)
- CSS 和 JS 动画哪个更快
- Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
- 【第20周复盘】转换思路,让更多的小朋友们参与进来!
- 【C++】利用构造函数对类对象进行初始化
- Ampere 携手 Rigetti 开发混合量子经典计算机
- 7000 字精华总结,Pandas/Sklearn 进行机器学习之特征筛选,有效提升模型性能
- 释放联接新价值,华为提出“1+N”5G目标网,推动运营商构筑四大数字化转型的核心能力
- 全领域通吃,12个经典Python数据可视化库盘点