商城首页卡爆了!!!

前言

最近我们的商城系统出现了一个线上问题,用户访问商城首页的时候要差不多20秒,才返回数据,可以说卡爆了。

到底怎么回事呢?

1.案发现场

上周四晚上,我们有一个正常的迭代版本按照预期的时候上线。

本次迭代,我所涉及的功能,很快上线,并且测试通过了。

但没法下班,因为项目组其他同事,还有线上问题在紧急处理。

我过去了解了一下情况,用户访问商城首页的时候响应太慢了,要20秒才返回,有用户投诉过来了。

进一步了解之后发现,造成这个问题的根本原因是redis服务器挂了。

为什么会挂呢?

是因为一次性往redis中存储的数据太多了,导致内存不足。

这个商城系统部署到了阿里云上,当时购买了1G的内存空间。

但由于这次上线,有个新功能,需要在商城首页上,按不同的地区,推荐不同的商品。商品还要按不同的分类做区分。

原本商品只有几十万其实不多,但是按地区和分类做区分之后,保存的数据量乘以了几百倍,一下子占用了大量的内存。

redis挂了为什么会导致首页慢呢?

答:因为代码中有业务逻辑,如果从redis中没有获取到数据,或者访问redis失败了,会从数据库中获取。虽说当时是晚上,用户并发量不大,但是直接访问数据库,响应时间一下子下降了很多。

图片

2.如何快速解决问题?

目前的这套方案,先从redis中获取数据,如果失败了,再从数据库中获取。

现在的问题是:redis内存不足,临时解决问题,只能加内存资源了。

因为加内存是最快的,直接加到了4G。如果要改代码,这个功能今天晚上可能没法上线,之前购买的1G的资源确实有点小。

在阿里云上redis加了内存之后,这个问题很快解决了,首页访问速度一下子提升。

但这不是问题的本质。

3.复盘

第二天,我们开始复盘问题。

发现之前的方案有点问题:

  1. 这次新增的推荐商品功能,保存到redis的数据量太大了,把有些为null值的字段,或者前端用不到的字段也保存到redis中了,数据结构设计不合理。

  2. redis出现问题之后的兜底方案有点问题,如果redis挂了,就直接访问了数据库,导致了用户访问慢的问题。如果是白天用户并发量上来,可能会直接导致数据库挂掉。

那么,如何优化呢?

最近无意间获得一份BAT大厂大佬写的刷题笔记,一下子打通了我的任督二脉,越来越觉得算法没有想象中那么难了。
这位BAT大佬写的Leetcode刷题笔记,让我offer拿到手软

4.如何优化?

数据结构不合理的问题,可以通过调整数据结构解决,非常容易。

但如果redis挂了该如何处理呢?

4.1 页面静态化

其实对于商城首页,最好的方案是做页面静态化处理。

但由于目前商城的用户并发量,还不算很大,而且如果改成页面静态化,前后端的改动都太大了。

因此,这个方案最先被我们否定了。

4.2 加本地缓存

为了防止后面再次出现商城首页访问慢的问题,可以在应用服务增加本地缓存。

这样不管redis以后能否正常运行,都不影响商城首页的功能。

但需要考虑一个事情:应用服务的内存是否够用?

显然如果将所有推荐的商品数据,都保存到应用服务的本地内存中,同样可能会导致应用服务的内存不足的问题。

因此,直接加本地内存是不行的。

4.3 改成MongoDB

使用MongoDB替代Redis保存数据。

Redis:数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。

MongoDB:数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

显然MongoDB更适合保存大批量的结构化的文档数据。

由于我们之前在做其他功能时,使用过MongoDB,它的性能也是挺不错的。

但如果直接改成从MongoDB中获取数据,商城首页的访问速度可能会有所下降。

最近无意间获得一份BAT大厂大佬写的刷题笔记,一下子打通了我的任督二脉,越来越觉得算法没有想象中那么难了。
这位BAT大佬写的Leetcode刷题笔记,让我offer拿到手软icon-default.png?t=N7T8https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzg4NjYyODc4OA%3D%3D%26mid%3D2247483776%26idx%3D1%26sn%3Dd4f06fcae670a537ebf4ce7b1a3c9138%26chksm%3Dcf97895bf8e0004d9bd147cfc82e7f44c971139ad399665610d74114eac9b824b20b9e9737d7%23rd

4.4 本地缓存 + MongoDB

上面说到过的加本地缓存,和使用MongoDB都有各自的优缺点。

为什么不把两种方案结合一下呢?

在本地缓存中保存热点数据,每隔5分钟更新一次。

用户的请求过来,先从本地缓存中获取推荐商品数据,如果有则直接返回。

如果没有,则从MongoDB获取数据。

这样可以解决性能的问题,也可以解决保存大量的数据。

5.兜底方案

上面的说的本地缓存 + MongoDB,基本可以解决redis挂了的问题。

但如果MongoDB挂了该怎么办呢?

这就需要有一套更好的兜底方案。

5.1 使用Apollo配置

如果MongoDB挂了,则直接返回Apollo配置中默认数据,默认是北京市东城区的推荐商品数据。

该配置由于在Apollo中,我们可以根据实际情况动态调整。

我们都知道Apollo可以配置成集群模式,是高可用的,一般不容易挂掉。

但它有一个硬伤,就是如果数据并更了,需要人手动调整数据。

没法保证数据的实时性。

5.2 再从数据库访问数据

如果从MongoDB中获取数据失败了,则直接从数据库中获取数据。

该方案从业务的角度来说,确实没有问题。

