Web服务50X错误背后分析和思考

背景

最近,技术部门另外一个研发团队负责的某个站点,负载过高后,出现了502错误,但一直又排查不到原因,被拉进群一起分析,虽然最终故障被定案,回头稍微思考下其中的一些问题,还是有一些可以整理的地方。

实际上类似的问题,在之前我们自己团队负责的站点,在大促期间也有类似的问题出现,这块大同小异,大都都是phpfpm在处理业务过程中存在了某类型的资源阻塞引起的,比如常见低效sql、慢第三方调用、redis连接资源限制等。

问题插曲

问题团队研发和运维反馈的几个表象问题:mysql sleep过多、连接丢失、502错误

  1. /tmp/mysqld.sock: 业务代码应该有问题,连接的host为localhost或者Null,导致选择了默认mysql连接(如果用的mysqli扩展,查看php.ini配置应该有:mysqli.default_socket=/tmp/mysql.sock),但本地实际没有mysql服务;
  2. MySQL server has gone away:这块应该是new了一个Mysqli的DB实例,但中间等待了很久才去和Mysql服务器进行交互,导致超过了mysql的option的配置:MYSQLI_OPT_CONNECT_TIMEOUT设定的阈值,再去执行SQL就会出现这个问题;
  3. Lost connection to MySQL server:一开始mysql的连接还在,没有断开,但执行sql过程中断开了,在网络抖动或者读取数据超时情况下会出现
  4. dba反馈通过show processlist,查快到故障期间sleep线程很多:php框架一启动就创建了一个mysql连接,但这个连接有一直空置着,没有断开(其实很多框架,没有延迟连接创建,一开始就是创建mysql连接,如果存在负载很高,可能出现该php脚本处理时间很久,该段时间内一直无法将mysql连接资源释放,导致占用了一个服务端的连接线程资源)
  5. 问题资料:

问题分析

持续的高频fastcgi请求进来,每个phpfpm都开始处理,但存在竟态问题,比如redis、mysql、网络http服务调用等,当一部分phpfpm进程正常处理,另一部分phpfpm进程刚启动框架执行php过程,同时初始化了mysql实例,创建了mysql连接,然后就一直被阻塞。

将phpfpm看成一个整体,针对nginx发送过来的fastcgi请求,这个phpfpm整体会出现错误、异常、暂时无法处理、超时问题,对应500~504错误(以下大都基于高负载下的错误分析):

  1. 500:由于竟态问题的存在,存在fastcgi请求可能无法立马得到执行,因此无法立即响应处理mysql的查询或者写入请求,导致超过了mysql实例设定的timeout超时的阈值,抛出异常,fastcgi请求结束。(普通负载情况下,没有资源争用,异常会快速抛出,响应500错误;)
  2. 502:上述情况,php如果此时没有抛出异常,依旧还在阻塞等待,可能超过了php-fpm.conf中的request_terminate_timeout时间,被phpfpm进程强行中断,引起一个bad gateway错误(php脚本执行时间过久,被phpfpm进程强行中断,502网关超时)
  3. 503:表示服务临时不可用,服务器过载,但还在满载运行,nginx暂时无法收到phpfpm的处理结果(fastcgi_connect_timeout)
  4. 504:nginx的fastcgi模块fastcgi_read_timeout配置,它表示从FastCGI server获取数据的超时时间。如果超过这个配置客户端就是收到504网关超时的响应。

长远来看

1. 需要有一套APM系统

应用程序性能管理(APM)是对软件应用程序的性能和可用性的监视和管理,APM致力于检测和诊断复杂的应用程序性能问题,主要两块(用户所体验的性能、应用程序用于负载的计算资源)

  1. 需要有一套完善的监控体系,监控web应用的资源使用情况(涵盖db、es、soa、第三方推荐等服务)
    • 单位时间的执行效率,比如mysql连接了多久、一个http请求多久才完成(快速定位效率)
    • 单位时间内的单一资源调用情况,比如哪些http请求或者sql调用次数最多(快速定位是哪块是热点区域,缩小范围),sql相识度问题。
  2. 基于http请求,响应维度,分析慢应用
    • 单位时间qps呈现
    • 响应时间呈现
    • 链路内容(从请求到来,然后到结束,尽量了哪些任务处理)
  3. 当前机器的资源使用情况(cpu、io、mm、network)
    • 每台机器当前的cpu负载、io磁盘情况、网络
    • 网络监控,针对关键的业务依赖,节点情况
  4. 当前机器的配置情况
    • backlog大小
    • timeout设置等
  5. 服务配置标准化(nginx、php.ini、phpfpm.conf、、mysql option、os..)
  6. 应用程序拓扑

2. 架构升级

  1. 考虑低频业务+高频业务逐步解耦,单一架构拆分成SOA或者微服务架构;
  2. web服务的解决方案,考虑基于swoole过渡,或者直接基于性能更优的go或者java来解决;

APM相关参考

  1. https://www.apmdigest.com/apmacademy/5-capabilities-to-consider-when-selecting-an-application-performance-monitoring-solution
  2. https://en.wikipedia.org/wiki/Application_performance_management
  3. https://en.wikipedia.org/wiki/List_of_performance_analysis_tools