OpenResty安装及使用

🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝

🍓 更多文章请点击
在这里插入图片描述在这里插入图片描述

文章目录

  • 一、OpenResty简介
  • 二、OpenResty安装
    • 2.1 安装开发库
    • 2.2 安装OpenResty仓库
    • 2.3 安装OpenResty
    • 2,4 安装opm工具
    • 2.5 目录结构
    • 2.6 配置nginx的环境变量
    • 2.7 启动和运行
  • 三、使用步骤
    • 3.1 添加对OpenResty的Lua模块的加载
    • 3.2 OpenResty监听请求
    • 3.3 编写item.lua
    • 3.4 重新加载配置
  • 四、请求参数处理
    • 4.1 获取参数的API
    • 4.2 获取参数并返回
  • 五、发送http请求的API
    • 5.1 封装http工具
  • 六、cjson的模块用来处理JSON的序列化和反序列化
  • 七、OpenResty提供了操作Redis的模块
    • 7.1 封装Redis工具
    • 7.2 实现Redis查询
  • 八、Nginx本地缓存
    • 8.1 本地缓存API
    • 8.2 实现本地缓存查询

一、OpenResty简介

官网地址 : http://openresty.org/cn/
在这里插入图片描述

OpenResty® 是一个基于 Nginx的高性能 Web 平台,用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

具备下列特点:

  • 具备Nginx的完整功能
  • 基于Lua语言进行扩展,集成了大量精良的 Lua 库、第三方模块
  • 允许使用Lua自定义业务逻辑、自定义库

二、OpenResty安装

首先你的Linux虚拟机必须联网

2.1 安装开发库

首先要安装OpenResty的依赖开发库,执行命令:

yum install -y pcre-devel openssl-devel gcc --skip-broken

2.2 安装OpenResty仓库

你可以在你的 CentOS 系统中添加 openresty 仓库,这样就可以便于未来安装或更新我们的软件包(通过 yum check-update 命令)。运行下面的命令就可以添加我们的仓库:

yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

如果提示说命令不存在,则运行:

yum install -y yum-utils 

然后再重复上面的命令

2.3 安装OpenResty

然后就可以像下面这样安装软件包,比如 openresty

yum install -y openresty

2,4 安装opm工具

opm是OpenResty的一个管理工具,可以帮助我们安装一个第三方的Lua模块。

如果你想安装命令行工具 opm,那么可以像下面这样安装 openresty-opm 包:

yum install -y openresty-opm

2.5 目录结构

默认情况下,OpenResty安装的目录是:/usr/local/openresty
OpenResty就是在Nginx基础上集成了一些Lua模块。

在这里插入图片描述

2.6 配置nginx的环境变量

打开配置文件:

vi /etc/profile

在最下面加入两行:

export NGINX_HOME=/usr/local/openresty/nginx
export PATH=${NGINX_HOME}/sbin:$PATH

NGINX_HOME:后面是OpenResty安装目录下的nginx的目录

然后让配置生效:

source /etc/profile

2.7 启动和运行

OpenResty底层是基于Nginx的,查看OpenResty目录的nginx目录
在这里插入图片描述
所以运行方式与nginx基本一致:

# 启动nginx
nginx# 重新加载配置
nginx -s reload# 停止
nginx -s stop

修改/usr/local/openresty/nginx/conf/nginx.conf文件,内容如下:


#user  nobody;
worker_processes  1;
error_log  logs/error.log;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       8081;server_name  localhost;location / {root   html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}
}

在Linux的控制台输入命令以启动nginx:

nginx

启动nginx后访问,替换自己的ip,端口8081.如何有安全组,则放开
在这里插入图片描述

三、使用步骤

我们需要在OpenResty中编写业务,查询商品数据并返回到浏览器。
但是这次,我们先在OpenResty接收请求,返回假的商品数据。

3.1 添加对OpenResty的Lua模块的加载

OpenResty的很多功能都依赖于其目录下的Lua库,需要在nginx.conf中指定依赖库的目录,修改/usr/local/openresty/nginx/conf/nginx.conf文件,在其中的http下面,添加下面代码

