Nginx16-Lua扩展案例

零、文章目录

Nginx16-Lua扩展案例

1、ngx_lua案例

(1)需求
  • 请求地址:http://192.168.119.161/getByGender?name=张三&gender=1
  • Nginx接收到请求后,根据gender传入的值
    • 如果gender传入的是1,则在页面上展示张三先生
    • 如果gender传入的是0,则在页面上展示张三女士
    • 如果未传或者传入的不是1和2,则在页面上展示张三。
(2)配置代码实现
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
location /getByGender {
	default_type 'text/html';
	set_by_lua $name "
		local uri_args = ngx.req.get_uri_args()
		gender = uri_args['gender']
		name = uri_args['name']
		if gender=='1' then
			return name..'先生'
		elseif gender=='0' then
			return name..'女士'
		else
			return name
		end
	";
	header_filter_by_lua "
		ngx.header.aaa='bbb'
	";
	return 200 $name;
}
(3)测试验证
  • 重启Nginx
/usr/local/openresty/nginx/sbin/nginx -s reload
  • 访问地址:http://192.168.119.161/getByGender?name=张三&gender=1

image-20241018185210246

2、ngx_lua操作Redis

(1)概述
  • Redis在系统中经常作为数据缓存、内存数据库使用,在大型系统中扮演着非常重要的作用。在Nginx核心系统中,Redis是常备组件。

  • Nginx支持3种方法访问Redis,分别是HttpRedis模块、HttpRedis2Module、lua-resty-redis库。

    • HttpRedis模块提供的指令少,功能单一,适合做简单缓存,
    • HttpRedis2Module模块比HttpRedis模块操作更灵活,功能更强大。
    • Lua-resty-redis库是OpenResty提供的一个操作Redis的接口库,可根据自己的业务情况做一些逻辑处理,适合做复杂的业务逻辑。所以本次课程将主要以Lua-resty-redis来进行讲解。
  • lua-resty-redis提供了访问Redis的详细API,包括创建对接、连接、操作、数据处理等。这些API基本上与Redis的操作一一对应。

(2)准备Redis环境
  • 环境配置:Centos7.9 192.168.119.163: 6379 Docker安装Redis

  • Docker相关知识请参考Docker详解

  • Docker命令如下

    • docker run -ddocker run 是 Docker 的命令,用于创建一个新的容器。-d 参数告诉 Docker 在后台运行容器。
    • --name redis-container--name 参数用于为容器指定一个名称,这里我们将其命名为 redis-container
    • -v /path/to/your/data:/data-v 参数用于挂载卷,将宿主机的目录挂载到容器内部。/path/to/your/data 是宿主机上的目录,用于持久化 Redis 数据。:/data 表示将宿主机的目录挂载到容器的 /data 目录。
    • -v /path/to/your/redis.conf:/usr/local/etc/redis/redis.conf/path/to/your/redis.conf 是宿主机上的 Redis 配置文件路径。:/usr/local/etc/redis/redis.conf 表示将宿主机的配置文件挂载到容器的 /usr/local/etc/redis/redis.conf
    • -p 6379:6379-p 参数用于端口映射。6379:6379 表示将容器的 6379 端口映射到宿主机的 6379 端口,这样你就可以通过宿主机的端口访问 Redis 服务了。
    • redis:指定要使用的 Docker 镜像名称,这里是 redis
    • redis-server /usr/local/etc/redis/redis.conf:在容器内运行 redis-server 命令,并指定使用挂载的配置文件。
docker run -d \
  --name redis-container \
  -v /path/to/your/data:/data \
  -v /path/to/your/redis.conf:/usr/local/etc/redis/redis.conf \
  -p 6379:6379 \
  redis redis-server /usr/local/etc/redis/redis.conf
  • Redis运行成功进行测试,使用客户端进行连接,客户端百度网盘地址:https://pan.baidu.com/s/1tBdTkKWl241agJgfCUEYGA?pwd=1234

image-20241019152739799

