大佬有什么好用的顺手的问题排查工具都可以推荐,python 和 go 中不知道有没有类似 JAVA 的 GC 这种的排查工具?
公司最近业务系统使用中反馈慢,APP 项目有时候打开页面老是转圈(周末高峰期会出现)。 后端:Tornado(python)+nginx+mysql 前端:ios 原生+h5 。 服务器: 阿里云 8 核 32G 部署:单进程+端口号 起了 6 个进程 upstream 负载。 1.后端日志没有发现 error 信息,请求正常。 2.nginx 日志在同一时间段会重复出现 recv() failed (104: Connection reset by peer) 3.top 查看 cpu 、内存、服务器负载都正常。nginx 加了$request_time 显示请求时间。 4.而且把出问题那一段时间的 nginx 日志找出来,都是同一个端口报的,而且前面 1-2 分钟之内有几个接口返回 30s 。 4.百度 nginx 的错误根据指导方案:nginx 连接数调高、buffer 缓存调大、keepalive 加了长连接。 5.自己这边又增加服务进程数(由原来 6-10 ,又增加了两台服务器负载一共 20 个进程)、慢接口进行读写分离优化。 6.最后增加自动访问接口提醒功能,超时提醒。[前端]优化了超时时间 30s 改 10s 、优化了页面快速切换的重复请求。 最后周末没有再出现转圈问题,整个一套组合拳打下来具体也不清楚是那里给治好了。 后来我仔细分析了一下: 1.数据库连接瓶颈,Tornado 每起动一个进程+端口服务会初始化一个数据库连接,所有的请求都用一个数据库连接。 2.python 单进程-单线程模式,堵塞造成的。 一个请求过来,单线程去处理,然后这个线程就去使用数据库连接,遇到一些统计查询慢 SQL ,很长时间返回造成这个单进程端口下的堵塞( nginx 报的那个问题)。
![]() | 1 xiaoqiao24 2022-09-30 10:51:11 +08:00 我感觉像是查询 mysql 拥堵导致。数据库应该使用连接池,避免慢 sql 卡主线程 还有就是前台应该减少重复的请求,类似埋点类的接口应该单独剥离成微服务处理 |
![]() | 2 zhuangzhuang1988 2022-09-30 14:00:05 +08:00 |
![]() | 3 zhuangzhuang1988 span class="ago" title="2022-09-30 14:04:32 +08:00">2022-09-30 14:04:32 +08:00 这个里面也有很多推荐调试方法 https://pythonhunter.org/episodes/2 |
4 yagamil 2022-09-30 14:35:04 +08:00 每个时间点打时间戳,是 mysql 部分,还是 nginx ,还是连接部分。还是你在处理数据的速度比较慢。 |
5 lookStupiToForce 2022-09-30 14:48:37 +08:00 |
![]() | 6 ipwx 2022-09-30 15:13:16 +08:00 看你的问题描述总觉得你司架构有问题。 首先,Python Tornado 算是很老的技术了。而且当年 Tornado 的特色在于老语法下的异步网络编程。可是按你的描述,怎么 Tornado 变成了单线程阻塞模式了。。 在这个奇怪的错误架构下,你的问题我感觉都没法搞定。 |
![]() | 7 slowgen 2022-09-30 17:33:17 +08:00 连 mysql 用的什么库? 在异步 IO 里面用同步阻塞的库是个比较常见的错误用法,表现就是一处阻塞处处阻塞,如果内部各种 IO 操作一个地方用了同步阻塞的就会出现这种问题。 平时做好异常监控,比如接入 Sentry ,提早发现问题吧。 |
8 longmeier90 OP @ipwx 是的,由于历史原因一句话也说不清楚,咱只聊技术。 |
9 chenqh 2022-09-30 20:03:56 +08:00 如果我用 tornado 的话,估计也是这么搞,后来我大致想了两个办法 1. 把慢接口分离出来,加 nginx 里面加慢接口的路由,重新起一套 tornado 进程来处理,这个改动小一点 2. 加异步任务使用 celery 或者 rq,分成两个接口来搞,但是这个样子的话改动太大 你用 py 后台技术栈和我差不多,supervisor+tornado+nginx+mysql, python 的 mysql 库使用同步库,用 tornado 的目的 1. 是为了 class 2. 是为了异步 http 请求 |
10 chenqh 2022-09-30 20:07:21 +08:00 你这个问题多加进程就是能搞定, 和你解释下为什么, 你一开始假如是 6 个 tornado 进程, 那假设有 6 个 30S 的请求进来,那么 6 个进程就全 busy 了,这个时候进来第七个请求的话,就没有 tornado 进程可以处理了,这第七个请求就直接等了 30S 超时了, 这是我的看法,也不一定对 |
![]() | 11 encro 2022-09-30 20:10:06 +08:00 1,端口回收问题,连接数超过了,服务器自动断开,如果是阿里云默认有五千个限制。需要用链接池。 2,数据库超时堵塞,既然你发现有 30 的了,那么看下是那些 URL ,开启数据库和 web 慢日志(PHP 自带 fpm 慢日志,python 等可以自己实现满日志),定位不是分分秒秒的事情。 |
![]() | 12 akira 2022-09-30 20:37:49 +08:00 就这么点量,横向扩展大概率就能解决了。服务器没 cpu 内存压力的话,多加几个进程啊,要那么高配置的服务器 又不跑满,就是浪费钱 |
13 chenqh 2022-09-30 20:38:54 +08:00 我想了下,那两个方案都不靠谱,直接加进程就好了,以 tornado 一个进程 100M 来算,10G 内存都可以开 100 个进程,唯一要担心的就是 mysql 的连接数了 |
![]() | 14 test523 2022-09-30 21:24:20 +08:00 nginx 日志分析下接口响应时间,把比较久的拿出来单个接口分析,慢慢排查 |
15 oudemen 2022-09-30 22:08:35 +08:00 可以尝试一些 apm 工具,比如 newrelic ,基本所有语言都支持了 |
16 longmeier90 OP @chenqh 是的,现在起了很多端口一起负载。 |