【多级缓存】

news2024/12/28 21:01:53

文章目录

  • 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.coloradmin.cn/o/1060069.html

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

相关文章

App分发苹果ios内测ipa应用文件签名分发平台剖析其运行模式及法律注意事项

随着移动应用的快速发展,为了确保应用的质量和稳定性,开发者们通常在发布应用之前会进行内部测试。而App内测签名分发平台作为一种解决方案,不仅能够提供快速的应用分发和安装,还能确保应用的完整性和可靠性。本文将详细分析App内…

【算法|动态规划No.11】leetcode53. 最大子数组和

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望…

input允许多行输入

input允许多行输入 input允许多行输入 ______________________________ 表示停止输入想象一下,我们现在身处一间充满活力的课堂。学生们坐在自己的座位上,准备聆听老师的讲解。老师站在讲台上,充满激情地开始教授代码。 老师:同…

星球作业(第十期)Android中的ClassLoader

Android中的ClassLoader 1.Android中有哪几种ClassLoader?它们的作用和区别是什么? 2.简述ClassLoader的双亲委托模型 Android中有哪几种ClassLoader?它们的作用和区别是什么? Android中有三个ClassLoader,分别是Bas…

【智慧导诊系统源码】智慧导诊系统的技术支撑与实际运作

什么是智慧导诊系统? 简单地说,智慧导诊系统是一种利用人工智能技术,为医生提供帮助的系统。它可以通过分析患者的症状和病史为医生提供疾病诊断和治疗方案的建议。 智慧导诊系统需要具备以下技术支撑才能实现 人工智能技术支撑。智慧导诊系统的核心在…

设计模式9、组合模式 Composite

解释说明:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属…

两种新建CAA项目快捷启动方式

文章目录 一、前言二、新建项目快捷启动方式(相当于直接Cnext进入)方式一:按下面图示操作(以V5 R21为例)方式二:按下面图示操作(以V5 R18为例) 一、前言 环境变量配置文件可存放路径…

字典与数组第七讲:工作表数据计算时为什么要采用数组公式(一)

《VBA数组与字典方案》教程(10144533)是我推出的第三套教程,目前已经是第二版修订了。这套教程定位于中级,字典是VBA的精华,我要求学员必学。7.1.3.9教程和手册掌握后,可以解决大多数工作中遇到的实际问题。…

个人论坛系统的测试用例

首先要弄清楚论坛系统都具有什么功能,然后对各个功能进行分类编写测试用例。

使用Sen2cor对Sentinel-2辐射定标和大气校正

使用Sen2cor对Sentinel-2辐射定标和大气校正 在上一篇文章中,先对Sen2cor进行了安装 先定位到插件所在文件夹下 cd C:\Users\lenovo\AppData\Local\Sen2Cor-02.11.00-win64如果在上一篇中已经配置好环境变量,那就不用cd定位了,直接输后面的…

经典算法-----八皇后问题

目录 前言 八皇后问题 1.问题简介 1.2思路剖析 1.3递归和回溯 代码实现 ​编辑 1.递归回溯解决 能否放置数组 完整代码: 2.非递归回溯解决 前言 今天我们学习一个新的算法,也就是回溯算法,就以八皇后问题作为示例,这是…

剑指offer——JZ25 合并两个排序的链表 解题思路与具体代码【C++】

一、题目描述与要求 两个链表的第一个公共结点_牛客题霸_牛客网 (nowcoder.com) 题目描述 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其…

C++的对像生存期

栈 栈由操作系统分配管理,也就是它是规整的,内存的大小在申请之后不会发生变化。因此,它不会出现碎片化,并且读取速度非常的快 例如:经常声明的局部变量,一些基本数据类型,如int ,double, char…

力扣 -- 518. 零钱兑换 II(完全背包问题)

解题步骤&#xff1a; 参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:int change(int amount, vector<int>& coins) {int ncoins.size();//多开一行&#xff0c;多开一列vector<vector<int>> dp(n1,vector<int>(amount1…

LLVM IR 文档 专门解释 LLVM IR

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

Linux网络编程:详解https协议

目录 一. https协议概述 二. 中间人截获 三. 常见的加密方法 3.1 对称加密 3.2 非对称加密 四. 数据摘要和数据签名的概念 五. https不同加密方式的安全性的探究 5.1 使用对称加密 5.2 使用非对称加密 5.3 非对称加密和对称加密配合使用 六. CA认证 七. 总结 一.…

JWFD开源工作流大模型设计器

JWFD开源工作流大模型设计器&#xff0c;把流程图的拓扑结构从几十个节点扩展到数千个节点&#xff0c;就不是使用绘图器的模式了&#xff0c;需要开发一个模型生成器了&#xff0c;尝试做一下大模型&#xff0c;赶赶时髦啊

openwrt安装与旁路由 以玩客云为例

鉴于安了wfnb/onecloud 23年的bata版本 结果发现进入docker 连make config apt yum apk curl等命令都没有……而且curl下载很慢 得选6.0哪个版本 反正就是 安不了istore 所以 直接刷人家的成品算了 为什么要使用软路由、旁路由 普通的路由器往往集无线信号转发、网关、DNS 服…

JMeter工具的介绍,安装

一、本文学习目标 1、能知道JMeter的优缺点 2、能掌握JMeter的安装流程 3、能掌握JMeter线程组的设置 4、能掌握JMeter参数化的使用 5、能掌握JMeter直连数据库操作 6、能掌握JMeter的断言. 二、JMeter简介 &#xff08;1&#xff09;Jmeter详细介绍 **JMeter&#xff08;A…

RTC 时间、闹钟

实时时钟RTC是一个独立的定时器。RTC模块拥有一个连续计数的计数器&#xff0c;在软件配置下&#xff0c;可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。 在掉电情况下 RTC仍可以独立运行 只要芯片的备用电源…