#lua 模块
lua_package_path "/usr/local/openresty/lualib/?.lua;;";#c模块     
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";  

在这里插入图片描述

3.2 OpenResty监听请求

监听/api/item路径,响应结果由lua/item.lua文件来决定

修改/usr/local/openresty/nginx/conf/nginx.conf文件,在nginx.conf的server下面,添加对/api/item这个路径的监听:

location  /api/item {# 默认的响应类型default_type application/json;# 响应结果由lua/item.lua文件来决定content_by_lua_file lua/item.lua;
}

在这里插入图片描述

3.3 编写item.lua

/usr/loca/openresty/nginx目录创建文件夹:lua
/usr/loca/openresty/nginx/lua文件夹下,新建文件:item.lua

在这里插入图片描述编写item.lua,返回假数据
item.lua中,利用ngx.say()函数返回数据到Response中

ngx.say('{"id":10010,"name":"桌子","title":"桌子出售","price":1000,"createTime":"2024-09-21T16:00:00.000+00:00"}')

3.4 重新加载配置

nginx -s reload

成功显示
在这里插入图片描述

四、请求参数处理

上述我们在OpenResty接收前端请求,但是返回的是假数据。
要返回真实数据,必须根据前端传递来的商品id,查询商品信息才可以。
那么如何获取前端传递的商品参数呢?

4.1 获取参数的API

OpenResty中提供了一些API用来获取不同类型的前端请求参数:
在这里插入图片描述

4.2 获取参数并返回

在这里插入图片描述

可以发现上述中使用的时路径占位符,所以使用api中的正则表达式获取

  1. 修改/usr/loca/openresty/nginx/nginx.conf文件中监听/api/item的代码,利用正则表达式获取ID:

    location ~ /api/item/(\d+) {# 默认的响应类型default_type application/json;# 响应结果由lua/item.lua文件来决定content_by_lua_file lua/item.lua;
    }
    

    在这里插入图片描述

  2. 修改/usr/loca/openresty/nginx/lua/item.lua文件,获取id并拼接到结果中返回:

    下图为我主页文章:lua基本语法使用可自行查看

    语法---可以使用操作符…(两个点)

    print("hello".."world")
    
    -- 获取商品id
    local id = ngx.var[1]
    -- -- 拼接并返回
    ngx.say('{"id":'..id..',"name":"桌子","title":"桌子出售","price":1000,"createTime":"2024-09-21T16:00:00.000+00:00"}')
    

    在这里插入图片描述结果成功
    说明我们请求参数获取成功在这里插入图片描述

五、发送http请求的API

local resp = ngx.location.capture("/path",{method = ngx.HTTP_GET,   -- 请求方式args = {a=1,b=2},  -- get方式传参数body = "c=3&d=4"  -- post方式传参
})

返回的响应内容包括:

  • resp.status:响应状态码
  • resp.header:响应头,是一个table
  • resp.body:响应体,就是响应数据

注意:这里的path是路径,并不包含IP和端口。这个请求会被nginx内部的server监听并处理。
但是我们希望这个请求发送到Tomcat服务器(后端),所以还需要编写一个server来对这个路径做反向代理:

 location /path {proxy_pass http://192.168.130.1:8081; }

5.1 封装http工具

我们封装一个发送Http请求的工具,基于ngx.location.capture来实现查询,方便后续使用
之前我们说过,OpenResty启动时会加载以下两个目录中的工具文件:
在这里插入图片描述
所以,自定义的http工具也需要放到这个目录下。

  1. /usr/local/openresty/lualib目录下,新建一个common.lua文件(公共函数封装)

这个工具将read_http函数封装到_M这个table类型的变量中,并且返回,这类似于导出。
使用的时候,可以利用require('common')来导入该函数库,这里的common是函数库的文件名。

	-- 封装函数,发送http请求,并解析响应local function read_http(path, params)local resp = ngx.location.capture(path,{method = ngx.HTTP_GET,args = params,})if not resp then-- 记录错误信息,返回404ngx.log(ngx.ERR, "http请求查询失败, path: ", path , ", args: ", args)ngx.exit(404)endreturn resp.bodyend-- 将方法导出local _M = {  read_http = read_http}  return _M
  1. 使用http函数发送请求,实现商品查询

修改/usr/local/openresty/lua/item.lua文件,利用刚刚封装的函数库实现查询

-- 引入自定义common工具模块,返回值是common中返回的 _M
local common = require("common")
-- 从 common中获取read_http这个函数
local read_http = common.read_http
-- 获取路径参数
local id = ngx.var[1]
-- 根据id查询商品
local itemJSON = read_http("/item/".. id, nil)
-- 返回结果
ngx.say(itemJSON)

六、cjson的模块用来处理JSON的序列化和反序列化

官方地址:https://github.com/openresty/lua-cjson/

1)引入cjson模块:

