当前位置: 首页 > news >正文

C# --- 本地缓存失效形成缓存击穿触发限流

C# --- 本地缓存失效形成缓存击穿触发限流

  • 问题描述
  • 解决方案
    • 缓存Request Task
    • 加入信号量限制请求数量

问题描述

  • 某一接口前端会偶发返回400.
  • 通过检查日志发现是后端服务调用外部Api时,因为缓存失效导致并发请求数量过多 (QPS接近300), 外部Api返回429导致的.
  • 代码大致如下

private readonly MemoryCache _timeZoneCache = new(new MemoryCacheOptions())private MemeoryCacheEntryOptions EntryOption => new MemeoryCacheEntryOption().SetAbsoluteExpiraton(DataTimeOffset.Utc.Now.AddMinutes(1))public async Task Process()
{var elements = await GetAllElementsAsync();//如果elements数量过多,这里会并发发送大量请求var tasks = elements.Select(element -> GetTimeZoneAsync(element)).ToList();if (tasks.Any()){await Task.WhenAll(tasks)}}private async Task<string> GetTimeZoneAsync(Element element){if (_timeZoneCache.TryGetValue(element.QueryParameter, out string timeZone){return timeZone}//send reuqets to external Apivar reponse = await SendTimeZoneRequestAsync(element)//parse http responsevar result = ParseHttpResponse(response)//set cache_timeZoneCache.Add(element.QueryParameter, result)}
  • 当缓存失效时,如果elements的数量过多(比如300个),那么上面的代码会并发发送300个请求. 导致触发外部服务的限流,返回429

解决方案

缓存Request Task

  • 经过调查发现,被发送出去的大量请求其实很多是重复的请求
  • 那么可以利用C#的Task机制,加入一个新的缓存,这个缓存用来缓存发送出去的Request Task,避免重复发送请求

private readonly MemoryCache _timeZoneCache = new(new MemoryCacheOptions())private MemeoryCacheEntryOptions EntryOption => new MemeoryCacheEntryOption().SetAbsoluteExpiraton(DataTimeOffset.Utc.Now.AddMinutes(1))public async Task Process()
{var elements = await GetAllElementsAsync();//如果elements数量过多,这里会并发发送大量请求var tasks = elements.Select(element -> GetTimeZoneAsync(element)).ToList();if (tasks.Any()){await Task.WhenAll(tasks)}}private async Task<string> GetTimeZoneAsync(Element element){if (_timeZoneCache.TryGetValue(element.QueryParameter, out string timeZone){return timeZone}var response = await GetTimeZoneRequestTaskAsync(element);//parse http responsevar result = ParseHttpResponse(response)//set cache_timeZoneCache.Add(element.QueryParameter, result)}private async Task<HttpResponse> GetTimeZoneRequestTaskAsync(Element element){if (_timeZoneRequestCache.TryGetValue(element.QueryParameter, out string timeZoneRequest){return timeZoneRequest}//do not await herevar request = SendTimeZoneRequestAsync(element)//cache the request_timeZoneRequestCache(element.QueryParameter, request);return request;}

加入信号量限制请求数量

  • 如果都是不同的请求,那么可以使用信号量控制并发发送请求的数量
    参见 https://blog.csdn.net/weixin_38803409/article/details/135353000
http://www.lryc.cn/news/610891.html

相关文章:

  • RHCA04--系统模块管理与资源限制
  • 武汉火影数字:VR大空间在文旅产业的创新应用
  • TDengine 中 TDgpt 的模型评估工具
  • VR眼动追踪技术帮助医生更快速确认大脑神经损伤与疾病
  • 与功能包相关的指令ros2 pkg
  • Reading Books(Sorting and Searching)
  • 工作相关: 预刷真值与人工标注的真值之间的关系 以及 真值与原始数据的关系,
  • Node.js高并发下的内存泄漏排查与解决实录
  • postman接口测试实战
  • 前端性能测试:从工具到实战全解析
  • 奇偶校验码原理与FPGA实现
  • Z20K118库中寄存器及其库函数封装-CLOCK库
  • 通信算法之298: verilog语法generate和for介绍
  • 【学习笔记】FTP库函数学习
  • uniapp云打包打包安卓app失败,显示:本地安装包生成失败,请重试或者切换到非安心打包模式进行打包
  • 多模态新方向|从数据融合到场景落地,解锁视觉感知新范式
  • SOLIDWORKS 买断许可和订阅许可的资金流影响分析-代理商硕迪科技
  • Windows 安装 RabbitMQ 消息队列超详细步骤(附加详细操作截屏)
  • 项目设计模式草稿纸
  • Android --- Bug调查经验记录
  • zyh贪心类题目补题报告
  • 防御保护07-08
  • 游戏行业DDoS攻防实战指南
  • DDoS 防护的未来趋势AI 如何改变安全行业
  • Nginx 学习
  • Gradle 仓库管理模式深度解析与最佳实践指南
  • C语言自定义类型深度解析:联合体与枚举
  • 工业设备远程监控的 “颠覆性突破”:边缘计算网关让千里之外如在眼前
  • BUUCTF杂项MISC题解题思路(3)(不断更新)
  • Android 性能基准测试(Benchmark)完全指南:专业方法与最佳实践