openresty开发系列33--openresty执行流程之2重写赋值阶段
openresty开发系列33--openresty执行流程之2重写赋值阶段
一)重写赋值阶段
1)set_by_lua
语法:set_by_lua $res <lua-script-str> [$arg1 $arg2 …]
语境:server、server if、location、location if
阶段:rewrite
设置nginx变量,我们用的set指令即使配合if指令也很难实现负责的赋值逻辑;
传入参数到指定的lua脚本代码中执行,并得到返回值到res中。
<lua-script-str>中的代码可以使从ngx.arg表中取得输入参数(顺序索引从1开始)。
这个指令是为了执行短期、快速运行的代码因为运行过程中nginx的事件处理循环是处于阻塞状态的。
耗费时间的代码应该被避免。
禁止在这个阶段使用下面的API:
1、output api(ngx.say和ngx.send_headers);
2、control api(ngx.exit);
3、subrequest api(ngx.location.capture和ngx.location.capture_multi);
4、cosocket api(ngx.socket.tcp和ngx.req.socket);
5、sleep api(ngx.sleep)
a、nginx.conf配置文件
location /lua {
set $jump "1";
echo $jump;
}
set 命令对变量进行赋值,但有些场景的赋值业务比较复杂,需要用到lua脚本
所以用到set_by_lua
b、补充知识点:
ngx.var.arg与ngx.req.get_uri_args的区别,都是能够获取请求参数
ngx.var.arg_xx与ngx.req.get_uri_args["xx"]两者都是为了获取请求uri中的参数
例如 http://pureage.info?strider=1
为了获取输入参数strider,以下两种方法都可以:
local strider = ngx.var.arg_strider
local strider = ngx.req.get_uri_args["strider"]
差别在于,当请求uri中有多个同名参数时,ngx.var.arg_xx的做法是取第一个出现的值
ngx.req_get_uri_args["xx"]的做法是返回一个table,该table里存放了该参数的所有值
例如,当请求uri为:http://pureage.info?strider=1&strider=2&strider=3&strider=4时
ngx.var.arg_strider的值为"1",而ngx.req.get_uri_args["strider"]的值为table ["1", "2", "3", "4"]。
因此,ngx.req.get_uri_args属于ngx.var.arg_的增强。
-------------------------------
案例需求:书店网站改造把之前的skuid为8位商品,请求到以前的页面,为9位的请求到新的页面
书的商品详情页进行了改造,美化了一下;上线了时候,不要一下子切换美化页面;;做AB概念
把新录入的书的商品 采用 新的商品详情页,之前维护的书的商品详情页 用老的页面
以前书的id 为8位,新的书id为9位
root /data/www/html;
location /book {
set_by_lua $to_type '
local skuid = ngx.var.arg_skuid
ngx.log(ngx.ERR,"skuid=",skuid)
local r = ngx.re.match(skuid, "^[0-9]{8}$")
local k = ngx.re.match(skuid, "^[0-9]{9}$")
if r then
return "1"
end;
if k then
return "2"
end;
';
if ($to_type = "1") {
echo "skuid为8位";
proxy_pass http://127.0.0.1/old_book/$arg_skuid.html;
}
if ($to_type = "2") {
echo "skuid为9位";
proxy_pass http://127.0.0.1/new_book/$arg_skuid.html;
}
}
# 具体的网页内容
[root@node5 data]# tree /data/www/html/
/data/www/html/
├── new_book
│ └── 123456789.html
└── old_book
└── 12345678.html
2 directories, 2 files
[root@node5 data]# cat /data/www/html/old_book/12345678.html
<h1>old book</h1>
[root@node5 data]# cat /data/www/html/new_book/123456789.html
<h1>new book</h1>
# 测试访问:http://10.11.0.215/book?skuid=123456789
会跳转到new_book/123456789.html
访问:http://10.11.0.215/book?skuid=12345678
会跳转到new_book/12345678.html
=======================================
2)set_by_lua_file
语法set_by_lua_file $var lua_file arg1 arg2...;
在lua代码中可以实现所有复杂的逻辑,但是要执行速度很快,不要阻塞;
location /lua_set_1 {
default_type "text/html";
set_by_lua_file $num /usr/local/luajit/test_set_1.lua;
echo $num;
}
2.1、test_set_1.lua
local uri_args = ngx.req.get_uri_args()
local i = uri_args["i"] or 0
local j = uri_args["j"] or 0
return i + j
得到请求参数进行相加然后返回。
访问如http://192.168.31.138/lua_set_1?i=1&j=10进行测试。 如果我们用纯set指令是无法实现的。
3)注意,这个指令只能一次写出一个nginx变量,但是使用ngx.var接口可以解决这个问题:
location /foo {
set $diff '';
set_by_lua $sum '
local a = 32
local b = 56
ngx.var.diff = a - b; --写入$diff中
return a + b; --返回到$sum中
';
echo "sum = $sum, diff = $diff";
}
openresty开发系列33--openresty执行流程之2重写赋值阶段的更多相关文章
- openresty开发系列36--openresty执行流程之6日志模块处理阶段
openresty开发系列36--openresty执行流程之6日志模块处理阶段 一)header_filter_by_lua 语法:header_filter_by_lua <lua-scri ...
- openresty开发系列35--openresty执行流程之5内容content阶段
openresty开发系列35--openresty执行流程之5内容content阶段 content 阶段 ---init阶段---重写赋值---重写rewrite---access content ...
- openresty开发系列34--openresty执行流程之4访问阶段
openresty开发系列34--openresty执行流程之4访问阶段 访问阶段 用途:访问权限限制 返回403 nginx:allow 允许,deny 禁止 allow ip:deny ip: 涉 ...
- openresty开发系列33--openresty执行流程之3重写rewrite和重定向
openresty开发系列33--openresty执行流程之3重写rewrite和重定向 重写rewrite阶段 1)重定向2)内部,伪静态 先介绍一下if,rewrite指令 一)if指令语法:i ...
- openresty开发系列32--openresty执行流程之1初始化阶段
openresty开发系列32--openresty执行流程之初始化阶段 一)初始化阶段 1)init_by_lua init_by_lua_block init_by_lua_file语 ...
- openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息
openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息 为了实现业务系统针对不同地区IP访问,展示包含不同地区信息的业务交互界面.很多情况下系统需要根据用户访问的IP信息 ...
- openresty开发系列38--通过Lua+Redis 实现动态封禁IP
openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...
- openresty开发系列37--nginx-lua-redis实现访问频率控制
openresty开发系列37--nginx-lua-redis实现访问频率控制 一)需求背景 在高并发场景下为了防止某个访问ip访问的频率过高,有时候会需要控制用户的访问频次在openresty中, ...
- openresty开发系列31--openresty执行流程
openresty开发系列31--openresty执行流程 我们先看个例子 location /test { set $a 32; echo $a; set $a 56; e ...
随机推荐
- thymeleaf模板、thymeleaf语法相关中文文档教程
thymeleaf模板在SpringBoot中是默认的模范引擎技术,SpringBoot不推荐使用比较老旧的jsp.但如果您想使用jsp的话,当然也可以.我这里为您讲述thymeleaf模板的基本th ...
- The Instruction Set In Cortex-M3
The Cortex-M3 supports the Thumb-2 instruction set. This is one of the most important features of th ...
- 列车网络智能诊断工具链—MVB智能诊断仪
由于MVB网络采用分布式网络结构,各组网设备分布在不同电气柜,甚至是在不同车辆上,各组网设备往往来自于不同供应商,这给MVB网络调试及诊断带来了很大的难度.目前MVB网络调试及故障排查,主要是通过仪器 ...
- 功能更新 | medini analyze — 符合ISO 26262的功能安全平台工具
汽车电子电气系统的功能安全随着智能驾驶.新能源等新兴技术的发展而愈发受到重视.在国际功能安全标准ISO 26262的落地过程中遇到了很多的棘手问题:如何正确而有效地实施HARA以得到合 ...
- Jenkins+robotframework单机版简约教程
迫于某人极渴望学自动化测试,因此写下此简约教程.妈蛋我是个JAVA后端开发啊... 此教程为基于window系统的Jenkins单机版,测试代码无版本控制的精要压缩版本教程,勿喷 前提:通过Jenki ...
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
- 20199301《Linux内核原理与分析》第十一周作业
Linux Capability探索实验 一.实验描述 本实验中,将感受到linux capability功能在访问控制上的优势,掌握使用Capability达到遵守最小权限原则的目的,并分析linu ...
- 电脑重装后 python 2 3快速安装
背景: 电脑重装后,python也要跟着重装,将安装包.环境变量备份等安装完成后直接安装 重装前 1. pip包备份,命令窗口 pip freeze > py2.txt #python2的包 p ...
- python 批量打印PDF
有一批PDF文件,好几百个,每个只打印第2,3页,双面打印. 网上搜索一波,方案如下: 安装Ghostscript,GhostView,使用gsprint命令打印pdf文件. gsprint命令参数说 ...
- kvm创建windows2008虚拟机
virt-install -n win2008-fushi001 -r 16384 --vcpus=4 --os-type=windows --accelerate -c /data/kvm/imag ...