local cjson = require "cjson"

2)序列化:

local obj = {name = 'jack',age = 21
}
-- 把 table 序列化为 json
local json = cjson.encode(obj)

3)反序列化:

local json = '{"name": "jack", "age": 21}'
-- 反序列化 json为 table
local obj = cjson.decode(json);
print(obj.name)

七、OpenResty提供了操作Redis的模块

7.1 封装Redis工具

为了方便,我们将Redis操作封装到之前的common.lua工具库中。
修改/usr/local/openresty/lualib/common.lua文件:

-- 导入redis
local redis = require('resty.redis')
-- 初始化redis
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)-- 关闭redis连接的工具方法,其实是放入连接池
local function close_redis(red)local pool_max_idle_time = 10000 -- 连接的空闲时间,单位是毫秒local pool_size = 100 --连接池大小local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)if not ok thenngx.log(ngx.ERR, "放入redis连接池失败: ", err)end
end-- 查询redis的方法 ip和port是redis地址,key是查询的key
local function read_redis(ip, port, key)-- 获取一个连接local ok, err = red:connect(ip, port)if not ok thenngx.log(ngx.ERR, "连接redis失败 : ", err)return nilend-- 查询redislocal resp, err = red:get(key)-- 查询失败处理if not resp thenngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)end--得到的数据为空处理if resp == ngx.null thenresp = nilngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)endclose_redis(red)return resp
end-- 封装函数,发送http请求,并解析响应
local function read_http(path, params)local resp = ngx.location.capture(path,{method = ngx.HTTP_GET,args = params,})if not resp then-- 记录错误信息,返回404ngx.log(ngx.ERR, "http查询失败, path: ", path , ", args: ", args)ngx.exit(404)endreturn resp.body
end
-- 将方法导出
local _M = {  read_http = read_http,read_redis = read_redis
}  
return _M

7.2 实现Redis查询

修改/usr/local/openresty/lua/item.lua文件,添加一个查询函数:

-- 导入common函数库
local common = require('common')
local read_http = common.read_http
local read_redis = common.read_redis
-- 导入cjson库
local cjson = require('cjson')-- 封装查询函数 先查询redis,再查http
function read_data(key, path, params)-- 查询redislocal val = read_redis("127.0.0.1", 6379, key)-- 判断redis是否命中if not val thenngx.log(ngx.ERR, "redis查询失败,尝试查询http, key: ", key)-- redis查询失败,去查询httpval = read_http(path, params)end-- 返回数据return val
end-- 获取路径参数
local id = ngx.var[1]-- 查询商品信息
local itemJSON = read_data("item:id:" .. id,  "/item/" .. id, nil)ngx.say(itemJSON)

最终重新加载

nginx -s reload

八、Nginx本地缓存

8.1 本地缓存API

OpenResty为Nginx提供了shard dict的功能,可以在nginx的多个worker之间共享数据,实现缓存功能。

  1. 开启共享字典,在nginx.conf的http下添加配置:
     # 共享字典,也就是本地缓存,名称叫做:item_cache,大小150mlua_shared_dict item_cache 150m; 
    
  2. 操作共享字典:
-- 获取本地缓存对象
local item_cache = ngx.shared.item_cache
-- 存储, 指定key、value、过期时间,单位s,默认为0代表永不过期
item_cache:set('key', 'value', 1000)
-- 读取
local val = item_cache:get('key')

8.2 实现本地缓存查询