但万一真的出现这种情况,同样会出现商城首页访问很慢的问题。

5.3 再从redis访问数据

如果从MongoDB中获取数据失败了,则直接从redis中获取数据。

Redis中只保留热点商品数据。

这也是一种方案,不过要维护两份数据:MongoDB一份,Redis一份。

可能会存在数据不一致的问题。

5.4 再加一个本地缓存

在从数据库获取数据之后,再加一个本地缓存,保存默认的数据,即:北京市东城区的推荐商品数据。

这个本地缓存,只有在第一次访问数据库时写入,并且有效期是24小时。

相当于在MongoDB和数据库之间,再加了一层默认的本地缓存。

这样就能解决数据库访问慢的问题。

6.最终方案

经过激烈讨论之后,我们最终选择的方案是:本地缓存+MongoDB+本地默认缓存+数据库。

图片

有时候选择的某一个技术方案,是根据当前的业务发展,或者公司现状,资金,资源,人手,技术能力等多方面考虑的。

很多技术问题都没有最完美的解决方案,只有最适合的方案。

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描下发二维码关注一下,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:面试、代码神器、开发手册、时间管理有超赞的粉丝福利,另外回复:加群,可以跟很多BAT大厂的前辈交流和学习。

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

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

相关文章

【K8S基础】-k8s的核心概念控制器和调度器

Kubernetes是一个开源的容器编排平台,旨在简化和自动化容器化应用程序的部署、扩展和管理。它提供了一个强大的基础设施来管理容器化应用程序的生命周期,并确保它们在整个集群中高效运行。 Kubernetes的核心概念包括集群、节点、Pod、控制器、调度器等。…

vue3使用mixins

<template><div>{{ num }}___{{ fav }}</div><button click"favBtn">改变值</button> </template><script setup lang"ts"> import mixin from "../mixins/mixin"; let { num, fav, favBtn } mixin(…

如何使用PatchaPalooza对微软每月的安全更新进行全面深入的分析

关于PatchaPalooza PatchaPalooza是一款针对微软每月安全更新的强大分析工具&#xff0c;广大研究人员可以直接使用该工具来对微软每月定期推送的安全更新代码进行详细、全面且深入的安全分析。 PatchaPalooza使用了微软MSRC CVRF API的强大功能来获取、存储和分析安全更新数…

ip addr和ifconfig

ip addr可以显示更多信息&#xff0c;包括为启动的网络驱动如wlan&#xff0c;而ifocnfig只显示在线的驱动。若wlan是down的&#xff0c;则ip addr会显示信息&#xff0c;ifconfig不会显示信息。 ip addr: ifconfig:

双端队列、优先级队列、阻塞队列

双端队列、优先级队列、阻塞队列 文章目录 双端队列、优先级队列、阻塞队列1 双端队列1.1 概述1.2 应用实例1.2.1 双端链表实现1.2.2 数组实现1.2.3 测试代码 1.3 课后作业- LeeTCode103 2. 优先级队列2.1 概述2.2 基于无序数组实现2.3 基于有序数组实现2.3 堆实现优先级队列2.…

Python 爬虫之下载歌曲(一)

爬取某酷音乐平台歌曲 文章目录 爬取某酷音乐平台歌曲前言一、基本流程二、代码编写三、效果展示总结 前言 老是爬视频有点乏味&#xff0c;换个口味。今天出个爬歌曲的。后续由易到难也出个相关的系列教程。 一、基本流程 打开某酷网站播放某个歌曲&#xff0c;复制这个歌曲…

洛谷 P1387 最大正方形 刷题笔记

P1387 最大正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 找出一个 由数字1组成的最大正方形 输出该正方形的边长 &#xff1b; 思路 dp 画图模拟 可以发现 当 当前点a[i][j]1,满足构成正方形的初步条件 而当前点能构成的最大正方形长度 由它的左上角 左边和上边…

uni-app封装表格组件

组件代码&#xff1a; <template><view><uni-table class"tableBox" border stripe emptyText"暂无更多数据" ><!-- 表头行 --><uni-tr class"tableTr"><uni-th align"center" v-for"item in …

网页乱码问题(edge浏览器)

网页乱码问题&#xff08;edge&#xff09; 文章目录 网页乱码问题&#xff08;edge&#xff09;前言一、网页乱码问题1.是什么&#xff1a;&#xff08;描述&#xff09;2.解决方法&#xff1a;&#xff08;针对edge浏览器&#xff09;&#xff08;1&#xff09;下载charset插…

CUMT--Java复习--Java的一些琐碎的知识

目录 一、Java体系 1、Java语言优势 2、Java相关专有名词 3、Java跨平台原理 4、垃圾回收机制 二、类加载 1、Class类 2、类加载步骤 3、类加载器 三、反射 四、枚举 1、Enum类方法 2、改写Enum类 五、注解、国际化 六、接口的默认方法和静态方法 七、Lambda规…

宝塔mysql本地服务器状态异常如何解决

今天安装宝塔的时候突然遇到的问题 来吧 直接上bug图 答案&#xff1a;修改Mysql数据库密码

(10)Linux冯诺依曼结构操作系统的再次理解

&#x1f4ad; 前言&#xff1a;本章我们首先会明确冯诺依曼体系结构的概念&#xff0c;旨在帮助大家理解体系结构在硬件角度去理解数据流走向的问题。理解完之后我们再去谈操作系统、更多有关操作系统的细节&#xff0c;着重谈谈操作系统概念与定位、操作系统是如何去做管理的…