高性能软件负载OpenResty整合Reids集群配置

news2024/11/26 17:45:49

目录

  • 1 OpenResty整合Reids集群配置
    • 1.1 下载安装lua_resty_redis
      • 1.1.1 连接Redis集群封装
      • 1.1.2 配置lua脚本路径
      • 1.1.3 测试脚本
    • 1.2 请求参数封装
      • 1.2.1 测试脚本
    • 1.3 抓取模板内容封装
      • 1.3.1 下载安装lua-resty-http
      • 1.3.2 测试脚本
    • 1.4 模版渲染配置
      • 1.4.1 下载安装lua-resty-template
      • 1.4.2 使用方式
      • 1.4.3 测试
  • 2 整体业务分析
    • 2.1 编写lua脚本
    • 2.2 编写nginx配置
      • 2.2.1 添加本地缓存
      • 2.2.2 编写nginx配置文件
    • 2.3 初始化数据
    • 2.4 访问测试


1 OpenResty整合Reids集群配置

在这里插入图片描述

1.1 下载安装lua_resty_redis

lua_resty_redis 它是一个基于rockspec API的为ngx_lua模块提供Lua redis客户端的驱动。

resty-redis-cluster模块地址:https://github.com/steve0511/resty-redis-cluster

  • resty-redis-cluster/lib/resty/下面的文件 拷贝到 openresty/lualib/resty

总共两个文件rediscluster.lua,xmodem.lua

1.1.1 连接Redis集群封装

创建redisUtils.lua的文件

xxxxxxxxxx
--操作Redis集群,封装成一个模块
--引入依赖库
local redis_cluster = require "resty.rediscluster"


--配置Redis集群链接信息
local config = {
    name = "testCluster",                   --rediscluster name
    serv_list = {                           --redis cluster node list(host and port),
                   {ip="192.168.245.164", port = 7001},
                   {ip="192.168.245.164", port = 7002},
                   {ip="192.168.245.164", port = 7003},
                   {ip="192.168.245.164", port = 7004},
                   {ip="192.168.245.164", port = 7005},
                   {ip="192.168.245.164", port = 7006},
    },
    keepalive_timeout = 60000,              --redis connection pool idle timeout
    keepalive_cons = 1000,                  --redis connection pool size
    connection_timout = 1000,               --timeout while connecting
    max_redirection = 5
}


--定义一个对象
local lredis = {}

--创建查询数据get()
function lredis.get(key)
        local red = redis_cluster:new(config)
        local res, err = red:get(key)
        if err then
            ngx.log(ngx.ERR,"执行get错误:",err)
            return false
        end
        return res
end

-- 执行hgetall方法并封装成table
function lredis.hgetall(hash_key)
    local red = redis_cluster:new(config)
    local flat_map, err = red:hgetall(hash_key)
    if err then
        ngx.log(ngx.ERR,"执行hgetall错误:",err)
        return false
    end
    local result = {}
    for i = 1, #flat_map, 2 do
        result[flat_map[i]] = flat_map[i + 1]
    end
    return result
end

-- 判断key中的item是否在布隆过滤器中
function lredis.bfexists(key,item)
             local red = redis_cluster:new(config)
             -- 通过eval执行脚本
             local res,err = red:eval([[
             local  key=KEYS[1]
             local  val= ARGV[1]
             local  res,err=redis.call('bf.exists',key,val)
             return res
                ]],1,key,item)
     if  err then
        ngx.log(ngx.ERR,"过滤错误:",err)
        return false
     end
     return res
end

return lredis

1.1.2 配置lua脚本路径

我们编写了lua脚本需要交给nginx服务器去执行,我们需要将创建一个lua目录,并在全局的nginx‘配置文件中配置lua目录,配置参数使用lua_package_path

xxxxxxxxxx
# 配置redis 本地缓存
lua_shared_dict redis_cluster_slot_locks 100k;
# 配置lua脚本路径
lua_package_path "/usr/local/openresty/script/?.lua;;"; #注意后面是两个分号

完整的配置如下

xxxxxxxxxx

