后端程序员常犯的错误-本地缓存相关bug和技术思考

news2024/9/9 7:29:00

1 springboot集成本地缓存基本常识:

SpringBoot集成本地缓存性能之王Caffeine示例详解
SpringBoot 缓存之 @Cacheable介绍

2 线上问题

2.1 发现过程

接口内的rpc调用报错,error级别的日志被监控平台报警。

2.2 故障排查

2.2.1 代码

@Cacheable(cacheManager = RedisKeyConstants.CACHE_MANAGER_LOCAL, value = RedisKeyConstants.Gpc.certificate.CACHE_NAME, key = RedisKeyConstants.Gpc.certificate.CACHE_KEY)
public User getData(Object obj) {
	User user = new User();
	try {
		Response<User> res = aliyunClient.doRpcCall(obj);
		if (!resp.getCode().equals("success!")) {
        	log.error("error happening, code:{}, msg:{}", resp.getCode(), resp.getMsg());
            return null;
		}
		if (res.getData() == null) {
        	log.error("error happening. rpc return a Null Object, code:{}, msg:{}", resp.getCode(), resp.getMsg());
			return null;
		}
	} catch (Exception e) {
        log.error("rpc调用异常", e);
        return user;
    }
    return user;
}

2.2.2 原因

(1)主要有两个,一个是当rpc调用异常的时候,会被try捕获并且直接return一个实例化的user对象,然后触发@Cacheable注解定义的本地缓存机制,导致异常调用的时候,对象也被缓存,随后直至本地缓存中该条目过期,后面的请求才会发起rpc请求更新缓存,所以对于rpc调用时获取的错误,应该不缓存
(2)rpc调用成功但是返回了一个空对象,这个时候我直接返回的是null值,导致本地缓存没有存储这个空值,随后当流量走getData这个方法时,因为没有查到缓存,就会一直走rpc调用,造成cpu时间浪费,同时会延长响应时间,如果某一波大流量打进来,rpc服务甚至会挂掉,这个时候会发生缓存击穿。

3 解决

3.1 代码

@Cacheable(cacheManager = RedisKeyConstants.CACHE_MANAGER_LOCAL, value = RedisKeyConstants.Gpc.certificate.CACHE_NAME, key = RedisKeyConstants.Gpc.certificate.CACHE_KEY,unless = "#result==null")
public User getData(Object obj) {
	User user = new User();
	try {
		Response<User> res = aliyunClient.doRpcCall(obj);
		if (!resp.getCode().equals("success!")) {
        	log.error("error happening, code:{}, msg:{}", resp.getCode(), resp.getMsg());
            return user;
		}
		if (res.getData() == null) {
        	log.error("error happening. rpc return a Null Object, code:{}, msg:{}", resp.getCode(), resp.getMsg());
			return user;
		}
	} catch (Exception e) {
        log.error("rpc调用异常", e);
        return null;
    }
    user.setXXXX(res.getData().getXXXX());
    ....
    return user;
}

3.2 解决方法

3.2.1 确保springboot不会缓存null值

在@Cacheable注解上添加unless = "#result==null"属性

3.2.2 try捕获异常时返回null(解决rpc异常仍然缓存的问题)

3.2.3 当rpc调用正常返回null或者有对象但没有实际存储值时返回user对象,以使得本地缓存这个实例化但是无值的user(解决缓存击穿问题)

3.3 测试过程

1 首先会在各个return之前会打印相关的error级别的日志以作观察

2 在rpc调用代码中故意写一个错误的url以使得出发异常或插入int i = 5/0触发异常,第一次调用触发rpc异常,然后第二次再进行,如果仍然触发异常或者执行了getData方法的代码,就说明异常后的返回值不会缓存。

3 模拟rpc调用返回空值,分两次调用,查看第二次是否会走getData方法,如果没走就说明缓存生效。

4 一些技术的其他思考【从阿里p8的聊天中得到的一些技术上的思考】

4.1 为什么对于rpc调用异常后的方法返回值不进行缓存?如果rpc故障时间长,每次都不缓存,是不是也存在缓存失效,长时间内数据都会进行rpc调用?【或者问不对rpc调用异常进行缓存的精确场景。】

(1)首先既然rpc异常了就不应该对null值进行缓存,后续的查询不能一直用null缓存。
(2)rpc是暂时故障,被调用方会进行迅速(秒级)的故障转移,比如重启、切换,在故障切换期间

