当前位置: 首页 > news >正文

6.OpenResty系列之深入理解(二)

1. 日志输出
vim /usr/local/openresty/nginx/conf/nginx.conf

默认配置如下

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;http {#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';#access_log  logs/access.log  main;

我们访问error.log,内容如下:

access.log,内容如下

# $remote_addr - 表示客户端发起请求的IP地址
# $remote_user - 表示发起请求的经过身份验证的用户的用户名(如果有)
# $time_local - 表示请求发起的本地时间
# $request - 表示客户端发起的HTTP请求,包括方法、URL和HTTP版本
# $status - 表示服务器返回的请求的HTTP状态码
# $body_bytes_sent - 表示服务器在响应体中发送的字节数
# $http_referer - 表示HTTP Referer头,指示引导客户端访问当前页面的页面的URL
# $http_user_agent - 表示客户端的Web浏览器或其他HTTP客户端的用户代理字符串
# $http_x_forwarded_for - 表示X-Forwarded-For头,通常用于跟踪客户端通过代理或负载均衡器连接到Web服务器时的原始IP地址
127.0.0.1 - - [07/Jan/2024:06:13:31 +0800] "GET login.cgi HTTP/1.1" 400 163 "-" "-"

如果你的日志需要归集,并且对时效性要求比较高那么用 lua-resty-logger-socket

lua-resty-logger-socket的目标是替代 Nginx 标准的 ngx_http_log_module 以非阻塞 IO 方式推送 access log 到远程服务器上。对远程服务器的要求是支持 syslog-ng 的日志服务

2. 子查询

Nginx 子请求是一种非常强有力的方式,它可以发起非阻塞的内部请求访问目标 location

需要注意的是,子请求只是模拟 HTTP 接口的形式, 没有 额外的 HTTP/TCP 流量,也 没有 IPC (进程间通信) 调用。所有工作在内部高效地在 C 语言级别完成

子请求与 HTTP 301/302 重定向指令 (通过 ngx.redirect) 完全不同,也与内部重定向 ((通过 ngx.exec) 完全不同

在发起子请求前,用户程序应总是读取完整的 HTTP 请求体 (通过调用 ngx.req.read_body 或设置 lua_need_request_body 指令为 on).

该 API 方法(ngx.location.capture_multi 也一样)总是缓冲整个请求体到内存中。因此,当需要处理一个大的子请求响应,用户程序应使用 cosockets 进行流式处理

下面是一个简单例子:

res = ngx.location.capture(uri)
  • 返回一个包含四个元素的 Lua 表 (res.status, res.header, res.body, 和 res.truncated)。
  • res.status (状态) 保存子请求的响应状态码。
  • res.header (头) 用一个标准 Lua 表储子请求响应的所有头信息。如果是“多值”响应头,这些值将使用 Lua (数组) 表顺序存储。例如,如果子请求响应头包含下面的行,则 res.header[“Set-Cookie”] 将存储 Lua 表 {“a=3”, “foo=bar”, “baz=blah”}。
 Set-Cookie: a=3Set-Cookie: foo=barSet-Cookie: baz=blah
  • res.body (体) 保存子请求的响应体数据,它可能被截断。用户需要检测 res.truncated (截断) 布尔值标记来判断 res.body 是否包含截断的数据。这种数据截断的原因只可能是因为子请求发生了不可恢复的错误,例如远端在发送响应体时过早中断了连接,或子请求在接收远端响应体时超时
3. 不同阶段共享变量

在 OpenResty 的体系中,可以通过共享内存的方式完成不同工作进程的数据共享,可以通过 Lua 模块方式完成单个进程内不同请求的数据共享

如何完成单个请求内不同阶段的数据共享呢?ngx.ctx 表就是为了解决这类问题而设计的

location /test {rewrite_by_lua_block {ngx.ctx.foo = 76}access_by_lua_block {ngx.ctx.foo = ngx.ctx.foo + 3}content_by_lua_block {ngx.say(ngx.ctx.foo)}}

首先 ngx.ctx 是一个表,所以我们可以对他添加、修改。它用来存储基于请求的 Lua 环境数据,其生存周期与当前请求相同 (类似 Nginx 变量)。它有一个最重要的特性:单个请求内的 rewrite (重写),access (访问),和 content (内容) 等各处理阶段是保持一致的

额外注意,每个请求,包括子请求,都有一份自己的 ngx.ctx 表

 location /sub {content_by_lua_block {ngx.say("sub pre: ", ngx.ctx.blah)ngx.ctx.blah = 32ngx.say("sub post: ", ngx.ctx.blah)}}location /main {content_by_lua_block {ngx.ctx.blah = 73ngx.say("main pre: ", ngx.ctx.blah)local res = ngx.location.capture("/sub")ngx.print(res.body)ngx.say("main post: ", ngx.ctx.blah)}}

访问 GET /main 输出

 main pre: 73sub pre: nilsub post: 32main post: 73
4. 防止SQL注入

对于 MySQL ,可以调用 ndk.set_var.set_quote_sql_str ,进行一次过滤即可,如果恰巧你使用的是 PostgreSQL ,调用 ndk.set_var.set_quote_pgsql_str 过滤输入变量

-- for MySQL
local req_id = [[1'; drop table cats;--]]
res, err, errno, sqlstate =db:query(string.format([[select * from cats where id = %s]],ndk.set_var.set_quote_sql_str(req_id)))
if not res thenngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")return
end
5. 发起新HTTP请求
http {server {listen    80;location /test {content_by_lua_block {ngx.req.read_body()local args, err = ngx.req.get_uri_args()local http = require "resty.http"   -- ①local httpc = http.new()local res, err = httpc:request_uri( -- ②"http://127.0.0.1:81/spe_md5",{method = "POST",body = args.data,})if 200 ~= res.status thenngx.exit(res.status)endif args.key == res.body thenngx.say("valid request")elsengx.say("invalid request")end}}}server {listen    81;location /spe_md5 {content_by_lua_block {ngx.req.read_body()local data = ngx.req.get_body_data()ngx.print(ngx.md5(data .. "*&^%$#$^&kjtrKUYG"))}}}
}

重点解释:
① 引用 resty.http 库资源,它来自 github https://github.com/pintsized/lua-resty-http, 下载tar.gz解压lua文件至openresty/lualib/resty/usr/local/openresty/lualib/resty
② 参考 resty-http 官方 wiki 说明,我们可以知道 request_uri 函数完成了连接池、HTTP 请求等一系列动作

相关文章:

  • PHPStudy快速搭建网站并结合内网穿透远程访问本地站点
  • 添加一个编辑的小功能(PHP的Laravel)
  • 计算机创新协会冬令营——暴力枚举题目03
  • 063:vue中一维数组与三维数组联动,类似购物车增减
  • 查看Linux系统内存、CPU、磁盘使用率和详细信息
  • Linux du和df命令
  • web学习笔记(十四)
  • spring-mvc数据绑定和表单标签库(介绍)
  • 51-5 Transformer 论文精读
  • Java反射获取实例并填充注解值
  • 2022 年全国职业院校技能大赛高职组云计算赛项试卷部分解析
  • 对象的复制
  • 【Android Studio】APP练手小项目——切换图片APP
  • 2024开放式耳机测评推荐榜单曝光!超热门开放式耳机选购攻略
  • C++牛客知识点3
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • conda常用的命令
  • Git 使用集
  • github从入门到放弃(1)
  • java2019面试题北京
  • java正则表式的使用
  • js ES6 求数组的交集,并集,还有差集
  • Median of Two Sorted Arrays
  • passportjs 源码分析
  • PAT A1050
  • python 学习笔记 - Queue Pipes,进程间通讯
  • SpriteKit 技巧之添加背景图片
  • Vue UI框架库开发介绍
  • 理清楚Vue的结构
  • 小程序测试方案初探
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 第二十章:异步和文件I/O.(二十三)
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Ruby)Ubuntu12.04安装Rails环境
  • (力扣)1314.矩阵区域和
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (篇九)MySQL常用内置函数
  • (转载)OpenStack Hacker养成指南
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • ./configure,make,make install的作用
  • .NET NPOI导出Excel详解
  • .Net7 环境安装配置
  • .NET简谈设计模式之(单件模式)
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net实现客户区延伸至至非客户区
  • .stream().map与.stream().flatMap的使用
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @requestBody写与不写的情况
  • @RequestMapping-占位符映射
  • @Valid和@NotNull字段校验使用
  • [ linux ] linux 命令英文全称及解释
  • [100天算法】-二叉树剪枝(day 48)