Redis页面优化

文章目录

    • 1.Redis页面缓存
        • 1.思路分析
        • 2.首先记录一下目前访问商品列表页的QPS
          • 1.线程组配置10000次请求
          • 2.请求配置
          • 3.开始压测
            • 1.压测第一次 平均QPS为612
            • 2.压测第二次 平均QPS为615
            • 3.压测第三次 平均QPS为617
        • 3.然后记录一下访问商品详情页的QPS
          • 1.线程组配置10000次请求
          • 2.请求配置
          • 3.开始压测
            • 1.压测第一次 平均QPS为633
            • 2.压测第二次 平均QPS为642
            • 3.压测第三次 平均QPS为641
        • 4.商品列表页Redis缓存优化
          • 1.GoodsController.java
          • 2.启动报错 Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource
          • 3.发现是produces写错了,将冒号换成分号
          • 4.重新启动测试
            • 1.登录后访问 http://localhost:9092/seckill/goods/toList
            • 2.此时如果在数据库中修改信息,在60s内是不会刷新的
        • 5.商品详情页Redis缓存优化
          • 1.GoodsController.java
          • 2.测试
            • 1.登录后访问详情页
            • 2.在Redis中也有了缓存
        • 6.压力测试
          • 1.清空Redis
          • 2.清空用户表
          • 3.启动应用,重新生成2000个用户
          • 4.对访问列表页进行压测
            • 1.发现平均QPS只有80,比直接走数据库还慢
            • 2.由于六台机器都开启了RDB和AOF的持久化策略,现在分别将其关闭,然后重启redis
            • 3.再次压测,还是80
            • 4.那么就可能是网络原因了,因为服务器都在北京,所以将服务部署到生产环境然后再进行压力测试
    • 2.生产环境的压力测试
        • 1.首先将GoodsController.java的从db查询商品列表打开
        • 2.部署上线
          • 1.激活环境为prod
          • 2.maven打包
          • 3.上传到服务器然后重新启动
        • 3.UserUtil.java 获取用户信息
          • 1.修改环境变量
          • 2.获取cookie
        • 4.准备压测
          • 1.http请求默认值
          • 2.http请求信息
          • 3.修改cookie的域
          • 4.开始压测5000次请求,QPS为55
        • 5.使用redis缓存页面来优化并重新部署
        • 6.再次压测,QPS为80,有所提升
        • 7.关于Redis缓存页面与DB的数据同步问题
    • 3.对象缓存问题解决
        • 1.问题分析
        • 2.具体实现
          • 1.UserService.java
          • 2.UserServiceImpl.java
          • 3.UserController.java
        • 3.测试
          • 1.登录一下,得到票据
          • 2.Redis中有该用户信息
          • 3.更新密码 http://localhost:9092/seckill/user/updatePassword?userTicket=4dfaea799a9b438ea96ef61f7da435e3&password=666666
          • 4.刷新Redis,用户信息被删除

1.Redis页面缓存

1.思路分析

image-20240510103830900

2.首先记录一下目前访问商品列表页的QPS
1.线程组配置10000次请求

image-20240510104150231

2.请求配置

image-20240510104243589

3.开始压测
1.压测第一次 平均QPS为612

image-20240510104745555

2.压测第二次 平均QPS为615

image-20240510104836407

3.压测第三次 平均QPS为617

image-20240510104913070

3.然后记录一下访问商品详情页的QPS
1.线程组配置10000次请求

image-20240510104150231

2.请求配置

image-20240510114304155

3.开始压测
1.压测第一次 平均QPS为633

image-20240510114342610

2.压测第二次 平均QPS为642

image-20240510114510495

3.压测第三次 平均QPS为641

image-20240510114551866

4.商品列表页Redis缓存优化
1.GoodsController.java
    @ResourceGoodsService goodsService;@Resourceprivate RedisTemplate redisTemplate;@Resourceprivate ThymeleafViewResolver thymeleafViewResolver;// 进入到商品首页-使用redis优化@RequestMapping(value = "/toList", produces = "text/html;charset=UTF-8")@ResponseBodypublic String toList(Model model, User user, HttpServletRequest request, HttpServletResponse response) {// 判断是否有用户信息if (null == user) {return "login";}// 先从redis中获取页面,如果有则直接返回String html = (String) redisTemplate.opsForValue().get("goodsList");if (StringUtils.hasText(html)) {return html;}// 如果没有就从数据库中查询,然后存入redis中// ------------------------------db查询商品列表------------------------------// 查询商品列表model.addAttribute("goodsList", goodsService.findGoodsVo());// 将用户信息存入model中model.addAttribute("user", user);// ------------------------------db查询商品列表------------------------------// 渲染页面// 1.首先构建一个webContext对象,用来存放modelWebContext context = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap());// 2.渲染页面html = thymeleafViewResolver.getTemplateEngine().process("goodsList", context);// 3.判断html是否为空,不为空则存入redis中,设置过期时间为60sif (StringUtils.hasText(html)) {redisTemplate.opsForValue().set("goodsList", html, 180, TimeUnit.SECONDS);}return html;}
