论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
程序人生
›
一下午连续故障两次,谁把我们接口堵死了?! ...
一下午连续故障两次,谁把我们接口堵死了?!
农妇山泉一亩田
金牌会员
|
2024-7-27 02:13:58
|
显示全部楼层
|
阅读模式
楼主
主题
517
|
帖子
517
|
积分
1551
唉。。。
大家好,我是程序员鱼皮。又来跟着鱼皮学习线上事故的处置处罚经验了喔!
事故现场
周一下午,我们的
编程导航网站
连续出现了两次故障,每次持续半小时左右,现象是用户无法正常加载网站,一直转圈圈。
用户很快就在群里炸开锅了,甚至有用户表示 “我提进步去了,都不敢刷新。。”
看到这些我真的非常难熬,我们团队的开辟同学也第一时间展开了排查。
简单看了下前端向后端发的请求,发现全部的请求都一直阻塞,直到超时。直接请求后端服务器的接口也是一样的,等了很久都没有正常返回数据。最关键的是,全部接口都阻塞住了,哪怕只是请求个康健检查接口(后端直接返回 "ok",不查询数据库),也无法正常响应。
我们的后端服务是摆设在容器托管平台的,正常环境下如果资源(比如 CPU 和内存)占用超过肯定比例,会自动扩容节点来让服务承载更多的并发请求,但为什么这次没有扩容呢?
其实有经验的朋侪应该已经能猜到接口堵死的原因了,下面我带大家揭开谜团。
事故排查
根据上面的现象,推测大概率是接口层出了问题,而不涉及到业务和数据库等依靠资源。由于我们的后端使用的是 Spring Boot + 内嵌的 Tomcat 服务器,而 Tomcat 同时处置处罚请求的最大线程数是固定的(默认是 200),所以当同时处置处罚的请求过多,而且每个请求一直没有处置处罚完成时,全部的线程都在繁忙,没有办法处置处罚新的请求,就会导致新的请求排队等待处置处罚,从而造成了接口堵死(迟迟无法响应)的现象。
这里我用一个简单的程序来模拟下接口堵死和排查过程。
首先写一个非常简单的测试接口,在返回内容前加一个 Thread.sleep,模拟耗时的操作,让处置处罚请求的线程进入较长的等待。
然后更改下 Tomcat 的最大线程数为 5,便于我们模拟线程数不敷的环境:
启动项目,在 Thread.sleep 打断点,然后连续请求 6 次接口。
应该只有 5 次请求会进入断点,末了一次请求会一直转圈卡住,没有线程来处置处罚。这样我们就还原了事故现场。
但以上只是推测,实际线上项目中,怎么去排查确认 Tomcat 线程都阻塞了呢?又怎么确认是哪个接口或代码让 Tomcat 线程阻塞等待了呢?
其实很简单,首先用 jps -l 下令查看 Java 后端服务对应的进程 PID:
然后使用 jstack 下令天生线程快照,并保存为文件。具体下令如下:
jstack <进程PID> > thread_dump.txt
复制代码
打开线程快照文件,全部线程的状态一目了然,搜索 http-nio 就能看到 Tomcat 的请求处置处罚线程,果然全部的请求处置处罚线程状态都是 TIMED_WAITING ,表示线程正在等待另一个线程实行特定的动作,但是有一个指定的等待时间。而且能直接看到请求是阻塞在了哪个代码位置。
利用这个方法,我们也很快定位到了编程导航接口堵死的原因,是发生在一个从数据库查询用户的方法。由于我们昨天下午实行了短信群发召回老用户的动作,导致大量用户同时访问编程导航并实行这个方法。由于涉及的数据库查询操作实行较慢,每个请求都需要等待数据库查询出效果后,才能响应数据,下一个请求才能再进来查询数据库,就导致大量 Tomcat 请求处置处罚线程阻塞在等待数据库查询上,再进一步导致新的请求要排队等待处置处罚。
真相明白了!
怎样解决?
其实我们这次碰到的问题就是典型的 “线上连接池爆满问题”,面试的时候也是经常问的。前面讲了怎么排查此类问题,那怎样解决这类问题呢?
首先碰到连接池爆满的环境,先保护现场,比如按照鱼皮上面的操作 dump 线程信息,然后赶紧重启服务或启动新的实例,让用户先能正常使用。再进行排查分析和优化。
怎样优化线上连接池爆满问题?首先肯定还是要优化造成请求阻塞的代码。比如数据库查询慢,我们就通过添加索引来提升查询速度。
还可以增长数据库连接池的巨细,在 Spring Boot 中,默认使用 HikariCP 作为数据源连接池,而 HikariCP 的 maximumPoolSize(最大连接池巨细)默认值只有 10,显然是不足以应对高并发场景的。可以把下面的配置数值调大一点:
spring:<br>datasource:<br> hikari:<br> maximum-pool-size: 50
复制代码
由于后端请求操作不止有查询数据库,所以 Tomcat 线程池的最大线程数和最小空闲线程数也可以按需调整,比如下列配置:
# 设置 Tomcat 最大线程数<br>server.tomcat.threads.max=300<br># 设置 Tomcat 最小空闲线程数<br>server.tomcat.threads.min-spare=20
复制代码
适当调大 Tomcat 的最大线程数,可以增长并发请求的处置处罚能力。适当调大 Tomcat 的最小空闲线程数,可以确保在并发高峰时候,Tomcat 能迅速响应新的请求,而不需要重新创建线程。
其实我们大多数环境下,线上服务器(容器)的内存利用率是不高的,所以可以根据实际的资源和并发环境,适本地改一改配置。记得多做做测试,由于过高的线程数可能导致线程调度开销增长,反而降低性能。
实际
好吧,以上只是我碰到此类问题的解决方案。但实际可能没那么理想,其实慢 SQL 这个问题我们在上一次故障时就已经定位到,而且在群内同步了。效果你猜怎么着,我们团队的开辟同学发了一堆监控的截图,但是没有一个人真正去解决了这个问题,这才导致了故障在多日之后重新上演!
一旦发现了问题,就必须要想到尽可能长久支持的解决方案,要不然这监控不是白做了?
为什么这次事故持续了这么久呢?也是由于我团队的开辟同学缺少线上问题处置处罚的经验,在那一通分析,效果忘了规复服务,过了半个小时用户还是无法访问,直到我去提醒。。。
所以这个时候就知道平常背的八股文有多紧张了吧?Tomcat 的连接器配置和性能优化也是一道经典的八股文,也是我们
面试鸭刷题神器
收录的题目。这些知识等到真出了线上问题时,都是用的上的。
吃一堑,长一智,颠末这次的事故,我信赖团队的同学又一次成长了。读者朋侪们,你们有劳绩没有嘞~
更多
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
正序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
发新帖
回复
农妇山泉一亩田
金牌会员
这个人很懒什么都没写!
楼主热帖
2022 春节抖音视频红包系统设计与实现 ...
OpenHarmony和HarmonyOS有什么区别?这 ...
XSS和CSRF漏洞
原型设计工具比较及实践--滴爱音乐 ...
厉害了,腾讯云云巢荣获信通院“云原生 ...
Kafka原理介绍+安装+基本操作(kafka o ...
SpringCloud Alibaba(八) - Durid,Spri ...
matplotlib画图基础知识
体系集成商已死,有事烧纸:浙江着名集 ...
Python工具箱系列(二十八)
标签云
挺好的
服务器
快速回复
返回顶部
返回列表