(3)配置代码实现
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
location /redis {
    default_type "text/html";
    content_by_lua_block{
        local redis = require "resty.redis" -- 引入Redis
        local redisObj = redis:new()  --创建Redis对象
        redisObj:set_timeout(1000) --设置超时数据为1s
        local ok,err = redisObj:connect("192.168.119.163",6379) --设置redis连接信息
        if not ok then --判断是否连接成功
         ngx.say("failed to connection redis",err)
         return
        end
        ok,err = redisObj:set("username","TOM")--存入数据
        if not ok then --判断是否存入成功
         ngx.say("failed to set username",err)
         return
        end
        local res,err = redisObj:get("username") --从redis中获取数据
        ngx.say(res)	--将数据写会消息体中
        redisObj:close()
    }
}
(4)配置代码说明
  • (1)redis = require “resty.redis”

  • (2)new

    • 语法: redis,err = redis:new(),创建一个Redis对象。
  • (3)connect

    • 语法:ok,err=redis:connect(host,port[,options_table]),设置连接Redis的连接信息。

    • ok:连接成功返回 1,连接失败返回nil

    • err:返回对应的错误信息

  • (4)set_timeout

    • 语法: redis:set_timeout(time) ,设置请求操作Redis的超时时间。
  • (5)close

    • 语法: ok,err = redis:close(),关闭当前连接,成功返回1,失败返回nil和错误信息。
  • (6)redis命令对应的方法

    • 在lua-resty-redis中,所有的Redis命令都有自己的方法,方法名字和命令名字相同,只是全部为小写。
(5)测试验证
  • 重启Nginx
/usr/local/openresty/nginx/sbin/nginx -s reload
  • 访问地址:http://192.168.119.161/redis

image-20241019155838837

image-20241019155854120

3、ngx_lua操作Mysql

(1)概述
  • MySQL是一个使用广泛的关系型数据库。MYSQL相关知识请参考MYSQL详解。

  • 在ngx_lua中,MySQL有两种访问模式

    • 用ngx_lua模块和lua-resty-mysql模块:这两个模块是安装OpenResty时默认安装的。

    • 使用drizzle_nginx_module(HttpDrizzleModule)模块:需要单独安装,这个库现不在OpenResty中。

  • lua-resty-mysql是OpenResty开发的模块,使用灵活、功能强大,适合复杂的业务场景,同时支持存储过程的访问。我们以lua-resty-mysql为例进行讲解。

(2)准备MySQL环境
  • 环境配置:Centos7.9 192.168.119.163: 3306 Docker安装MySQL。账号:root 密码:123456
  • Docker相关知识请参考Docker详解
  • Docker命令如下
    • docker run:Docker 的命令,用于创建并启动一个新的容器。
    • -d:后台运行容器。使用 -d 参数可以让容器在后台运行,而不是在当前终端占用前台。
    • --name mysql:为新创建的容器指定一个名称,这里名称为 mysql。如果不指定,Docker 会默认生成一个名称。
    • -p 3306:3306:端口映射参数,格式为 <宿主机端口>:<容器端口>。这里将容器的 3306 端口映射到宿主机的 3306 端口,使得宿主机可以通过 3306 端口访问 MySQL 服务。
    • -e MYSQL_ROOT_PASSWORD=123456:设置环境变量。这里设置的环境变量是 MYSQL_ROOT_PASSWORD,其值为 123456,即 MySQL 的 root 用户的密码。这是 Docker 容器启动时需要的配置信息之一。
    • -v /path/to/mysql/data:/var/lib/mysql:挂载数据卷参数,格式为 <宿主机目录>:<容器目录>。这里将宿主机的 /path/to/mysql/data 目录挂载到容器的 /var/lib/mysql 目录。这样,MySQL 的数据文件就会被持久化存储在宿主机的指定目录中,而不是容器内部,从而实现数据的持久化。
    • mysql:latest:指定要使用的 Docker 镜像。这里使用的是 mysql 镜像的最新版本(latest 标签)。
docker run -d \
  --name mysql-container \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /path/to/mysql/data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:latest
  • Mysql运行成功进行测试,使用Navicat进行连接,Navicat百度网盘下载连接(科学安装方法请自行百度):https://pan.baidu.com/s/1xg5dJcaqv6cTw_opWJG9AQ?pwd=8888

image-20241021113005390

  • 创建数据库,创建表,插入数据
create database nginx_db;

use nginx_db;

create table users(
   id int primary key auto_increment,
   username varchar(30),
   birthday date,
   salary double
);