2.启动报错 Error creating bean with name ‘requestMappingHandlerMapping’ defined in class path resource

image-20240510112622807

3.发现是produces写错了,将冒号换成分号

image-20240510112644275

4.重新启动测试
1.登录后访问 http://localhost:9092/seckill/goods/toList

image-20240510113319062

2.此时如果在数据库中修改信息,在60s内是不会刷新的

image-20240510113453521

image-20240510113501947

5.商品详情页Redis缓存优化
1.GoodsController.java
    // 进入到商品详情页@RequestMapping(value = "/toDetail/{goodsId}", produces = "text/html;charset=UTF-8")@ResponseBodypublic String toDetail(Model model, User user, @PathVariable Long goodsId, HttpServletRequest request, HttpServletResponse response) {// 判断是否有用户信息if (null == user) {return "login";}// 先从redis中获取页面,如果有则直接返回String html = (String) redisTemplate.opsForValue().get("goodsDetail:" + goodsId);// 如果有则直接返回if (StringUtils.hasText(html)) {return html;}// 如果没有就从数据库中查询,然后存入redis中// ------------------------------db查询商品详情------------------------------// 查询商品详情GoodsVo goodsVoByGoodsId = goodsService.findGoodsVoByGoodsId(goodsId);model.addAttribute("goods", goodsVoByGoodsId);// secKillStatus:秒杀状态 0:未开始 1:进行中 2:已结束// remainSeconds:秒杀剩余时间 >0:未开始 0:进行中 -1:已结束// 获取该商品的秒杀开始时间和结束时间long startAt = goodsVoByGoodsId.getStartDate().getTime();long endAt = goodsVoByGoodsId.getEndDate().getTime();long now = System.currentTimeMillis();// 根据当前时间与秒杀开始时间和结束时间的比较,判断秒杀状态int secKillStatus = 0;int remainSeconds = 0;if (now < startAt) {// 秒杀未开始secKillStatus = 0;remainSeconds = (int) ((startAt - now) / 1000);} else if (now > endAt) {// 秒杀已结束secKillStatus = 2;remainSeconds = -1;} else {// 秒杀进行中secKillStatus = 1;remainSeconds = 0;}// 将秒杀状态和剩余时间存入model中,返回到前端model.addAttribute("secKillStatus", secKillStatus);model.addAttribute("remainSeconds", remainSeconds);// 将用户信息存入model中,返回到前端model.addAttribute("user", user);// ------------------------------db查询商品详情------------------------------// 渲染页面// 1.首先构建一个webContext对象,用来存放modelWebContext context = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap());// 2.渲染页面html = thymeleafViewResolver.getTemplateEngine().process("goodsDetail", context);// 3.判断html是否为空,不为空则存入redis中,设置过期时间为60sif (StringUtils.hasText(html)) {redisTemplate.opsForValue().set("goodsDetail:" + goodsId, html, 180, TimeUnit.SECONDS);}return html;}
2.测试
1.登录后访问详情页

image-20240510115537167

2.在Redis中也有了缓存

image-20240510115506347

6.压力测试
1.清空Redis

image-20240510131337298

2.清空用户表

image-20240510131408927

3.启动应用,重新生成2000个用户

image-20240510131906293

4.对访问列表页进行压测
1.发现平均QPS只有80,比直接走数据库还慢

image-20240510133226209

2.由于六台机器都开启了RDB和AOF的持久化策略,现在分别将其关闭,然后重启redis

image-20240510134438566

3.再次压测,还是80

image-20240510135137575

4.那么就可能是网络原因了,因为服务器都在北京,所以将服务部署到生产环境然后再进行压力测试

2.生产环境的压力测试

1.首先将GoodsController.java的从db查询商品列表打开

image-20240510140806413

2.部署上线
1.激活环境为prod

image-20240510141002410

2.maven打包

image-20240510141329259

3.上传到服务器然后重新启动

image-20240510141219305

image-20240510141322995

3.UserUtil.java 获取用户信息
1.修改环境变量

image-20240510141454701

2.获取cookie

image-20240510141645300

4.准备压测
1.http请求默认值

image-20240510141746474

