【多级缓存】

文章目录

  • 1. JVM进程缓存
  • 2. Lua语法
  • 3. 实现多级缓存
    • 3.1 反向代理流程
    • 3.2 OpenResty快速入门
  • 4. 查询Tomcat
    • 4.1 发送http请求的API
    • 4.2 封装http工具
    • 4.3 基于ID负载均衡
    • 4.4 流程小结
  • 5. Redis缓存预热

传统的缓存策略一般是请求到达Tomcat后,先查询Redis,如果未命中则查询数据库,如图:在这里插入图片描述
存在下面的问题:

  • 请求要经过Tomcat处理,Tomcat的性能成为整个系统的瓶颈

  • Redis缓存失效时,会对数据库产生冲击

多级缓存就是充分利用请求处理的每个环节,分别添加缓存,减轻Tomcat压力,提升服务性能
在多级缓存架构中,Nginx内部需要编写本地缓存查询Redis查询Tomcat查询的业务逻辑,因此这样的nginx服务不再是一个反向代理服务器,而是一个编写业务的Web服务器了

在这里插入图片描述

可见,多级缓存的关键有两个:

  • 一个是在nginx中编写业务,实现nginx本地缓存、Redis、Tomcat的查询
  • 另一个就是在Tomcat中实现JVM进程缓存
  • Nginx编程则会用到OpenResty框架结合Lua这样的语言。

1. JVM进程缓存

案例:
需求:利用Caffeine实现下列需求:

  • 给根据id查询商品的业务添加缓存,缓存未命中时查询数据库
  • 给根据id查询商品库存的业务添加缓存,缓存未命中时查询数据库
  • 缓存初始大小为100
  • 缓存上限为10000

首先,我们需要定义两个Caffeine的缓存对象,分别保存商品、库存的缓存数据。
在item-service的com.heima.item.config包下定义CaffeineConfig类:
在这里插入图片描述
然后,修改item-service中的com.heima.item.web包下的ItemController类,添加缓存逻辑:
在这里插入图片描述

2. Lua语法

Nginx编程需要用到Lua语言,因此学习Lua的基本语法。
Lua中支持的常见数据类型包括:
在这里插入图片描述
需求:自定义一个函数,可以打印table,当参数为nil时,打印错误信息
在这里插入图片描述

3. 实现多级缓存

多级缓存的实现离不开Nginx编程,而Nginx编程又离不开OpenResty。
在这里插入图片描述

  • windows上的nginx用来做反向代理服务,将前端的查询商品的ajax请求代理到OpenResty集群
  • OpenResty集群用来编写多级缓存业务

3.1 反向代理流程

现在,商品详情页使用的是假的商品数据。不过在浏览器中,可以看到页面有发起ajax请求查询真实商品数据。在这里插入图片描述
请求地址是localhost,端口是80,就被windows上安装的Nginx服务给接收到了。然后代理给了OpenResty集群:
在这里插入图片描述

3.2 OpenResty快速入门

在这里插入图片描述
可以看到商品id是以路径占位符方式传递的,因此可以利用正则表达式匹配的方式来获取ID

OpenResty的很多功能都依赖于其目录下的Lua库,需要在nginx.conf中指定依赖库的目录,并导入依赖:
1)添加对OpenResty的Lua模块的加载在这里插入图片描述
2)获取商品id在这里插入图片描述

3)编写item.lua在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4. 查询Tomcat

4.1 发送http请求的API

nginx提供了内部API用以发送http请求:在这里插入图片描述
返回的响应内容包括:

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

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

4.2 封装http工具

1)添加反向代理,到windows的Java服务

因为item-service中的接口都是/item开头,所以我们监听/item路径,代理到windows上的tomcat服务。在这里插入图片描述
以后,只要我们调用ngx.location.capture("/item"),就一定能发送请求到windows的tomcat服务。

2)封装工具类
在这里插入图片描述
所以,自定义的http工具也需要放到这个目录下。
/usr/local/openresty/lualib目录下,新建一个common.lua文件:内容如下:
在这里插入图片描述
这个工具将read_http函数封装到_M这个table类型的变量中,并且返回,这类似于导出。

使用的时候,可以利用require('common')来导入该函数库,这里的common是函数库的文件名。
3)实现商品查询
最后,我们修改/usr/local/openresty/lua/item.lua文件,利用刚刚封装的函数库实现对tomcat的查询:在这里插入图片描述
这里查询到的结果是json字符串,并且包含商品、库存两个json字符串,页面最终需要的是把两个json拼接为一个json:
在这里插入图片描述
这就需要我们先把JSON变为lua的table,完成数据整合后,再转为JSON。
OpenResty提供了一个cjson的模块用来处理JSON的序列化和反序列化。
下面,我们修改之前的item.lua中的业务,添加json处理功能:在这里插入图片描述

