美文网首页
OpenResty+Lua+Redis 高性能后端接口

OpenResty+Lua+Redis 高性能后端接口

作者: 右耳菌 | 来源:发表于2022-08-17 00:02 被阅读0次

1. OpenResty简介

点击查看官网

OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web 服务和动态网关。

OpenResty通过汇聚各种设计精良的Nginx模块(主要由OpenResty团队自主开发),从而将Nginx有效地变成一个强大的通用Web应用平台。这样,Web开发人员和系统工程师可以使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。

OpenResty的目标是让你的Web服务直接跑在Nginx服务内部,充分利用Nginx的非阻塞I/O模型,不仅仅对HTTP客户端请求,甚至于对远程后端诸如MySQL、PostgreSQL、Memcached以及Redis等都进行一致的高性能响应。


某些大型网站广告的访问流程

流程:

  1. 查询Ngin缓存,如果有缓存则直接将缓存中的广告数据返回
  2. 如果Nginx缓存中没有广告数据,则通过Lua脚本查询Redis,如果Redis中有数据,则将数据存入到Nginx的缓存并返回查询到广告数据。
  3. 如果Redis中没有缓存数据,则此时会通过Lua脚本查询MySQL,如果MySQL有数据,则将数据存入到Redis中并返回查询到数据。

2. 例子

请先确保到官网查看并下载安装OpenResty后再继续操作。

1. 表结构
  • 广告分类表
CREATE TABLE `tb_content_category` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  • 广告表
CREATE TABLE `tb_content` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `category_id` bigint NOT NULL,
  `title` varchar(200) DEFAULT NULL,
  `url` varchar(500) DEFAULT NULL,
  `pic` varchar(300) DEFAULT NULL,
  `status` varchar(1) DEFAULT NULL,
  `sort_order` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

请自行填充数据哦~~~

2. 代码实现
缓存预热

缓存预热就是将数据提前加入到缓存中,当数据发生变更,再将最新的数据更新到缓存。

实现思路

  • 定义请求:用于查询MySQL数据库中的数据更新到redis中。
  • 连接Mysql 按照广告分类ID读取广告列表,转换为json字符串。
  • 连接Redis将广告列表json字符串存入redis 。
  • 实现步骤
  • 定义请求:请求地址:/content_update 请求参数:id -- 广告分类id 返回值:json
    在/root/lua目录下创建content_update.lua 实现连接Mysql 查询数据 并存储到Redis中。
  • content_update.lua
ngx.header.content_type="application/json;charset=utf-8";
local id= ngx.req.get_uri_args()["id"];--提取参数
local cjson= require("cjson"); --加载cjson模块
local mysql= require("resty.mysql");--加载mysql模块
local redis= require("resty.redis");--加载redis模块
 
--读取mysql中的数据
local db= mysql:new();
local props = {
         host = "192.168.1.101",
         port = 3306,
         database ="mybatis",
         user ="root",
         password ="root"
 }
db:connect(props);
local select_sql="select pic,url from tb_content where status = '1' and category_id="..id.." order by sort_order ";
local res=db:query(select_sql);
db:close();
 
--写入redis
local red= redis:new();
red:set_timeout=(2000);
local ok, err = red:connect("192.168.1.100",6379);
if not ok then
    ngx.say("failed to connect:", err)
    return
end
--redis认证
local _res, err = res:auth("redis123456");
if not _res then
    ngx.say("failed to authenticate:", err)
    return
end

red:set("content_"..id,cjson.encode(res));
red:close();

ngx.say("{falg:true,code:20000}");
  • 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
location /content_update {
    content_by_lua_file /root/lua/content_update.lua;
}
广告缓存读取

** 实现思路**

  • 定义请求:用户根据广告分类的ID 获取广告的列表
  • 从Nginx缓存获取,获取到直接返回广告数据,否则执行下一步
    从Redis中获取广告数据,获取到则将广告数据存入Nginx缓存中
  • 实现步骤
  • 定义请求:请求地址:/content_read 请求参数:id -- 广告分类id 返回值:json
  • 在/root/lua目录下创建content_read.lua 实现查询nginx缓存数据
    content_read.lua
ngx.header.content_type="application/json;charset=utf-8";
--提取参数:广告分类id
local id= ngx.req.get_uri_args()["id"];
--加载本地缓存模块
local cache_ngx= ngx.shared.dis_cache; 
--从本地缓存获取广告数据
local content_cache = cache_ngx:get("content_"..id); 
--如果本地缓存没有数据
if content_cache =="" or content_cache == nil then 
    --引入redis模块
    local redis= require("resty.redis"); 
    --实例化redis对象
    local red = redis:new(); 
    --超时
    red:set_timeout=(2000); 
    --建立连接
    local ok, err = red:connect("192.168.1.100",6379);
    if not ok then
        ngx.say("failed to connect:", err)
        return
    end
    --redis认证
    local _res, err = res:auth("redis123456");
    if not _res then
        ngx.say("failed to authenticate:", err)
        return
    end
    --从redis取值
    local data= red:get("content_"..id);
    --关闭连接
    red:close();
    ngx.say(data);
    --存入本地缓存
    cache_ngx:set("content_"..id , data); 
else
    ngx.say(content_cache);
end
  • 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
# 定义lua缓存命名空间(在http几点下)
lua_shared_dict dis_cache 128m;

location /content_read {
    content_by_lua_file /root/lua/content_read.lua;
}

如果觉得有收获,欢迎点赞和评论,更多知识,请点击关注查看我的主页信息哦~

相关文章

网友评论

      本文标题:OpenResty+Lua+Redis 高性能后端接口

      本文链接:https://www.haomeiwen.com/subject/ieidgrtx.html