insert into users(id,username,birthday,salary) values(null,"TOM","1988-11-11",10000.0);
insert into users(id,username,birthday,salary) values(null,"JERRY","1989-11-11",20000.0);
insert into users(id,username,birthday,salary) values(null,"ROWS","1990-11-11",30000.0);
insert into users(id,username,birthday,salary) values(null,"LUCY","1991-11-11",40000.0);
insert into users(id,username,birthday,salary) values(null,"JACK","1992-11-11",50000.0);
(3)配置代码实现
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
location /mysql {
    content_by_lua_block{
        local mysql = require "resty.mysql"
        local db = mysql:new()
        local ok,err = db:connect{
            host="192.168.119.163",
            port=3306,
            user="root",
            password="123456",
            database="nginx_db"
        }
        db:set_timeout(1000)

        db:send_query("select * from users where id =1")
        local res,err,errcode,sqlstate = db:read_result()
        	ngx.say(res[1].id..","..res[1].username..","..res[1].birthday..","..res[1].salary)
    	db:close()
    }
}
(4)配置代码说明
  • (1)引入"resty.mysql"模块:local mysql = require “resty.mysql”

  • (2)new:

    • 创建一个MySQL连接对象,遇到错误时,db为nil,err为错误描述信息

    • 语法: db,err = mysql:new()

  • (3)connect

    • 尝试连接到一个MySQL服务器

    • 语法:ok,err=db:connect(options),options是一个参数的Lua表结构,里面包含数据库连接的相关信息。

    • host:服务器主机名或IP地址

    • port:服务器监听端口,默认为3306

    • user:登录的用户名

    • password:登录密码

    • database:使用的数据库名

  • (4)set_timeout

    • 设置子请求的超时时间(ms),包括connect方法
    • 语法:db:set_timeout(time)
  • (5)close

    • 关闭当前MySQL连接并返回状态。如果成功,则返回1;如果出现任何错误,则将返回nil和错误描述。
    • 语法:db:close()
  • (6)send_query

    • 异步向远程MySQL发送一个查询。如果成功则返回成功发送的字节数;如果错误,则返回nil和错误描述
    • 语法:bytes,err=db:send_query(sql)
  • (7)read_result

    • 从MySQL服务器返回结果中读取一行数据。res返回一个描述OK包或结果集包的Lua表
    • 语法:
      • res, err, errcode, sqlstate = db:read_result()
        • res:操作的结果集
        • err:错误信息
        • errcode:MySQL的错误码,比如1064
        • sqlstate:返回由5个字符组成的标准SQL错误码,比如42000
      • res, err, errcode, sqlstate = db:read_result(rows)
        • rows:指定返回结果集的最大值,默认为4
/// 如果是查询,则返回一个容纳多行的数组。每行是一个数据列的key-value对,如下
{
  {id=1,username="TOM",birthday="1988-11-11",salary=10000.0},
  {id=2,username="JERRY",birthday="1989-11-11",salary=20000.0}
}

///如果是增删改,则返回类上如下数据
{
	insert_id = 0,
	server_status=2,
	warning_count=1,
	affected_rows=2,
	message=nil
}
(5)处理查询结果
  • 通过上述的案例学习,read_result()得到的结果res都是table类型,要想在页面上展示,就必须知道table的具体数据结构才能进行遍历获取。处理起来比较麻烦。
  • 接下来我们介绍一种简单方式cjson,使用它就可以将table类型的数据转换成json字符串,把json字符串展示在页面上即可。
# 步骤一:引入cjson
local cjson = require "cjson"

# 步骤二:调用cjson的encode方法进行类型转换
cjson.encode(res) 
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
location /mysql1 {
    content_by_lua_block{

        local mysql = require "resty.mysql"
        local cjson = require "cjson"

        local db = mysql:new()

        local ok,err = db:connect{
            host="192.168.119.163",
            port=3306,
            user="root",
            password="123456",
            database="nginx_db"
        }
        db:set_timeout(1000)

        --db:send_query("select * from users where id = 2")
        db:send_query("select * from users")
        local res,err,errcode,sqlstate = db:read_result()
        ngx.say(cjson.encode(res))
         for i,v in ipairs(res) do
       ngx.say(v.id..","..v.username..","..v.birthday..","..v.salary)
        end
    	db:close()
    }
}
(4)实现数据增删改
  • 本方法是send_query和read_result组合的快捷方法。
res, err, errcode, sqlstate = db:query(sql[,rows])
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
location /mysql2 {
    content_by_lua_block{

        local mysql = require "resty.mysql"

        local db = mysql:new()

        local ok,err = db:connect{
        host="192.168.119.163",
        port=3306,
        user="root",
        password="123456",
        database="nginx_db",
        max_packet_size=1024,
        compact_arrays=false
        }
        db:set_timeout(1000)
        local res,err,errcode,sqlstate = db:query("select * from users")
        --local res,err,errcode,sqlstate = db:query("insert into users(id,username,birthday,salary) values(null,'zhangsan','2020-11-11',32222.0)")
        --local res,err,errcode,sqlstate = db:query("update users set username='lisi' where id = 6")
        --local res,err,errcode,sqlstate = db:query("delete from users where id = 6")
        db:close()
    }
}

4、综合案例-Redis缓存预热