4.2 如果rpc服务重启了,而本地缓存也刚好过期了,这个时候大流量过来同时调用这个rpc服务怎么办呢?

1. 异常降级处理

对于RPC服务,可以实现服务降级策略,当检测到RPC服务负载过高或出现异常时,可以临时返回一些兜底数据或执行简化的逻辑以减轻服务压力。

2. 限流

对于高频请求,尤其是批量操作导致的数据访问,可以通过限流策略来控制请求速率,避免短时间内对后端服务(包括缓存和RPC服务)造成过大压力。

3. 分布式锁

当缓存失效后,为了防止同时有大量对同一数据的访问请求打到后端服务,可以引入分布式锁的机制。在更新缓存前通过获取分布式锁来确保同一时间只有一个请求去调用RPC服务更新数据,并将结果写入缓存。其他的请求只需等待缓存更新即可获取数据,这种方式需要确保锁的获取与释放正确管理,以防止死锁或服务延迟。

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

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

相关文章

C语言典型例题19

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题2.7 检查浮点型数据的舍去误差 C语言知识&#xff1a; 浮点数在C语言用有两个类型&#xff0c;有float和double类型&#xff0c;其中double类型的数据精度更高 解题思路&#xff1a; 可以将一个double类型的…

城市运管服平台:智慧城市的神经中枢

“城市运行管理服务平台”&#xff08;简称“城市运管服平台”&#xff09;作为现代城市治理的智慧核心&#xff0c;正以前所未有的方式重塑着城市管理与服务的面貌。本文旨在深度解析城市运管服平台的内涵、运作机制及其对推动智慧城市发展的重要意义。 城市运管服平台&#…

视频超压缩保持质量 ffmpeg

参考&#xff1a; https://x.com/mortenjust/status/1817991110544744764 基于 FFMpeg 的 H264 压缩标准&#xff0c;实现压缩 90% 的视频大小 在线体验地址&#xff1a; https://tools.rotato.app/compress ffmpeg命令执行 ffmpeg -i "C:\Users\loong\Downloads\屏幕录…

Vidu视频生成工具全球上线,注册即刻体验

生数科技&#xff0c;这家成立于2023年3月的年轻企业&#xff0c;其核心团队成员来自清华大学人工智能研究院。首席科学家朱军教授&#xff0c;曾在贝叶斯机器学习和多模态大模型领域取得多项原创性成果。Vidu的核心技术U-ViT架构&#xff0c;是全球首个将Diffusion与Transform…

# mongodb_基础到进阶 -- MongoDB 快速上手(四)

mongodb_基础到进阶 – MongoDB 快速上手&#xff08;四&#xff09; 一、MongoDB &#xff1a;文章评论 需求&表结构&技术选型 1、文章评论&#xff1a;需求分析 1&#xff09;参考某头条的文章评论业务&#xff0c;文章示例参考&#xff1a;早晨空腹喝水&#xff…

功能强大的图片/pdf识别成文字的工具Umi-OCR

一、工具概述 操作系统&#xff1a;支持windows、Linux使用方法&#xff1a;图形化、命令行、http接口 二、功能特性 三、部署方式 1、windows 下载地址&#xff1a;Umi-OCR_文字识别工具 2、linux 推荐使用docker部署 》下载 Dockerfile mkdir Umi-OCR-Docker cd Umi-OC…

Overlay网络

Overlay 介绍 Overlay网络是将已有的物理网络&#xff08;Underlay网络&#xff09;作为基础&#xff0c;在其上建立叠加的逻辑网络&#xff0c;实现网络资源的虚拟化。 传统网络带来了以下一些问题&#xff1a; ● 虚拟机规模受 网络规格限制在传统二层网络环境下&#xff0…

某“新一线城市“前端面试,纯纯被恶心到了

一.起因 在boss上刷到的一个小小厂&#xff0c;收大四全年实习生(web前端)&#xff0c;因为离家乡比较近&#xff0c;而且双非一本的学历以及入坑的时间没有太长(前端部分不到一年)&#xff0c;想去那里看看形势&#xff0c;要求是笔试面试&#xff0c;当场给是否录用结果&…

WPS@文字文档插入的表格,对单元格填充底纹颜色时,有字的地方就填充不上 ,空白。

