-
我用 ThreadLocal 存当前登录用户,本以为线程私有绝不会串,结果某个用户偶尔会看到另一个用户的数据,因为在线程池里线程是复用的、用完没清的 ThreadLocal 残留给了下一个请求的深度复盘
我用 ThreadLocal 存当前登录用户(请求进来时 set、后续各层从 ThreadLocal 取,避免层层传参),想当然以为 ThreadLocal 线程私有、每个请求一个线程各存各的绝不会串。结果线上出了最可怕的 bug:偶发地某个用户页面上显示出了另一个用户的数据(订单、隐私),用户身份串了、是严重越权。排查才定位到线程池:Web 服务器用线程池处理请求、线程是复用的(处理完一个请求会…- 0
- 0
-
一个调用第三方接口忘了设超时的 HTTP 客户端,把整个服务的线程池拖到全部 hang 死:一次没有超时引发级联雪崩的深度复盘与韧性正解
核心服务突然大面积 504,jstack 一看几百个工作线程全卡在调用第三方风控接口的 socketRead0 上一动不动——而那个 HTTP 客户端压根没设超时。对方发布卡了几十秒,我方每个线程无限期等待,线程池被占满,连不相干的接口也全挂了,级联雪崩。本文从满屏 hang 死的线程堆栈讲起,剖析没超时如何耗尽线程池拖垮全局,给出设超时(底线)+熔断+降级+线程隔离(舱壁)的韧性组合拳,并梳理常…- 0
- 0
-
服务器很闲却瘫了:.NET 异步死锁避坑复盘
一个跑了两年都好好的 .NET 接口,某天起在流量高一点的时段就大面积超时,请求像泥牛入海一样卡住不返回。我第一反应是哪儿慢了,可登上服务器一看更懵:CPU 占用才百分之十几,内存宽裕,数据库一点不慢,可就是请求堆积、响应不出来——一个不忙的服务器,却服务不了请求。抓内存 dump 看线程栈才发现真相:进程里堆积着大量工作线程,几乎全卡在同一行形如 GetDataAsync().Result 的调…- 2
- 0
-
用户A看到了用户B的信息:ThreadLocal 串号避坑
这是我职业生涯里最惊出一身冷汗的一次线上事故。我们用 ThreadLocal 存当前登录用户的上下文——请求进来时在拦截器里把用户信息塞进 ThreadLocal、后续业务随时取当前是谁,用了很久一直稳稳的。可某天客服收到一个让所有人头皮发麻的投诉:一个用户登录后在自己的页面里看到的却是另一个陌生用户的姓名手机号订单,用户信息串了——这涉及隐私泄露性质极其恶劣。连夜拉日志排查才拼出全貌:Web 服…- 2
- 0
-
压测一上量接口全超时:C# async/await 死锁与线程池饥饿
一次本该平平无奇的上线前压测,把并发拉到几百之后整个服务就像被掐住了脖子:响应时间从几十毫秒飙到十几秒,最后大面积超时——可机器的 CPU 占用还不到 20%,内存也宽裕得很。这种"不忙却瘫"的景象比 CPU 打满还让人发毛。排查一圈数据库和下游都没问题,直到拉出线程池指标才发现真相:工作线程被一口气全占满,而它们没一个在干活,全都阻塞在一个 await 上睡觉等结果。凶手是一…- 2
- 0
-
Java 线程池实战:别用 Executors,七个参数与拒绝策略怎么配
一次大促压测,服务在流量爬到峰值前先 OOM 倒下,dump 一拉堆里塞满几十万个待处理任务,全卡在一个 Executors.newFixedThreadPool(50) 背后的无界队列里。那次之后我把 ThreadPoolExecutor 的七个参数当成七个必须亲手做的决策来理解:为什么禁用 Executors 工厂方法、队列为什么必须有界、核心线程数按 CPU 密集还是 IO 密集怎么算、四种…- 0
- 0
-
Python 并发模型选型:GIL、多线程、asyncio 与多进程到底怎么选
同事用 8 个线程跑纯 CPU 的图像处理,结果比单线程还慢——这是 Python 并发里最经典的困惑。从 GIL 这把全局锁讲起,把多线程、asyncio、多进程三套模型的脾性、坑和适用边界逐一摊开:IO 密集用线程或协程,CPU 密集只能靠多进程,asyncio 全程异步否则卡死事件循环,有 GIL 也照样要加锁。最后收口成一棵先问任务在等还是在算的选型决策树。- 0
- 0
-
C# async/await 踩坑实战:同步阻塞死锁、async void 与线程池饥饿
事情是从一个看起来人畜无害的 PR 开始的:一位同事在 ASP.NET Core 控制器里图省事,把异步调用写成了 var data = GetDataAsync().Result;,能编译、本地点一下也出结果,评审就这么过了——结果一上生产,这个接口在并发上来后开始大面积超时,最后整个应用线程池被拖垮、几乎所有请求一起卡死,根因就是这一行同步阻塞异步。那次之后我把这些年在 C# 异步上踩过的坑系…- 2
- 0
-
Java 线程池配置完全指南:从一次"线程池把服务拖到 OOM"看懂为什么不能用 Executors
2023 年我给一个订单服务加异步处理下单成功后要发通知写审计流水更新统计报表这些事都不该卡住下单这条主流程我决定把它们丢给一个线程池在后台异步做第一版我做得很顺手一行 Executors.newFixedThreadPool 拿到一个 10 线程的池子业务里需要异步的地方任务 submit 进去就不管了本地我测了测任务都正常执行完了我心里很笃定线程池嘛就是设一个线程数我把任务交给它它就用那几个线…- 3
- 0
-
Java 线程池完全指南:从一次线上 OOM 看懂七个核心参数怎么配
2022 年我维护一个电商订单处理服务,某次大促流量上来十几分钟服务就 OOM 崩了,重启又崩。导出 heap dump 一看堆里躺着几十万个待执行任务对象全堆在同一个队列里,顺着追到一行没多想的代码 Executors.newFixedThreadPool(20)——它背后是一个没有容量上限的队列,20 个线程处理不过来潮水般的订单任务被这个无底洞照单全收直到把堆内存塞爆。那一刻才意识到我从来没…- 4
- 0
-
Executors 埋的雷:一次线程池配置踩坑的复盘
几个用户同时导出大报表,报表服务就 OOM 挂掉了。根子是代码里用 Executors 随手创建的线程池:newFixedThreadPool 的无界队列撑爆内存、newCachedThreadPool 的无界线程数压力下爆炸。几天梳理线程池:七个参数、有界队列、拒绝策略、线程数估算、业务隔离、异常处理、优雅关闭、监控。- 0
- 0
-
线程池踩坑:无界队列把堆撑爆,一次 OOM 宕机的复盘
活动高峰服务反复 OOM 宕机,dump 分析发现一个线程池队列里堆了三百多万个任务,几个 G 的堆全被它占满。罪魁是 Executors.newFixedThreadPool 默认的无界队列。几天治理:显式构造 ThreadPoolExecutor、有界队列、拒绝策略产生背压、按业务隔离线程池、补齐 7 类监控指标。- 0
- 0
-
一个共用线程池拖垮全站:线程池隔离与参数调优实录
商品详情服务并行调 5 个下游,共用一个线程池。推荐服务抖动 RT 涨到 3s,十分钟全站接口 503。一周治理:有界队列 + 按下游隔离 5 个线程池(舱壁模式)+ 任务超时 + Resilience4j 熔断 + 动态线程池 + 监控告警。下游再抖动,影响圈死在单业务内。- 0
- 0
线程池
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!













