【多级缓存】多级缓存OpenResty,Canal,nginx本地缓存

发布于:2024-05-02 ⋅ 阅读:(30) ⋅ 点赞:(0)

安装OpenResty

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

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

官方地址:https://openresty.org/cn/

  • 在linux下安装
  1. 安装OpenResty的依赖开发库
    yum install -y pcre-devel openssl-devel gcc --skip-broken
  2. 在centos中添加openresty仓库
    yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
  3. 安装openResty
    yum install -y yum-utils
  4. 安装opm工具,是一个openresty的管理工具,可以帮助我们安装一个第三方的lua模块
    yum instally openrest -y -opm

默认情况下 openResty的安装目录是/usr/local/openresty
在这里插入图片描述
配置nginx环境变量
5. 打开配置文件vim /etc/profile
6. 在最下面添加
export NGINX_HOME=/usr/local/openresty/nginx
export PATH=${NGINX_HOME}/sbin:$PATH
7. 让配置生效
source /etc/profile
8. 启动nginx

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

在这里插入图片描述

OpenResty入门

这里由代理一个访问路径为例子:
在windows端的nginx中进行

  1. 在nginx.conf的http下面,添加对OpenResty的Lua模块的加载:
    在这里插入图片描述

  2. 在nginx.conf的server下面,添加对/api/item这个路径的监听:
    在这里插入图片描述

  3. Linux中niginx目录下创建lua文件夹,新建item.lua文件
    创建内容:
    在这里插入图片描述

  4. 重新加载配置
    nginx -s reload

OpenResty获取请求参数

OpenResty提供了各种API用来获取不同类型的参数:
在这里插入图片描述

OpenResty向tomcat服务器发送请求

nginx提供了内部API请求用以发送http请求:
在这里插入图片描述
返回的响应内容包括:
resp.status:响应状态码
resp.header:响应头,是一个table
resp.body:响应体,就是响应数据

注意:这里的path是路径,并不包含IP和端口,这个请求会被nginx内部的server监听并处理,可以使用反向代理
在这里插入图片描述

我们可以把http查询的请求封装到一个函数中,放到OpenResty函数库中,方便以后使用

  1. 创建文件/usr/local/openresty/lualib/common.lua
  2. 在文件中封装请求http查询的函数
    在这里插入图片描述
    如何使用这个封装函数,返回向tomcat请求的数据,在item.lua文件中
    在这里插入图片描述

注意:Openresty提供了一个cjson的模块用来处理JSON的序列化和反序列化
地址:https://github.com/openresty/lua-cjson/
如何使用:

  1. 引入json模块
    local cjson=require "cjson"
  2. 序列化:
    在这里插入图片描述
    反序列化:
    在这里插入图片描述

在nginx与tomcat端之间添加redis缓存

  • 冷启动和缓存预热

冷启动:服务刚刚启动时,Redis中并没有缓存,如果所有商品数据都在第一次查询时添加缓存,可能会给数据库带来较大压力。
缓存预热:在实际开发中,我们可以利用大数据统计用户访问的热点数据,在项目启动时将这些热点数据提前查询并保存到Redis中。

OpenResty提供了操作Redis的模块,只需要引入就能够使用
在这里插入图片描述
封装函数,用来释放Redis连接,放入连接池
在这里插入图片描述
封装函数,从Redis中读取数据并返回
在这里插入图片描述

Redis本地缓存

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

  1. 开启共享词典,在nginx.conf的http下添加配置:

在这里插入图片描述
2. 操作共享词典
在这里插入图片描述

缓存同步

缓存同步策略

设置有效期:给缓存设置有效期,到期后自动删除。再次查询时更新
优势:简单、方便
缺点:时效性差,缓存过期之前可能不一致
场景:更新频率较低,时效性要求低的业务
同步双写:在修改数据库的同时,直接修改缓存
优势:时效性强,缓存与数据库强一致
缺点:有代码侵入,耦合度高;
场景:对一致性、时效性要求较高的缓存数据
异步通知:修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据
优势:低耦合,可以同时通知多个缓存服务
缺点:时效性一般,可能存在中间不一致状态
场景:时效性要求一般,有多个服务需要同步

基于Canal的异步通知

在这里插入图片描述

安装Canal

Canal是阿里巴巴旗下的开源项目,基于java开发,基于数据库增量日志解析,提供增量数据订阅&消费
地址:https://github.com/alibaba/canal

Canal是基于MySQL的主从同步来实现的,MySQL主从同步的原理如下:
在这里插入图片描述
MySOL master将数据变更写入二进制日志( binarylog)其中记录的数据叫binary log events
MySQLslave 将master的 binary log events拷贝到它的中继日志(relay log)
MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

Canal就是把自己伪装成MVSOL的一个slave节点,从而监听master的binarylog变化。再把得到的变化信息通知给Canal的客户端,进而完成对其它数据库的同步。

安装:

  1. 首先创建一个网络,将MySQL,Canal,MQ放在同一个Docker网络中:
    docker network create hhh
    让mysql加入这个网络
    docker network connect hhh mysql

  2. 将Canal镜像上传到虚拟机中,通过命令导入;
    docker load -i canal.tar

  3. 运行创建Canal容器
    docker run p 11111:11111 --name canal
    -e canal.destinations=hhh
    -e canal.instance.master.address=mysql:3306
    -e canal.instance.dbUsername=canal
    -e canal.instance.dbPassword=canal
    -e canal.instance.connectionCharset=UTF-8
    -e canal.instance.tsdb.enable=true
    -e canal.instance.gtidon=false
    -e canal.instance.filter.regex=hhh\…*
    –network hhh
    -d canal/canal-server:v1.1.5

Canal客户端

Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。
第三方开源的canal-starter:地址:https://github.com/NormanGyllenhaal/canal-client

  1. 引入依赖

在这里插入图片描述
2. 编写配置

canal:
    destination: hhh #要跟canal运行时设置的destination一致
    server: 192.168.75.135:11111 #canal地址
  1. 编写监听器,监听canal消息
//Item是指定表的实体类
@CanalTable("表名")
@Component
public class ItemHandler implements EntryHandler<Item>{
   @Override
   public void insert(Item item){
   //新增数据到redis中
   //新增数据到JVM缓存
   }
   @Override
   public void update(Item before,Item after){
   //更新redis数据
   //更新本地缓存
   //更新数据到JVM缓存
   }
   @Override
   public void delete(Item item){
   //删除redis数据
   //清除本地缓存
   //从JVM中删除缓存
   }
}

网站公告

今日签到

点亮在社区的每一天
去签到