背景
最近,技术部门另外一个研发团队负责的某个站点,负载过高后,出现了502错误,但一直又排查不到原因,被拉进群一起分析,虽然最终故障被定案,回头稍微思考下其中的一些问题,还是有一些可以整理的地方。
实际上类似的问题,在之前我们自己团队负责的站点,在大促期间也有类似的问题出现,这块大同小异,大都都是phpfpm在处理业务过程中存在了某类型的资源阻塞引起的,比如常见低效sql、慢第三方调用、redis连接资源限制等。
问题插曲
问题团队研发和运维反馈的几个表象问题:mysql sleep过多、连接丢失、502错误
- /tmp/mysqld.sock: 业务代码应该有问题,连接的host为localhost或者Null,导致选择了默认mysql连接(如果用的mysqli扩展,查看php.ini配置应该有:mysqli.default_socket=/tmp/mysql.sock),但本地实际没有mysql服务;
- MySQL server has gone away:这块应该是new了一个Mysqli的DB实例,但中间等待了很久才去和Mysql服务器进行交互,导致超过了mysql的option的配置:MYSQLI_OPT_CONNECT_TIMEOUT设定的阈值,再去执行SQL就会出现这个问题;
- Lost connection to MySQL server:一开始mysql的连接还在,没有断开,但执行sql过程中断开了,在网络抖动或者读取数据超时情况下会出现
- dba反馈通过show processlist,查快到故障期间sleep线程很多:php框架一启动就创建了一个mysql连接,但这个连接有一直空置着,没有断开(其实很多框架,没有延迟连接创建,一开始就是创建mysql连接,如果存在负载很高,可能出现该php脚本处理时间很久,该段时间内一直无法将mysql连接资源释放,导致占用了一个服务端的连接线程资源)
- 问题资料:
问题分析
持续的高频fastcgi请求进来,每个phpfpm都开始处理,但存在竟态问题,比如redis、mysql、网络http服务调用等,当一部分phpfpm进程正常处理,另一部分phpfpm进程刚启动框架执行php过程,同时初始化了mysql实例,创建了mysql连接,然后就一直被阻塞。
将phpfpm看成一个整体,针对nginx发送过来的fastcgi请求,这个phpfpm整体会出现错误、异常、暂时无法处理、超时问题,对应500~504错误(以下大都基于高负载下的错误分析):
- 500:由于竟态问题的存在,存在fastcgi请求可能无法立马得到执行,因此无法立即响应处理mysql的查询或者写入请求,导致超过了mysql实例设定的timeout超时的阈值,抛出异常,fastcgi请求结束。(普通负载情况下,没有资源争用,异常会快速抛出,响应500错误;)
- 502:上述情况,php如果此时没有抛出异常,依旧还在阻塞等待,可能超过了php-fpm.conf中的
request_terminate_timeout
时间,被phpfpm进程强行中断,引起一个bad gateway错误(php脚本执行时间过久,被phpfpm进程强行中断,502网关超时) - 503:表示服务临时不可用,服务器过载,但还在满载运行,nginx暂时无法收到phpfpm的处理结果(
fastcgi_connect_timeout
) - 504:nginx的fastcgi模块
fastcgi_read_timeout
配置,它表示从FastCGI server获取数据的超时时间。如果超过这个配置客户端就是收到504网关超时的响应。
长远来看
1. 需要有一套APM系统
应用程序性能管理(APM)是对软件应用程序的性能和可用性的监视和管理,APM致力于检测和诊断复杂的应用程序性能问题,主要两块(用户所体验的性能、应用程序用于负载的计算资源)
- 需要有一套完善的监控体系,监控web应用的资源使用情况(涵盖db、es、soa、第三方推荐等服务)
- 单位时间的执行效率,比如mysql连接了多久、一个http请求多久才完成(快速定位效率)
- 单位时间内的单一资源调用情况,比如哪些http请求或者sql调用次数最多(快速定位是哪块是热点区域,缩小范围),sql相识度问题。
- 基于http请求,响应维度,分析慢应用
- 单位时间qps呈现
- 响应时间呈现
- 链路内容(从请求到来,然后到结束,尽量了哪些任务处理)
- 当前机器的资源使用情况(cpu、io、mm、network)
- 每台机器当前的cpu负载、io磁盘情况、网络
- 网络监控,针对关键的业务依赖,节点情况
- 当前机器的配置情况
- backlog大小
- timeout设置等
- 服务配置标准化(nginx、php.ini、phpfpm.conf、、mysql option、os..)
- 应用程序拓扑
2. 架构升级
- 考虑低频业务+高频业务逐步解耦,单一架构拆分成SOA或者微服务架构;
- web服务的解决方案,考虑基于swoole过渡,或者直接基于性能更优的go或者java来解决;