(1)需求
  • 使用ngx_lua模块完成Redis缓存预热
    • 浏览器输入如下地址:http://191.168.119.163/mysqltoredis?username=TOM
    • 从表中查询出符合条件的记录,此时获取的结果为table类型
    • 使用cjson将table数据转换成json字符串
    • 将查询的结果数据存入Redis中
(2)功能实现
  • 在配置文件中/usr/local/openresty/nginx/conf/nginx.conf添加如下配置
init_by_lua_block{
	redis = require "resty.redis"
    mysql = require "resty.mysql"
    cjson = require "cjson"
}
location /mysqltoredis {
			default_type "text/html";
			content_by_lua_block{
				--获取请求的参数username
				local param = ngx.req.get_uri_args()["username"]
				--建立mysql数据库的连接
				local db = mysql:new()
				local ok,err = db:connect{
					host="192.168.119.163",
					port=3306,
					user="root",
					password="123456",
					database="nginx_db"
				}
				if not ok then
				 ngx.say("failed connect to mysql:",err)
				 return
				end
				--设置连接超时时间
				db:set_timeout(1000)
				--查询数据
				local sql = "";
				if not param then
					sql="select * from users"
				else
					sql="select * from users where username=".."'"..param.."'"
				end
				local res,err,errcode,sqlstate=db:query(sql)
				if not res then
				 ngx.say("failed to query from mysql:",err)
				 return
				end
				--连接redis
				local rd = redis:new()
				ok,err = rd:connect("192.168.119.163",6379)
				if not ok then
				 ngx.say("failed to connect to redis:",err)
				 return
				end
				rd:set_timeout(1000)
				--循环遍历数据
				for i,v in ipairs(res) do
				 rd:set("user_"..v.username,cjson.encode(v))
				end
				ngx.say("success")
				rd:close()
				db:close()
			}			
		}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初阶数据结构【3】--单链表(比顺序表还好的一种数据结构!!!)

本章概述 前情回顾单链表实现单链表彩蛋时刻&#xff01;&#xff01;&#xff01; 前情回顾 咱们在上一章博客点击&#xff1a;《顺序表》的末尾&#xff0c;提出了一个问题&#xff0c;讲出了顺序表的缺点——有点浪费空间。所以&#xff0c;为了解决这个问题&#xff0c;我…

Java项目-基于springboot框架的线上买菜系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

WebGL编程指南 - 高级变换与动画基础

学习使用一个矩阵变换库&#xff0c;该库封装了矩阵运算的数学细节。快速上手使用该矩阵库&#xff0c;对图形进行复合变换。在该矩阵库的帮助下&#xff0c;实现简单的动画效果。 矩阵变换库&#xff1a;cuon-matrix.js OpenGL中的函数&#xff1a; 书中 cuon-matrix.js 函数…

go jwt 用户登录和返回用户信息 token ----important!!!

1.每一行代码都有详细注释&#xff0c;解释了其功能和作用。这些注释可以帮助你理解代码如何工作&#xff0c;特别是在处理用户登录、生成 JWT、验证 JWT 和返回用户信息的过程中。 package main // 指定这个文件是一个可执行程序import ("fmt" …

SSRF-利用dict协议-攻击redis

1.靶场准备&#xff1a; CTFHub-技能树-Web-SSRF-Redis协议 蚁剑AntSword 2.简述&#xff1a; 2.1 SSRF 服务器端请求伪造&#xff0c;存在一个url参数&#xff0c;一般用于图片上传、网页重定向等&#xff0c;我们可以控制url参数&#xff0c;去访问内网服务器的敏感内容…

运用AI实践|如何从AI工具提升工作效率实践

文章目录 引言关于1024这个数值Python 语言获取算法代码Java语言获取算法代码其他语言获取算法代码1024 的用途和功能总结 &#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&am…

FPGA学习(6)-基础语法参数化设计阻塞与非阻塞

目录 1.两种参数化不改变源文件&#xff0c;只改仿真文件的值 2.参数化设计实现模块的重用 2.1不用参数化方法 2.1.1源文件 2.1.2仿真文件 2.1.3仿真波形及实验 2.2 用参数方法 2.2.1调用之前写的led灯闪烁模块&#xff0c;在本源函数中&#xff0c;例化4次调用之前的模…

Nginx15-Lua扩展模块

零、文章目录 Nginx15-Lua扩展模块 1、ngx_lua模块概念 淘宝开发的ngx_lua模块通过将lua解释器集成进Nginx&#xff0c;可以采用lua脚本实现业务逻辑&#xff0c;由于lua的紧凑、快速以及内建协程&#xff0c;所以在保证高并发服务能力的同时极大地降低了业务逻辑实现成本。…

