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 请求等一系列动作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于SO-LSTM蛇群算法优化…

docker镜像的生成过程

镜像的生成过程 Docker镜像的构建过程,大量应用了镜像间的父子关系。即下层镜像是作为上层镜像的父镜像出现的,下层镜像是作为上层镜像的输入出现。上层镜像是在下层镜像的基础之上变化而来。 FROM centos:7 FROM指令是Dockerfile中唯一不可缺少的命令&a…

RocketMq直接上手(火箭班)

Apache RocketMQ官方文档:https://rocketmq.apache.org/zh/docs/bestPractice/06FAQ/,这里面涵盖了所有的基本知识、各种搭建环境、基础代码测试…还有各种问题总结,很值得自主学习。 1.配置依赖:pom.xml文件 可以只截取maven仓库…

3.3 IMAGE BLUR: A MORE COMPLEX KERNEL

我们研究了vecAddkernel和colorToGreyscaleConversion,其中每个线程只对一个数组元素执行少量算术运算。这些内核很好地服务于其目的:说明基本的CUDA C程序结构和数据并行执行概念。在这一点上,读者应该问一个显而易见的问题——所有CUDA线程…

C++类和对象(万字超详细讲解!!!)

文章目录 前言1.面向过程和面向对象区别2.类的基本概念2.1 类的引入2.2 类的定义2.3 类成员变量的命名规则2.4 类的访问限定符2.5 类的封装2.6 类的作用域2.7 类的实例化 3.类对象模型3.1 如何计算类对象的大小3.2 对齐规则 4.this指针4.1 this指针的引出4.2 this指针的特性4.3…

Android App打包加固后的APK无法安装问题

最近开发的一个应用要上架,正常流程打完包后去加固,由于以前一直用的是360的加固助手,这里开始也是选择用它。 使用360加固: 问题一、开始出现的问题是说应用未签名无法加固,我明明是签名后打的包,怎么会…

2023全球年度安全漏洞TOP 10

数字化转型步伐不断加快,社会各行业迎来了许多发展机遇,但与此同时面临着日益复杂的数据安全和网络安全威胁。其中,安全漏洞数量持续增长更是成为了各行各业不可忽视的挑战,尤其是在工业、金融、交通、国防、医疗和信息技术等领域…

K8S集群调度(2)

schedule的调度算法 预算策略 过滤出合适的节点 优先策略 选择部署的节点 nodeName:硬匹配,不走调度策略。node01. nodeSelector: 根据节点的标签选择,会走调度的算法。 只要是走调度算法,在不满足预算策略的情况下,所有po…

MyBatisPlus学习笔记一

1、简介 MyBatisPlus(简称MP)是一个MyBatis的增强工具,在MyBatisMyBatisMyBatis的的基础上只做增强不做改变,为简化开发,提高效率而生。 官网:MyBatis-Plus mybatisplus通过扫描实体类,并基于…

2-归并排序

算法:归并排序 思想:分治法【问题分解,归并排序递归解决,合并解】 实现:将数组通过递归方式自顶向下的分解至最小单元,再自底向上进行合并,以此实现排序 时间复杂度: Θ ( n l g n )…

老胡的周刊(第123期)

老胡的信息周刊[1],记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 ai-video-search-engine[2] 随着 TikTok 和 …

206.【2023年华为OD机试真题(C卷)】最大N个数与最小N个数的和(JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-最大N个数与最小N个数的和二.解题思路三.题解代…

力扣173. 二叉搜索树迭代器

深度优先搜索 思路: 遍历二叉搜索树,左子树总比根节点小,右子树总比根节点大;先深度遍历左子树,然后返回其父节点,然后遍历其右子树节点;使用栈数据结构存储节点数据,借用其“后进先…

空间转录组与单细胞转录组联合分析——MIA,代码分享(Nature Biotechnology :)

​ 原文:Integrating microarray-based spatial transcriptomics and single-cell RNA-seq reveals tissue architecture in pancreatic ductal adenocarcinomas | Nature Biotechnology 研究者采用 MIA 联合 scRNAseq 和 ST 数据,分析原发性胰腺导管腺癌…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷②

2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷2 目录 需要竞赛软件包环境以及备赛资源可私信博主!!! 2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷2 模块一 …

NX二次开发 Block UI 指定方位控件的应用

一、概述 NX二次开发中一般都是多个控件的组合,这里我首先对指定方位控件进行说明并结合选择对象控件,具体如下图所示。 二、实现功能获取方位其在选择面上原点的目标 2.1 在initialize_cb()函数中进行初始化,实现对象选择过滤面 //过滤平…

Unity中Shader面片一直面向摄像机

文章目录 前言一、实现思路1、 我们要实现模型面片一直跟着摄像机旋转,那么就需要用到旋转矩阵2、确定 原坐标系 和 目标坐标系3、确定旋转后坐标系基向量二、确定旋转后 坐标系基向量 在 原坐标系 下的值1、Z轴基向量2、假设Y轴基向量 和 世界空间下 的Y轴方向一致竖直向上3、…

go study twoday

交换两个数值 package mainimport "fmt"func main() {var num1 intvar num2 float32fmt.Println("请输入一个整数:")if _, err : fmt.Scanln(&num1); err ! nil {fmt.Println("输入错误:", err)return}fmt.Println(&q…

基于51单片机的蓄水池液位无人监测与自动调节系统设计

设计并实现基于51单片机的蓄水池液位无人监测与自动调节系统是一篇工程实践性很强的技术论文,以下是一个可能的论文提纲示例: **标题:** 基于51单片机的智能蓄水池液位监测与自动调节系统设计 **摘要:** 本文针对蓄水池液位实时…

在 ESP-IDF 环境下,使用标准 C 扩展 Micropython 模块

在 ESP-IDF 环境下,使用标准 C 扩展 Micropython 模块 源码地址 : https://gitee.com/Mars.CN/micropython_extend_example 一、 安装 ESP-IDF 环境 在其他课程中讲过,这里不再赘述,有机会再出教程吧,但需要注意的是…