修改/usr/local/openresty/lua/item.lua文件,修改read_data查询函数,添加本地缓存逻辑:

-- 导入common函数库
local common = require('common')
local read_http = common.read_http
local read_redis = common.read_redis
-- 导入cjson库
local cjson = require('cjson')
-- 导入共享词典,本地缓存
local item_cache = ngx.shared.item_cache-- 封装查询函数
function read_data(key, expire, path, params)-- 查询本地缓存local val = item_cache:get(key)if not val thenngx.log(ngx.ERR, "本地缓存查询失败,尝试查询Redis, key: ", key)-- 查询redisval = read_redis("127.0.0.1", 6379, key)-- 判断查询结果if not val thenngx.log(ngx.ERR, "redis查询失败,尝试查询http, key: ", key)-- redis查询失败,去查询httpval = read_http(path, params)endend-- 查询成功,把数据写入本地缓存item_cache:set(key, val, expire)-- 返回数据return val
end-- 获取路径参数
local id = ngx.var[1]-- 查询商品信息
local itemJSON = read_data("item:id:" .. id, 1800,  "/item/" .. id, nil)ngx.say(itemJSON)

最终重新加载

nginx -s reload

成功获取数据
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

构建高可用和高防御力的云服务架构第四部分:REDIS(4/5)

本文的目的是深入探讨Redis在构建高可用和高防御力云服务架构中的应用。我们将分析Redis的工作原理、核心特性以及如何通过Redis优化云服务架构的性能和安全性。此外,我们还将提供实际案例和最佳实践,帮助读者更好地理解和应用Redis,以构建更…

中小企业体系技术抽象沉淀-异地灾备篇

IT团队内部使用工具 系列文章:https://blog.csdn.net/caicongyang/article/details/136857045 DDL DML管控 https://github.com/hhyo/Archery/ flyway 文档编写 wiki 技术对外输出文档推荐gitbook 同城双活数据同步方案 总览: vivo 系列文章&#x…

普通程序员如何快速入门AIGC