4.3 基于ID负载均衡

刚才的代码中,我们的tomcat是单机部署。而实际开发中,tomcat一定是集群模式:
因此,OpenResty需要对tomcat集群做负载均衡。

而默认的负载均衡规则是轮询模式,当我们查询/item/10001时:

  • 第一次会访问8081端口的tomcat服务,在该服务内部就形成了JVM进程缓存
  • 第二次会访问8082端口的tomcat服务,该服务内部没有JVM缓存(因为JVM缓存无法共享),会查询数据库

如果能让同一个商品,每次查询时都访问同一个tomcat服务,那么JVM缓存就一定能生效了。

也就是说,我们需要根据商品id做负载均衡,而不是轮询。

nginx根据请求路径做hash运算,把得到的数值对tomcat服务的数量取余,余数是几,就访问第几个服务,实现负载均衡。

实现
修改/usr/local/openresty/nginx/conf/nginx.conf文件,实现基于ID做负载均衡。
首先,定义tomcat集群,并设置基于路径做负载均衡:在这里插入图片描述

4.4 流程小结

在这里插入图片描述
首先进来的localhost:80会由Nginx拦截代理到openresty,openresty会将路径为/api/item/(***)这样的路径解析出访问的商品id,之后通过将/item这样的路径代理发送到windows电脑中的Tomcat服务器查询,当tomcat中线程缓存有则返回,没有则去数据库查询。

5. Redis缓存预热

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLVM IR 文档 专门解释 LLVM IR

https://llvm.org/docs/LangRef.html#phi-instruction

计算机竞赛 车道线检测(自动驾驶 机器视觉)

0 前言 无人驾驶技术是机器学习为主的一门前沿领域,在无人驾驶领域中机器学习的各种算法随处可见,今天学长给大家介绍无人驾驶技术中的车道线检测。 1 车道线检测 在无人驾驶领域每一个任务都是相当复杂,看上去无从下手。那么面对这样极其…

量化交易全流程(六)

本节目录 多因子风险模型 自从股票市场产生以来,大量的学者、业界人员都在研究股票的价格波动究竟是由什么决定的。一个明显的事实是,股票的价格波动一定是由多种因素决定的,比如大盘因素、市值因素和行业因素。对于大盘因素,股…

最新AI创作系统/AI绘画系统/ChatGPT系统+H5源码+微信公众号版+支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图…

一个基于人工智能的视频分析和管理工具——Chat Video

Chat Video是一个基于人工智能的视频分析和管理工具,致力于帮助用户高效学习和管理视频。在这个视频泛滥的时代,Chat Video 凭借其独特的AI技术,为用户节省大量时间,真正释放视频的价值。 Chat Video 通过语音识别技术&#xff0…

Socket通信

优质博文IT-BLOG-CN 一、简介 Socket套接字:描述了计算机的IP地址和端口,运行在计算机中的程序之间采用socket进行数据通信。通信的两端都有socket,它是一个通道,数据在两个socket之间进行传输。socket把复杂的TCP/IP协议族隐藏在…

2023年-华为机试题库B卷(Python)【满分】

华为机试题库B卷 已于5月10号 更新为2023 B卷 (2023-10-04 更新本文) 华为机试有三道题目,前两道属于简单或中等题,分值为100分,第三道为中等或困难题,分值为200分。总分为 400 分,150分钟考试…

systrace/perfetto抓取方式分享

背景 近来有一些同学反馈性能分析,现在大部分都是其实已经开始使用perfetto了,连sdk上都已经找不到哦systrace相关工具,让马哥可以分享一些这个相关内容,其实以前企业里面那时候大部分都是使用老版本systrace的,相比新…

【10】c++设计模式——>依赖倒转原则

关于依赖倒转原则,对应的是两条非常抽象的描述: 1.高层模块不应该依赖低层模块,两个都应该依赖抽象。 2.抽象不应该依赖细节,细节应该依赖抽象。 先用人话解释一下这两句话中的一些抽象概念: 1.高层模块:可…

QT实现TCP服务器客户端

服务器 .cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);// 此时,服务器已经成功进入监听状…

flutter开发实战-应用更新apk下载、安装apk、启动应用实现

flutter开发实战-应用更新apk下载、安装apk、启动应用实现 在开发过程中,经常遇到需要更新下载新版本的apk文件,之后进行应用更新apk下载、安装apk、启动应用。我们在flutter工程中实现下载apk,判断当前版本与需要更新安装的版本进行比对判断…

竞赛选题 机器视觉目标检测 - opencv 深度学习

文章目录 0 前言2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 0 前言 &#x1f5…