user  root;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
# 注意!! error日志输出info级别日志
error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #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;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    # 注意!!配置redis 本地缓存
    lua_shared_dict redis_cluster_slot_locks 100k;
    # 注意!!lua脚本路径
    lua_package_path "/usr/local/openresty/script/?.lua;;";
    #gzip  on;
    include     conf.d/*.conf;
}

1.1.3 测试脚本

在 nginx配置文件嵌入lua脚本进行测试

xxxxxxxxxx
server {
        listen 9999;
        charset utf-8;
    
        location /test {
            default_type text/html;
            content_by_lua '
               local lrredis = require("redisUtils")
               -- 尝试读取redis中key的值
               local value = lrredis.get("key")
               --判断key是否在bf_taxi的布隆过滤器中
               local bfexist = lrredis.bfexists("bf_taxi","key")
               local htest = lrredis.hgetall("h_taxi")
               ngx.log(ngx.INFO, "key的值是",value)
               ngx.log(ngx.INFO, "bf_taxi布隆过滤器key的状态",bfexist)
               ngx.log(ngx.INFO, "h_taxi[url]的值是",htest["url"])
            ';
        }
    }

设置Redis数据

xxxxxxxxxx
# 登录Redis
docker exec -ti redis01 /bin/bash
redis-cli -h 172.18.0.2 -c
# 设置key
set key value11
# 设置hash
hset h_taxi url http://www.baidu.com
# 创建布隆过滤器
BF.RESERVE bf_taxi 0.01 10000 NONSCALING
# 布隆过滤器添加key
BF.ADD bf_taxi key

访问测试

访问查看nginx日志打印

xxxxxxxxxx
tail -f /usr/local/openresty/nginx/logs/error.log

在这里插入图片描述

1.2 请求参数封装

nginx为了能够处理请求需要获取请求数据,需要将获取请求参数的lua脚本封装以下,创建requestUtils.lua的文件

xxxxxxxxxx
--定义一个对象
local lreqparm={}
-- 获取请求参数的方法
function lreqparm.getRequestParam()
    -- 获取请求方法 get或post
   local request_method = ngx.var.request_method
    -- 定义参数变量
    local args = nil
    if "GET" == request_method then
        args = ngx.req.get_uri_args()
    elseif "POST" == request_method then
        ngx.req.read_body()
        args = ngx.req.get_post_args()
    end
    return args
end
return lreqparm

1.2.1 测试脚本

xxxxxxxxxx
server {
        listen 9999;
        charset utf-8;

        location /testreq {
            default_type text/html;
            content_by_lua '
              local lreqparm = require("requestUtils")
              local params = lreqparm.getRequestParam()
              local title = params["title"]
              if title ~= nil then
                  ngx.say("<p>请求参数的Title是:</p>"..title)
                return 
              end
              ngx.say("<P>没有输入title请求参数<P>")
            ';
        }
    }

访问http://192.168.64.150:9999/testreq?title=ceshi 测试

在这里插入图片描述

1.3 抓取模板内容封装

1.3.1 下载安装lua-resty-http

下载地址 https://github.com/ledgetech/lua-resty-http

lua-resty-http-master\lib\resty下的所有文件复制到openresty/lualib/resty httpclient

总共两个文件http.lua,http_headers.lua

因为需要从远程服务器抓取远程页面的内容,需要用到http模块,将其封装起来,创建requestHtml.lua

xxxxxxxxxx
-- 引入Http库
local http = require "resty.http"
--定义一个对象
local lgethtml={}

function lgethtml.gethtml(requesturl)

    --创建客户端
    local httpc = http:new()
    local resp,err = httpc:request_uri(requesturl,
        {
                method = "GET",
                headers = {["User-Agent"]="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"}
        })
    --关闭连接
    httpc:close()
    if not resp then
        ngx.say("request error:",err)
        return
    end
    local result = {}
    --获取状态码
    result.status = resp.status
    result.body  = resp.body
    return result

end

return lgethtml

1.3.2 测试脚本

模板文件我们用

x
server {
        listen 9999;
        charset utf-8;

        # 配置路径重写
        location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
            rewrite ^/(.*) http://www.resources.com/$1 permanent;
        }
    
        location /testgetHtml {
            default_type text/html;
            content_by_lua '
                local lgethtml = require("requestHtml")
                local url = "http://127.0.0.1/template.html"
                local result = lgethtml.gethtml(url);
                ngx.log(ngx.INFO, "状态是",result.status)
                ngx.log(ngx.INFO, "body是",result.body)
                ngx.say(result.body)
            ';
        }
    }

访问http://192.168.64.181:9999/testgetHtml 测试

在这里插入图片描述

1.4 模版渲染配置

1.4.1 下载安装lua-resty-template

xxxxxxxxxx
wget https://github.com/bungle/lua-resty-template/archive/v1.9.tar.gz
tar -xvzf v1.9.tar.gz

​ 解压后可以看到lib/resty下面有一个template.lua,这个就是我们所需要的,在template目录中还有两个lua文件,将这两个文件复制到/usr/openResty/lualib/resty中即可。

1.4.2 使用方式

xxxxxxxxxx
local template = require "resty.template"
-- Using template.new
local html=[[<html>
<body>
  <h1>{{message}}</h1>
</body>
</html>
]]
template.render(html, { message = params["title"] })

1.4.3 测试

在nginx中配置文件中嵌入lua脚本执行测试

x
server {
        listen 9999;
        charset utf-8;

         location /testtemplate {
            default_type text/html;
            content_by_lua '
              local lreqparm = require("requestUtils")
              local template = require "resty.template"
              local params = lreqparm.getRequestParam()
               -- Using template.new
               local html=[[<html>
                             <body>
                                <h1>{{message}}</h1>
                             </body>
                         </html>
                                ]]
                template.render(html, { message = params["title"] })
            ';
        }

    }

访问http://192.168.64.150:9999/testtemplate?title=123456

在这里插入图片描述

2 整体业务分析

整个调用流程如下,需要使用lua脚本编写,整体流程分为7 步

在这里插入图片描述

上面我们将各个组件都给封装了,下面我们需要将各个组件组合起来

2.1 编写lua脚本

创建一个requestTemplateRendering.lua的lua脚本

x
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by baiyp.
--- DateTime: 2020/11/24 13:24
---


local template = require("resty.template")
local lrredis = require("redisUtils")
local lgethtml = require("requestHtml")
local lreqparm = require("requestUtils")
--获取请求参数
local reqParams = lreqparm.getRequestParam()
-- 定义本地缓存
local html_template_cache = ngx.shared.html_template_cache

-- 获取请求ID的参数
local reqId = reqParams["id"];

ngx.log(ngx.INFO, "requestID:", reqId);
-- 校验参数
if reqId==nil then
    ngx.say("缺少ID参数");
    return
end

-- 布隆过滤器检查id是否存在
local bfexist = lrredis.bfexists("bf_taxi",reqId)
ngx.log(ngx.INFO, "布隆过滤器检验:", bfexist)

-- 校验key不存在直接返回
if bfexist==0 then
    ngx.say("布隆过滤器校验key不存在...")
    return
end

-- 拼接hget的key
local hgetkey = "hkey_".. reqId

-- 通过hget获取map的所有数据
local templateData = lrredis.hgetall(hgetkey);
if next(templateData) == nil then
    ngx.say("redis没有存储数据...")
    return
end


--获取模板价格数据
local amount = templateData["amount"]
ngx.log(ngx.INFO, "amount:", amount)
if amount == nil then
    ngx.say("价格数据未配置");
    return
end


-- 获取本地缓存对象
ngx.log(ngx.INFO, "开始从缓存中获取模板数据----")
local html_template = html_template_cache:get(reqId)
-- 判断本地缓存是否存在
if html_template == nil then
    -- 获取模板url中的数据
        ngx.log(ngx.INFO, "缓存中不存在数据开始远程获取模板")
    local url = templateData["url"]
        ngx.log(ngx.INFO, "从缓存中获取的url地址:", url)
    if url == nil then
        ngx.say("URL路径未配置");
        return
    end
        -- 抓取远程url的html
        ngx.log(ngx.INFO, "开始抓取模板数据:", url)
    local returnResult = lgethtml.gethtml(url);
    -- 判断抓取模板是否正常
    if returnResult==nil then
        ngx.say("抓取URL失败...");
        return
    end
        -- 判断html状态
    if returnResult.status==200 then
        html_template = returnResult.body
                --设置模板缓存为一小时
                ngx.log(ngx.INFO, "将模板数据加入到本地缓存")
        html_template_cache:set(reqId,html_template,60 * 60)
    end
end
ngx.log(ngx.INFO, "缓存中获取模板数据结束----")

-- 模板渲染
--编译得到一个lua函数

local func = template.compile(html_template)
local context = {amount=amount}
ngx.log(ngx.INFO, "开始渲染模板数据")
--执行函数,得到渲染之后的内容
local content = func(context)

--通过ngx API输出
ngx.say(content)

2.2 编写nginx配置

2.2.1 添加本地缓存

在nginx主配置文件中添加模板缓存

x
lua_shared_dict html_template_cache 10m;

2.2.2 编写nginx配置文件

我们这里使用content_by_lua_file的方式执行脚本

x
vi template.conf
x
server {
        listen 8888;
        charset utf-8;
        # 配置路径重写
        location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
            rewrite ^/(.*) http://www.resources.com/$1 permanent;
        }
    
        #删除本地缓存
        location /delete {
             default_type text/html;
             content_by_lua '
              local lreqparm = require("requestUtils")
              --获取请求参数
              local reqParams = lreqparm.getRequestParam()
               -- 定义本地缓存
              local html_template_cache = ngx.shared.html_template_cache

                -- 获取请求ID的参数
              local reqId = reqParams["id"];

              ngx.log(ngx.INFO, "requestID:", reqId);
              -- 校验参数
              if reqId==nil then
                  ngx.say("缺少ID参数");
                  return
               end
               -- 获取本地缓存对象
               html_template_cache:delete(reqId);
               ngx.say("清除缓存成功");
            ';
        }

        location /template {
            default_type text/html;
            content_by_lua_file /usr/local/openresty/script/requestTemplateRendering.lua;
        }
}

2.3 初始化数据

x
# 进入一个redis集群的节点内部
docker exec -ti redis01 /bin/bash
# 以集群方式登录172.18.0.2:3306节点
redis-cli -h 172.18.0.2 -c
# 在redis中添加一个布隆过滤器 错误率是0.01 数量是1万个
BF.RESERVE bf_taxi 0.01 10000 NONSCALING
# 在bf_test 的布隆过滤器添加一个key
BF.ADD bf_taxi 1
#检查数据是否存在
BF.EXISTS bf_taxi 1
# 添加URL以及价格
hset hkey_1 url http://127.0.0.1/template.html amount 100.00

2.4 访问测试

访问http://192.168.64.181:8888/template?id=1进行测试

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

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

相关文章

基于RK3399/RK3588 H.265/HEVC的低延迟视频传输系统设计与实现

近年来&#xff0c;随着短视频直播的兴起&#xff0c;视频传输设备在生活中的应用越发普及。人们对图像 清晰度、帧率、码率等技术指标的要求不断提高&#xff0c;视频帧所包含的数据量也在急速增加。在 有限的网络带宽下&#xff0c;传统的视频采集设备面临压缩率不足、帧率…

Ui自动化测试如何上传文件

前言 实施UI自动化测试的时候&#xff0c;经常会遇见上传文件的操作&#xff0c;那么对于上传文件你知道几种方法呢&#xff1f;今天我们就总结一下几种常用的上传文件的方法&#xff0c;并分析一下每个方法的优点和缺点以及哪种方法效率&#xff0c;稳定性更高 被测HTML代码…

python基础知识(九):函数

目录 1. 函数的定义2. 传递实参2.1 位置实参2.2 关键字实参2.3 默认值2.4 传递任意数量的实参2.5 结合使用位置实参和任意数量实参 3. 导入模块3.1 导入特定的函数3.2 使用 as 给函数指定别名3.3 使用 as 给模块指定别名3.4 导入模块中的所有函数 1. 函数的定义 函数的定义形式…

Wijmo 5.20231.888 JavaScript UI Crack

Wijmo使用更快、更灵活的 JavaScript UI 组件构建更好的应用程序 使用 Wijmo&#xff0c;利用我们引人注目的 UI 组件库&#xff0c;将更多时间花在应用程序的核心功能上。要求零依赖&#xff0c;Wijmo sports弹性网格&#xff0c;业内最好的 JavaScript 数据网格&#xff0c;提…

基于深度学习的高精度动物检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度动物检测识别系统可用于日常生活中或野外来检测与定位动物目标&#xff08;狼、鹿、猪、兔和浣熊&#xff09;&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的动物&#xff08;狼、鹿、猪、兔和浣熊&#xff09;目标检测识…

前端基础面试题(HTML,CSS,JS)

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 html语义化的理解 代码结构: 使页面在没有css的情况下,也能够呈现出好的内容结构 有利于SE…

AI实战营:MMPreTrain代码实现

环境 环境安装 pip install openmim mim install mmengine mim install mmcv mim install mmpretrain # 安装多模态模型 pip install "mmpretrain[multimodal]" 验证环境 In [1]: import mmengineIn [2]: mmengine.__version__ Out[2]: 0.7.3In [3]: import …

开发者出海合规手册;@levelsio独立开发月入20万解析;MJ+AR设计珠宝;SD算法原理-通俗版 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 独立开发者必看&#xff0c;出海应用开发者合规手册 这是 JourneymanChina 多年出海经验教训的总结&#xff0c;适用于Google Play 以…

在Wamp环境中如何下载Composer并且使用Laravel配置Apache服务器

一.Composer的安装 方法1.到Composer官网Composer (getcomposer.org)下载 点击Composer-Setup.exe下载Composer安装包 点击Next 这里选择你的php.exe的地址 然后一直点next结束。 然后打开cmd命令输入composer -v看是否运行成功。 方法2.CMD命令安装composer php -r &quo…

学生考试作弊检测系统 yolov8

学生考试作弊检测系统采用yolov8网络模型人工智能技术&#xff0c;学生考试作弊检测系统过在考场中安装监控设备&#xff0c;对学生的作弊行为进行实时监测。当学生出现作弊行为时&#xff0c;学生考试作弊检测系统将自动识别并记录信息。YOLOv8 算法的核心特性和改动可以归结为…

SolVES 模型与多技术融合【多语言】实现生态系统服务功能社会价值评估及拓展案例分析

生态系统服务是人类从自然界中获得的直接或间接惠益&#xff0c;可分为供给服务、文化服务、调节服务和支持服务4类&#xff0c;对提升人类福祉具有重大意义&#xff0c;且被视为连接社会与生态系统的桥梁。自从启动千年生态系统评估项目&#xff08;Millennium Ecosystem Asse…

IDEA中Maven依赖包下载不了的一种“奇怪”解决方案【亲测有效】

&#x1f4a7; 记录一下今天遇到的 b u g \color{#FF1493}{记录一下今天遇到的bug} 记录一下今天遇到的bug&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 数据结构与算法…

Linux - fd文件描述符和文件详解

​​​​​​​ ​​​​​​​ ​​​​​​​ 感谢各位 点赞 收藏 评论 三连支持 本文章收录于专栏【Linux系统编程】 ❀希望能对大家有所帮助❀ 本文章由 风君子吖 原创 ​​​​​​​ ​​​​​​​ ​​​​​​​ …

WPF 如何实时查看页面元素如何使用实时可视化树

文章目录 往期回顾可视化页面元素如何使用调试工具 总结 往期回顾 WPF 学习&#xff1a;如何使用实时可视化树&#xff0c;照着MaterialDesign的Demo学习 可视化页面元素 我们知道&#xff0c;网页的页面元素是可以通过按F12查看代码。查看到页面元素的。 WPF也有类似的工具…

基于相位共轭法的散射聚焦成像研究-Matlab代码

▒▒本文目录▒▒ 一、引言二、相位共轭法散射聚焦成像Matlab仿真三、参考文献四、Matlab程序开发与实验指导 一、引言 一直以来&#xff0c;研究人员致力于分析造成散射的原因、随机介质性质以及各种散射光的特征&#xff0c;并且研究透过散射介质成像。1990年&#xff0c;I.…

模型剪枝:给模型剪个头发

本文来自公众号“AI大道理”。 深度学习网络模型从卷积层到全连接层存在着大量冗余的参数&#xff0c;大量神经元激活值趋近于0&#xff0c;将这些神经元去除后可以表现出同样的模型表达能力&#xff0c;这种情况被称为过参数化&#xff0c;而对应的技术则被称为模型剪枝。 网…

在价格战中苦苦挣扎的小鹏汽车和蔚来,哪个是最好的电动汽车股?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; 从长期来看&#xff0c;小鹏汽车(XPEV)的基本面优于蔚来(NIO)&#xff0c;小鹏汽车目前的估值也更有吸引力&#xff0c;在全球电动汽车行业中也具有更好的长期投机性。 猛兽财经的投资组合中其中有一部分…

断更两个月的感悟

清明时节雨纷纷&#xff0c; 路上行人欲断魂&#xff0c; 借问酒家何处有&#xff0c; 牧童遥指杏花村。 1.断更 武汉的三月和四月是个多雨的季节&#xff0c;这样的天气经常让我患得患失&#xff0c;由于一些原因&#xff08;后文再详细说明&#xff09;&#xff0c;不知不觉…

【Linux】分析Fuse中libfuse源码

在Linux中&#xff0c;我们可以使用FUSE来进行自定义用户态文件系统的实现。编译example中的示例是学习FUSE的第一步&#xff0c;本文侧重于剖析FUSE的client端的源码。 文章目录 &#xff08;一&#xff09; 下载libfuse源码&#xff0c;避免重复造轮子&#xff08;二&#xf…

什么是WePY?

WePY&#xff08;微信小程序开发框架&#xff09;是一个基于组件化开发思想的微信小程序开发框架。它类似于Vue.js框架&#xff0c;通过封装小程序原生的API&#xff0c;提供了更加简洁、高效的开发方式。 WePY的主要特点包括&#xff1a; 组件化开发&#xff1a;WePY将页面拆…