获取请求参数

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相关推荐

  1. Openresty最佳案例 | 第3篇:Openresty的安装

    我的服务器为一台全新的centos 7的服务器,所以从头安装openresty,并记录了安装过程中出现的问题,以及解决办法. 1.首先安装openresty cd /usr mkdir servers ...

  2. Openresty最佳案例 | 第9篇:Openresty实现的网关权限控制

    简介 采用openresty 开发出的api网关有很多,比如比较流行的kong.orange等.这些API 网关通过提供插件的形式,提供了非常多的功能.这些组件化的功能往往能够满足大部分的需求,如果要 ...

  3. ​Openresty最佳案例 | 第8篇:RBAC介绍、sql和redis模块工具类

    RBAC介绍 RBAC(Role-Based Access Control,基于角色的访问控制),用户基于角色的访问权限控制.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成&q ...

  4. Openresty最佳案例 | 第5篇:http和C_json模块

    http客户端 Openresty没有提供默认的Http客户端,需要下载第三方的http客户端. 下载lua-resty-http到lualib目录下,使用以下的命令下载: cd /usr/examp ...

  5. Openresty最佳案例 | 第7篇: 模块开发、OpenResty连接Redis

    Lua模块开发 在实际的开发过程中,不可能把所有的lua代码写在一个lua文件中,通常的做法将特定功能的放在一个lua文件中,即用lua模块开发.在lualib目录下,默认有以下的lua模块. lua ...

  6. Openresty最佳案例 | 第1篇:Nginx介绍

    Nginx 简介 Nginx是一个高性能的Web 服务器,同时是一个高效的反向代理服务器,它还是一个IMAP/POP3/SMTP 代理服务器. 由于Nginx采用的是事件驱动的架构,能够处理并发百万级 ...

  7. Openresrt最佳案例 | 第2篇:Lua入门

    什么是lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学(Po ...

  8. OpenResty 最佳实践

    关注我的人都知道,我基本不在公号推文字消息,但这次我愿意为「温铭」破个例,他是 OpenResty 软件基金会主席,<OpenResty 最佳实践>作者,最近哥们开了个专栏讲 OpenRe ...

  9. OpenResty 最佳实践学习--实战演习笔记(4)

    本篇简单记录openresty连接redis数据库和缓存的一些东西,也基本上是官网上的一些例子和知识,作为整理方便自己后续回顾! openresty连接redis 因为我本地服务器安装了redis,这 ...

最新文章

  1. python import问题
  2. C语言里最基础的关键字
  3. 分数诚可贵的飞鸽传书2012绿色版
  4. openlayers之obj.js提供的功能函数
  5. 360浏览器清除缓存_微信缓存清理教程
  6. 批量操作权限的页面展示
  7. kubernetes session回话保持
  8. LA 2218 Triathlon (Geometry, Half Plane Intersection)
  9. 利用kd树实现最近邻搜索
  10. CATIA V6二次开发——宏应用
  11. 经典上海弄堂线路攻略
  12. Python Socket联机自动匹配双人五子棋(含登录注册系统与界面,数据库连接,可作结课作业,可用于学习)
  13. 前端javaScript模板引擎之ArtTemplate
  14. JZOJ3426. 封印一击
  15. cc2640软件用c语言开发,CC2640R2FTI-RTOS 拿到 TI CC2640R2F 开发板 第三件事就是使用 TI-RTOS 创建 一个任务 和 使用 信号量 超时来闪烁 LED灯...
  16. unshift() 与shift() 方法
  17. 教你用键盘打出各种符号 如 ♠♣♥........
  18. ff14最新服务器人数,FF14第一波转服过后 现各服务器人口状况
  19. Springboot+Mybatis-plus实现增删改查功能超详细
  20. wiki的备份以及迁移方式

热门文章

  1. eclipse快捷键操作
  2. HDU 1011-Starship Troopers(树形背包)
  3. CSS 和 JS 动画哪个更快
  4. Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
  5. 【第20周复盘】转换思路,让更多的小朋友们参与进来!
  6. 【C++】利用构造函数对类对象进行初始化
  7. Ampere 携手 Rigetti 开发混合量子经典计算机
  8. 7000 字精华总结,Pandas/Sklearn 进行机器学习之特征筛选,有效提升模型性能
  9. 释放联接新价值,华为提出“1+N”5G目标网,推动运营商构筑四大数字化转型的核心能力
  10. 全领域通吃,12个经典Python数据可视化库盘点