文章目录 第1阶段:基础知识打牢 (1-2周)第2阶段:深度学习理论与实践 (2-4周)第3阶段:AIGC 生成技术入门 (3-5周)第4阶段:进阶学习和项目实战 (5-8周)第5阶段:保持学习和更新 (持续进行) 要快速入门 AIGC(AI…

SPI驱动学习六(SPI_Master驱动程序)

目录 前言一、SPI_Master驱动程序框架1. SPI传输概述1.1 数据组织方式1.2 SPI控制器数据结构 2. SPI传输函数的两种方法2.1 老方法2.2 新方法 二、如何编写SPI_Master驱动程序1. 编写设备树2. 编写驱动程序 三、SPI_Master驱动程序简单示例demo1. 使用老方法编写的SPI Master驱…

Webrtc开发实战系列 - win10+vs2022下编译最新webrtc代码

1. 准备起步 操作系统:windows 10 安装 vs2019/vs2022 安装 win10 sdk 19041 一定勾选 Debugging Tools for Windows 科学上网准备代理工具 磁盘剩余空间至少 30G 推荐用一台干净的机器或者虚拟机来编译WebRTC,安装过python的会出现一些非常棘手…

昂首资本:欧美货币对的交易智慧

在外汇市场的海洋中,昂首资本的投资者们深知,把握欧美货币对的交易时段是获取收益的关键。欧美货币对,即欧元对美元,因其在欧洲和美国市场的活跃交易时段而备受瞩目。这两个时段不仅交易量巨大,而且价格波动剧烈&#…

【隐私计算篇】利用多方安全计算MPC实现VGG16人脸识别隐私推理

1. 背景介绍 本文主要介绍一种利用多方安全计算MPC技术,实现VGG16的人脸识别模型,侧重于模型推理阶段,目前已经公开专利,因此以下内容的分享都是基于公开材料。该分享涉及到最小化多方安全计算(MPC)以及明密文混合计算的思想&…

JAVA开源项目 甘肃非物质文化网站 计算机毕业设计

本文项目编号 T 043 ,文末自助获取源码 \color{red}{T043,文末自助获取源码} T043,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

python画图|把X轴标签移动到图像顶端

在前述学习过程中,我们一直使用的是默认的轴坐标,X轴往往置于图像的下端。 有时候,也会有将X轴标签放置在图形顶端的需求,今天就一起学习一下。 【1】官网教程 首先打开官网,可以通过下述链接一步直达: …

软考高级:系统安全 -区块链特点:去中心化、开放性、自治性、安全性、匿名性

讲解 生活化例子 想象一下,你和朋友们玩一个共享账本的游戏。每个人都可以在账本上记账,没人可以单独改动账本,大家都可以随时查看账本内容,也不用再信任某个单独的人来管理账本。这就类似于区块链的工作原理。 概念讲解 去中…

基于c++实现的简易shell

代码逻辑 核心思想 解析命令行,拆解命令及其选项创建子进程,在子进程中执行命令如果是前台执行命令,则父进程就阻塞等待子进程中命令执行结束后回收子进程的资源如果是后台执行命令,则父进程不进行阻塞等待,可继续向下…

【机器学习】---神经架构搜索(NAS)

这里写目录标题 引言1. 什么是神经架构搜索(NAS)1.1 为什么需要NAS? 2. NAS的三大组件2.1 搜索空间搜索空间设计的考虑因素: 2.2 搜索策略2.3 性能估计 3. NAS的主要方法3.1 基于强化学习的NAS3.2 基于进化算法的NAS3.3 基于梯度的…

【数据结构】图的遍历

快乐的流畅:个人主页 个人专栏:《C游记》《进击的C》《Linux迷航》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、深度优先遍历1.1 定义1.2 实现 二、广度优先遍历2.1 定义2.2 实现 三、DFS与BFS的对比 引言 前置知识&…

linux用户管理运行级别找回root密码

目录 1.用户的添加 1.1用户添加的基本指令 1.2不指定家目录的名称 1.3指定家目录的名称 2.密码的修改 3.删除目录 3.1删除的两个情况 3.2删除的流程 4.查询用户的信息 5.用户的切换 6.用户组 6.1用户组的概念 6.2创建用户到指定的组 6.3修改用户到其他的组 6.4用…

SpringCloud Alibaba之Sentinel实现熔断与限流

(学习笔记) QPS(Query Per Second):即每秒查询率,是对⼀个特定的查询服务器在规定时间内所处理流量多少的衡量标准。QPS req/sec 请求数/秒,即每秒的响应请求数,也即是最⼤吞吐能⼒…

ATTCK实战系列-Vulnstack三层网络域渗透靶场(一)

ATT&CK实战系列-Vulnstack三层网络域渗透靶场(一) 一、环境搭建1.1 靶场拓扑图1.2 靶场下载链接1.3 虚拟机配置1.3.1 Windows 7 (web服务器)1.3.2 Windows 2008 (域控)1.3.3 Win2k3 (域内主机) 二、外网打点突破2.1 信息搜集2.2 phpmyadmin 后台 Get…

肾癌的多模态预测模型-临床-组织学-基因组

目录 摘要 技术路线 ① lncRNA的预测模型 ②病理 WSI 的分类器 ③临床病理分类器 模型结果 与别的模型比较 同行评审学习 1)使用lncRNA的原因 2)模型临床使用意义 3)关于截止值的使用 摘要 A multi-classifier system integrated…

.NET常见的5种项目架构模式

前言 项目架构模式在软件开发中扮演着至关重要的角色,它们为开发者提供了一套组织和管理代码的指导原则,以提高软件的可维护性、可扩展性、可重用性和可测试性。 假如你有其他的项目架构模式推荐,欢迎在文末留言🤞!&a…

Java_Day04学习

类继承实例 package com.dx.test03; public class extendsTest {public static void main(String args[]) {// 实例化一个Cat对象,设置属性name和age,调用voice()和eat()方法,再打印出名字和年龄信息/********* begin *********/Cat cat ne…

实战OpenCV之直方图

基础入门 直方图是对数据分布情况的图形表示,特别适用于图像处理领域。在图像处理中,直方图通常用于表示图像中像素值的分布情况。直方图由一系列矩形条(也被称为bin)组成,每个矩形条的高度表示某个像素值(…