记录一次线上并发请求太多,导致StackExchange.Redis组件超时导致业务系统无法正常访问问题

项目场景:

项目场景:.NET 7  使用了StackExchange.Redis 1.5.0版本


问题描述

在某一天突然订单系统异常,查看日志提示:StackExchange.Redis.RedisTimeoutException: Timeout performing EXISTS (10000ms), next: XXXX, inst: 1, qu: 0, qs: 55, aw: False, bw: SpinningDown, rs: ReadAsync, ws: Idle, in: 3856, in-pipe: 0, out-pipe: 940, last-in: 1, cur-in: 0, sync-ops: 830585, async-ops: 15530, serverEndpoint: 192.168.15.130:6379, conn-sec: 166450.6, aoc: 0, mc: 1/1/0, mgr: 10 of 10 available, clientName: a0f76992b40a(SE.Redis-v2.6.122.38350), PerfCounterHelperkeyHashSlot: 16082, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=44,Free=32723,Min=4,Max=32767), POOL: (Threads=44,QueuedItems=39,CompletedItems=9162547,Timers=15), v: 2.6.122.38350 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts),其实就是超时了,然后点击这个文章里面看发现和线程池饥饿有关;看上面异常信息WORKER: (Busy=44,Free=32723,Min=4,Max=32767)44个繁忙,最小工作线程是4(因为没有配置,默认就是CPU核心数)


原因分析:

简单来说就是某一时刻突然大量请求涌入,又没有配置最小线程数,导致处理不过来,因为线程池注入线程是需要时间的,而在这时刻我们服务又是依赖与StackExchange.Redis,redis一超时就导致整个请求都失败了!按照文章里配置下最小线程数就好!

解决问题是很简单!!!但是最好知道下原理!!!经过题主一番搜索,发现一篇大佬的高质量博文!!!强烈建议大家看看!!!

概述 .NET 6 ThreadPool 实现

.NET Core线程池的源码,大概都在这个层级,包括一些Task相关的操作

runtime/src/libraries/System.Private.CoreLib/src/System/Threading at main · dotnet/runtime · GitHub

核心知识点:线程饥饿不够用时,会每隔一定时间去注入新的线程,我们设置最小线程数其实就是让程序更晚进入饥饿状态。


解决方案:

只需要在程序启动前加一行 ThreadPool.SetMinThreads(200, 200);这个数不是固定的,需要根据服务器CPU性能综合测试下

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值