2.http请求信息

image-20240510141913477

3.修改cookie的域

image-20240510142730644

4.开始压测5000次请求,QPS为55

image-20240510144422400

5.使用redis缓存页面来优化并重新部署

image-20240510144638573

6.再次压测,QPS为80,有所提升

image-20240510145440390

7.关于Redis缓存页面与DB的数据同步问题

image-20240510150344168

3.对象缓存问题解决

1.问题分析

在校验用户是否登录时,会根据cookie在Redis中查询用户信息,但是如果在DB中的用户信息更改了,那么就会发生数据不一致的问题

2.具体实现
1.UserService.java
    /*** 更新密码* @param userTicket* @param password* @param request* @param response* @return*/public RespBean updatePassword(String userTicket, String password, HttpServletRequest request, HttpServletResponse response);
2.UserServiceImpl.java
    @Overridepublic RespBean updatePassword(String userTicket, String password, HttpServletRequest request, HttpServletResponse response) {// 根据ticket获取用户User user = getUserByCookie(userTicket, request, response);if (null == user) {throw new GlobalException(RespBeanEnum.MOBILE_NOT_EXIST);}// 更新密码user.setPassword(MD5Util.inputPassToDBPass(password, user.getSlat()));int result = userMapper.updateById(user);if (1 == result) {// 删除redis中的用户信息redisTemplate.delete("user:" + userTicket);return RespBean.success();}return RespBean.error(RespBeanEnum.PASSWORD_UPDATE_FAIL);}
3.UserController.java
    // 更新密码@RequestMapping("/updatePassword")@ResponseBodypublic RespBean updatePassword(String userTicket, String password, HttpServletRequest request, HttpServletResponse response) {return userService.updatePassword(userTicket, password, request, response);}
3.测试
1.登录一下,得到票据

image-20240510154410627

2.Redis中有该用户信息

image-20240510154635876

3.更新密码 http://localhost:9092/seckill/user/updatePassword?userTicket=4dfaea799a9b438ea96ef61f7da435e3&password=666666

image-20240510154823197

4.刷新Redis,用户信息被删除

image-20240510154850757

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

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

相关文章

AIGC简介:如何利用人工智能进行内容生成

目录 一、引言二、AIGC的定义与技术原理1. 定义说明2. 关键技术3. 技术原理 三、AIGC的主要应用领域1. 文本内容生成2. 图像和视频生成3. 音频内容的创建4. 数据分析与报告 四、实施AIGC的步骤和方法1. 定义项目目标2. 数据准备与处理3. 选择合适的工具和技术4. 模型训练与测试…

服务器数据恢复—raid5阵列上分配的卷被删除后重建如何恢复被删除卷的数据?

服务器存储数据恢复环境&#xff1a; 某品牌FlexStorage P5730服务器存储&#xff0c;存储中有一组由24块硬盘组建的RAID5阵列&#xff0c;包括1块热备硬盘。 服务器存储故障&#xff1a; 存储中的2个卷被删除&#xff0c;删除之后重建了一个新卷。需要恢复之前删除的一个卷的数…

头文件和源文件的一些情况分析

c函数的定义和声明 函数和变量的声明可以有多次,但是定义只能有一次 其实头文件可以写函数的定义,但是在工程里面很多人引用这个头文件很容易造成重复定义的情况 有一个例外情况头文件里面也可以写函数定义或者变量定义 一般情况 //2.h #pragma once int add(int a, int b…

百分之九十的人都忽视了JMeter响应断言中的这个实用功能—— Jmeter Variable Name to use

JMeter的响应断言 相信对于使用过JMeter的同学来学&#xff0c;一定都使用过响应断言&#xff0c;在这里我就不相信介绍了&#xff0c;我们可以简单的理解为&#xff1a; JMeter的响应断言是一种用于检查测试中得到的响应数据是否符合预期的工具&#xff0c;旨在保证性能测试…

2024最新python入门教程|python安装|pycharm安装

前言&#xff1a;在安装PyCharm之前&#xff0c;首先需要明确PyCharm是一款功能强大的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。PyCharm旨在通过提供智能代码补全、语法高亮、代码检查、快速导航和重构等丰富的编码辅助工具&#xff0c…

在无GPU的windows上运行ChatTTS

如果你在安装的过程中出现了下面的错误&#xff0c;不妨先看看这些安装步骤&#xff1a; cl: 命令行 error D8021 :无效的数值参数“/Wno-register” error: command C:\ windows ERROR: Failed building wheel for pynini 卷完了文本&#xff0c;卷图片&#xff0c;卷完了图…

AI 入门指南二 :AI提示词(Prompt)

一&#xff0c;提示词的定义 提示词在中文中意为“触发”&#xff0c;在自然语言处理&#xff08;NLP&#xff09;的领域&#xff0c;它更接近于一个“心领神会”的概念&#xff0c;而非具有明确定义的术语。 简而言之&#xff0c;提示词是用户对大型语言模型的输入&#xff0…

电脑自动关机怎么设置?简单3步就能搞定

电脑自动关机功能在许多场景下非常实用&#xff0c;例如下载大文件后自动关机、长时间不使用电脑后自动关机以节省能源等。通过合理设置自动关机&#xff0c;可以提高电脑使用的便利性和节能效果。本文将介绍电脑自动关机怎么设置的三种方法&#xff0c;帮助您根据不同需求灵活…

详解51种企业应用架构模式

文章目录 什么是企业应用企业应用的种类企业架构模式关于作者 导读&#xff1a;企业应用包括哪些&#xff1f;它们又分别有哪些架构模式&#xff1f;世界著名软件开发大师Martin Fowler给你答案 什么是企业应用 我的职业生涯专注于企业应用&#xff0c;因此&#xff0c;这里…

物理隔离条件下文件交换的防泄密U盘,企业该如何选择?

对于网络安全要求高的企业和单位&#xff0c;往往采用物理隔离的方式进行网络建设&#xff0c;如政府单位、军工、科研所、航空航天企业、以及部分金融机构、医疗单位、电力企业、生物制药实验室等。 但物理隔离后&#xff0c;仍然存在着隔离网间的数据交换需求&#xff0c;此时…

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成 学习前言源码下载地址EasyAnimate V2简介技术储备Diffusion Transformer (DiT)Motion ModuleU-VITLora 算法细节算法组成视频VAE视频DIT 数据处理视频分割视频筛选视频描述 模型训练视频VAE视频D…

vue动态加载组件import引入组件找不到组件(Error: Cannot find module)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

Flutter开发效率提升1000%,Flutter Quick教程之定义Api(三)

将tab键切换到Response&#xff0c;会出现这么一个界面 这是添加api返回的json数据。比如我们添加一个json数据。 添加完json数据后&#xff0c;右上角有一个删除按钮。要换json数据的话&#xff0c;可以点击清除再重新输入。 这时候&#xff0c;左边的面板上还会显示出 这个的…

防勒索软件的功能特点

随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索软件(也称为勒索病毒)的威胁尤为严重。勒索软件通过加密用户数据或锁定用户系统来威胁用户支付赎金&#xff0c;一旦感染&#xff0c;用户将无法正常访问或使用其重要数据&#xff0c;导致严重的经…

Python02:python代码初体验

0、python代码初体验 print(hello,world)看到执行结果输出&#xff0c;则OKK! 1、输出结果取消换行 当print多个执行结果&#xff0c;又希望它们在同一行展示时&#xff1a; print(hello,world, end)print(Hao are, end ) print(you, end?) print(I am fine.) # end参数可…

C++——从C语言快速入门

目录 一、数组 1、声明数组 2、初始化数组 3、访问数组元素 4、示例 5、注意事项 6、数组小练习 计算器支持加减乘除 数组找最大值 二、指针 三、字符串 string 类型 一、数组 在 C 中&#xff0c;数组是一种存储固定大小的相同类型元素的序列。数组的所有元素都存…

白银票据~

一. 白银票据的原理 白银票据就伪造ST票据&#xff0c; kerberoasting是破解ST票据中的服务用户hash值&#xff0c;有以下区别&#xff1a; 白银票据&#xff1a;伪造的ST使用的是机器用户的Hash值 Kerberoasting:破解的是ST的域用户的hash值二. 白银票据的利用条件 1.域名 …

操作失败——后端

控制台观察&#xff0c;页面发送的保存菜品的请求 返回的response显示&#xff1a; ---------- 我开始查看明明感觉都挺正常&#xff0c;没啥错误&#xff0c;就是查不出来。结果后面电脑关机重启后&#xff0c;隔一天看&#xff0c;就突然可以了。我觉着可能是浏览器的缓存没…

【学习】DCMM认证提升企业竞争优势的表现

DCMM认证是企业提升数据管理能力的重要途径。它不仅可以帮助企业评估自身的数据管理水平&#xff0c;还可以为企业提供改进的方向和目标。在数字化时代&#xff0c;拥有强大的数据管理能力是企业成功的关键。因此&#xff0c;通过DCMM认证&#xff0c;企业可以更好地适应数字化…

ruoyi-nbcio基于jeecg的flowable前端支持自定义表单组件的自动获取方法

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…