ECharts饼图-饼图纹理,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…

信号(二)【信号的产生】

目录 1. 键盘组合键2. kill 命令3. 系统调用4. 异常5. 软件条件6. Term 和 Core 的区别 本篇文章介绍五种信号产生的方式&#xff0c;键盘组合键、kill 命令、系统调用、代码异常&#xff08;进程异常&#xff09;、软件条件来产生信号。 1. 键盘组合键 信号&#xff08;一&a…

商汤科技十周年公布新战略,将无缝集成算力、模型及应用

10月18日&#xff0c;恰逢商汤科技十周年庆典&#xff0c;“2024商汤十周年国际论坛&#xff1a;迈向AI 2.0共融新时代”在香港科学园成功举办。 据「TMT星球」了解&#xff0c;来自全球的行业领袖、政府代表、AI专家共聚于此&#xff0c;共同探讨AI行业的未来。 活动上&…

Linux隐藏权限介绍

隐藏权限概览 在Linux系统中&#xff0c;有时即便是以root用户身份&#xff0c;你也可能遇到无法修改特定文件的情况。这种限制往往源自chattr命令的应用&#xff0c;该命令用于为文件或目录设置“隐藏权限”&#xff0c;即底层属性&#xff0c;以增强系统安全性。值得注意的是…

Standard IO

为了提高可移植性&#xff0c;将通用IO接口经过再封装就形成了标准IO&#xff0c;标准IO不仅适用于Unix环境&#xff0c;也兼容非Unix环境&#xff0c;这也是为什么说我们应该尽可能的使用标准IO&#xff0c;通用IO通过文件描述符fd来与文件交互&#xff0c;为了以示区分&#…

极氪MIX:一台只有你想不到,没有它做不到的“家用神车”

了解极氪品牌的朋友应该都知道 极氪一直都在尝试打破目前汽车或者生活的一些现状 更愿意创造一些破界、超前的产品 比如说将家庭城市通勤、假日露营、自驾旅行、户外垂钓、朋友相聚等多场景融入一个空间的极氪MIX 这款车突破了SUV或MPV车型形态的固有限制 前悬仅 865mm&am…

【ArcGIS Pro实操第八期】绘制WRF三层嵌套区域

【ArcGIS Pro实操第八期】绘制WRF三层嵌套区域 数据准备ArcGIS Pro绘制WRF三层嵌套区域Map-绘制三层嵌套区域更改ArcMap地图的默认显示方向指定数据框范围 Map绘制研究区Layout-布局出图 参考 本博客基于ArcGIS Pro绘制WRF三层嵌套区域&#xff0c;具体实现图形参考下图&#x…

Centos安装Nginx 非Docker

客户的机器属于 Centos7 系列&#xff0c;由于其较为陈旧&#xff0c;2024开始众多镜像和软件源都已失效。此篇文章将详细记录在 Centos7 操作系统上从零开始安装 Nginx 的整个流程。 本文Nginx是安装在/usr/local/nginx下 详细步骤如下&#xff1a; 准备Nginx安装包&#x…

安防监控摄像头图传模组,1公里WiFi无线传输方案,监控新科技

在数字化浪潮汹涌的今天&#xff0c;安防监控领域也迎来了技术革新的春风。今天&#xff0c;我们就来聊聊这一领域的产品——摄像头图传模组&#xff0c;以及它如何借助飞睿智能1公里WiFi无线传输技术&#xff0c;为安防监控带来未有的便利与高效。 一、安防监控的新篇章 随着…

程序员适合玩的游戏:《人力资源机器》提升编程思维【Human Resource Machine】

程序员适合玩的游戏&#xff1a;《人力资源机器》提升编程思维【Human Resource Machine】 在当今这个技术日新月异的时代&#xff0c;编程已经成为一门不可或缺的技能。对于程序员来说&#xff0c;不仅需要扎实的专业知识&#xff0c;还需要不断锻炼逻辑思维和解决问题的能力…

用.NET开发跨平台应用程序采用 Avalonia 与MAUI如何选择

Avalonia是一个强大的框架&#xff0c;使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件&#xff0c;确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。这意味着开发人员可以共享他们的UI代码&#xff0c;…

RNN、LSTM 与 Bi-LSTM

一. RNN 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是深度学习领域一类具有内部自连接的神经网络能够学习复杂的矢量到矢量的映射。 最大特点&#xff1a;前面的序列数据可以用作后面的结果预测中。 一个简单的循环神经网络结构&#xff0c;其结构包…