背景 在创建的WPS文字文档中&#xff0c;插入了一个表格&#xff0c;对表格的某些单元格需要填充底纹颜色 问题 问题如标题&#xff0c;“文字文档插入的表格&#xff0c;对单元格填充底纹颜色时&#xff0c;有字的地方就填充不上 &#xff0c;空白”&#xff0c;直观如下图 解…

【Linux】-----进度条小程序

目录 前言 基本知识 Ⅰ、回车和换行 Ⅱ、缓冲区 两个有意思的现象 简单定义 刷新缓冲区 简易倒计时程序 进度条代码 多文件下makefile写法 一代(无任何场景) procs1.h代码 procs1.c代码 主函数main1.c 一代运行结果&#xff1a; 二代 (搭配下载场景) procs2.c代…

Qt Creator使用git管理代码

1.在GitHub中新建仓库&#xff0c;设置好仓库名后&#xff0c;其它的设置默认即可。 2.打开git bash&#xff0c;输入以下命令&#xff1a; git config --global user.name "xxxxx" #设置你的GitHub用户名 git config --global user.email "xxxxxxxxx.…

大厂linux面试题攻略四之Linux网络服务(二)

五、Linux网络服务-Apache优化 1.请写出工作中常见的Apache优化策略 Apache服务器优化是提升网站响应速度和稳定性的重要手段。在工作中&#xff0c;常见的Apache优化策略包括以下几个方面&#xff1a; 1. 启用压缩技术 Gzip压缩&#xff1a;使用Gzip压缩技术可以减少服务器…

免费【2024】springboot 宠物医院微信小程序的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Python(关于属性和类详细代码解释)

动态绑定属性 class Student:# 类属性&#xff1a;定义在类中&#xff0c;方法外的变量school 北京xxx教育print(type(school)) # 定义在类里面所以属性不变# 类属性初始化方法def __init__(self, xm, age): # xm,age是方法的参数&#xff0c;是局部变量&#xff0c;xm,age…

解决Centos不支持docker命令行tab提示问题!!!

一、CentOS不支持Docker Tab提示 在使用CentOS操作系统时&#xff0c;有些用户可能会遇到不能自动补全Docker命令的问题。这是因为CentOS默认不支持Docker Tab提示功能&#xff0c;需要手动配置才能实现。在这篇科普文章中&#xff0c;我们将介绍如何解决这个问题&#xff0c;…

Springer旗下中科院2区TOP,国人优势大!

关注GZH【欧亚科睿学术】&#xff0c;第一时间了解期刊最新动态&#xff01; 1 通信网络类 【期刊简介】IF&#xff1a;4.0-5.0&#xff0c;JCR1区&#xff0c;中科院3区 【出版社】ELSEVIER出版社 【检索情况】SCIE&EI双检&#xff0c;CCF-C类 【征稿领域】通信网络的…

这本vue3编译原理开源电子书,初中级前端竟然都能看懂

前言 众所周知vue提供了很多黑魔法&#xff0c;比如单文件组件(SFC)、指令、宏函数、css scoped等。这些都是vue提供的开箱即用的功能&#xff0c;大家平时用这些黑魔法的时候有没有疑惑过一些疑问呢。 我们每天写的vue代码一般都是写在*.vue文件中&#xff0c;但是浏览器却只…

大模型面试之LoRA

LoRA的解释&#xff1a;一种高效微调预训练神经网络的方法 LoRA 解决的问题&#xff1a; &#x1f538; 2021年初&#xff0c;微软与OpenAI合作探索GPT-3的商业可行性。 &#x1f538; 发现仅仅通过提示&#xff08;prompting&#xff09;不足以完成生产任务&#xff0c;例如…

C++:标准模板库(STL)介绍

1.STL基本概念 从C到C&#xff0c;C语言的核心优势之一就是便于软件的重用。前面我们提到过C程序的面向对象思想&#xff0c;即继承和多态、标准类库等可以实现重用。除此之外&#xff0c;通过泛型程序设计(generic programming)的思想&#xff0c;即模板机制以及标准模板库ST…

微软:警惕利用VMware ESXi进行身份验证绕过攻击

微软于7月29日发布警告&#xff0c;称勒索软件团伙正在积极利用 VMware ESXi 身份验证绕过漏洞进行攻击。 该漏洞被追踪为 CVE-2024-37085&#xff0c;由微软安全研究人员 Edan Zwick、Danielle Kuznets Nohi 和 Meitar Pinto 发现&#xff0c;并在 6 月 25 日发布的 ESXi 8.0 …