cpu负载高故障排查实战-网关故障导致业务请求堆积

原创 吴就业 159 0 2024-02-06

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/4c84476ba03b4fa6bdb4246aba50773f

作者:吴就业
链接:https://wujiuye.com/article/4c84476ba03b4fa6bdb4246aba50773f
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

故障现象

收到相关告警,从监控指标看,http请求成功率下降。

http请求成功率下降

网关是虚拟机部署,排查其中一台网关机器,发现CPU基本消耗完。

CPU基本消耗完

另外发现,该虚拟机实例的nginx句柄数被消耗完。

重启nginx和网关后,该机器CPU恢复正常。

安装go相关工具,排查到是非对称加密占用了大量CPU资源。

非对称加密占用了大量CPU资源

但这期间,CPU又继续飙升。由于nginx到网关是使用https通讯,紧急启用nginx到接入器连接复用,CPU占用率恢复正常。

CPU占用率恢复正常

总结

架构如下,业务app发起https请求,请求先到cdn,cdn通过https回源给nginx,nginx也通过https回源给网关。这里nginx其实是多余的,因为历史问题还要保留,而网关则是七层流量代理。

架构图

当请求增加的时候,nginx会使用更多的连接进行转发到网关的操作,因为go标准库实现tls握手性能比较差,在一台8核的机器,只能到达2000这个量级,所以当到达某个临界点的时候,握手占用CPU过高,反过头来影响正常的业务请求,导致了业务请求处理变得十分慢(故障时,在nginx的日志上可以找到很多十几秒才返回的请求,但是接入器的逻辑是5s就超时返回,明显是受到CPU的影响),从而客户端不断重试,进一步导致需要更多连接转发到接入器,同时nginx也收到更多来自CDN的连接,最终导致了雪崩(句柄数被用完,CPU占用率一直很高,请求没办法正常处理)

改进措施

  1. 网关支持对非对称加密的限流
  2. 消除技术债,移除nginx
#中间件

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

全球化的IM产品技术架构调研

主要调研学习Slack和WhatsApp这两个产品的全球化架构,单数据中心或是多数据中心,怎样做架构设计,能够解决异地多活和延迟问题。

Go语言内存泄漏问题排查实战-记一次线上容器重启问题排查

代码中,与tls有关的地方就是发送https请求从s3下载文件,所以检查下载文件调用链路上是否存在可疑的内存泄漏,发现如下疑点。统计了访问日记,发现确实经常出现响应403。所以问题就清晰了,由于403是有body的,没有close响应的body导致的内存泄漏。

Java内存GC故障问题排查实战-推送系统频繁GC告警问题排查

记录一次工作中实战的Java内存泄漏问题排查,Pod重启后无法查看现场,但通过gc日记可以确认存在内存泄露,并通过运行一段时间发现有个Java类的实例数量非常高。

Go写的文件上传中间件内存泄露问题排查

用go开发的一个文件上传中间件,由于依赖了ceph这个c库,早期通过pprof排查,怀疑内存泄露在c层,而项目依赖ceph,于是就怀疑是ceph的问题。但通过使用jemalloc排查后,并未发现ceph有什么异常。最后使用最笨的方法,定位到github.com/chai2010/webp库存在内存泄露bug。

组件和框架初始化顺序背后隐藏的线上故障

一个微服务可能引入非常多的SDK,例如消息中间件kafka的组件、RPC框架dubbo、定时任务调度平台xxl-job的组件,以及提供web服务的jetty/tomcat等。这些组件的初始化是不确定的,那么假如启动初始化过程中,其中某个组件初始化失败了,会发生什么?

S3文件上传403问题排查

业务反馈有个iOS设备上传出现403问题,打点日记只能看到403,没有详细的错误信息。开了s3的日记后,也只是看到403 AccessDenied。