searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

服务器带宽瓶颈导致的巨大http请求拥堵

2022-12-10 08:40:56
75
0

现象

小程序调这个接口感觉延时明显 /h5/v1/share/trip

小程序统计的延时见截图 ,时间范围是一天内平均:

 

图1

 

后端小程序api服务的日志切面统计的耗时:

图2

 

后端metrix收集的服务监控
http_server_requests_seconds_sum/http_server_requests_seconds_count 与 http_server_requests_seconds_max:

即接口平均耗时和最大耗时

图3

 

抽一个traceId去看调用链:

图4

 

图5

 

排查过程

 

图1小程序给的统计来看,share trip接口的平均耗时非常突出。

图2日志切面统计的耗时,绝大多数调用都在200ms内,日志切面覆盖的范围包括controller层以及api服务调用其他各服务的耗时。说明其他服务没问题,业务处理的代码也没问题。

图3是spring boot自带的统计上报,不太确定其范围,不过可以看出服务内的耗时已经很高。

图4的调用链看,在小程序api内耗时很高,而且是其他服务都早已返回。

图5的机器jvm的metaspace有点高。

另外,查看kibana上的日志发现,慢调用的trip接口返回的报文非常大。约200KB以上。

 

有一些疑点:

如果是http线程阻塞,应该所有的接口慢的机会均等。

部署机器内存和CPU不高。jvm的metaspace有点高。metaspace配置过低,max只有128M。

报文大就慢,可能是序列化慢,或者是网络拥堵。

 

初步怀疑metaspace问题,本着先抢通后抢修原则,且网络出事概率远低于其他可能,先加metaspace,扩容机器。

原来小程序api有2个机器,配置都是4核16G,启动参数中jvm堆内存是4G,metaspace是128M。

先加了2台机器8核16G,然后老机器未调整配置,启动参数改为堆内存8G,metaspace 1G。两个操作大概间隔了半个小时。观察发现加机器效果比较明显,老机器调参数没有明显再改善了。

好了,充钱变强之后暂时扛住了,然后我们开始定位问题,

为了避免以后再次踩坑。

而且奇怪的是,生产上还是有零星的慢调用,10s以上的那种。

 

首先尝试postman直接调用服务,大报文的情况,看能否复现问题。

运气不错,复现了,猜想是对的,跟大报文直接相关。

到机器上用arthas跟踪线程,从spring mvc的 dopost接口开始,滤除cost>3s的,逐层下钻。

 

中途遇到json序列化方法慢(16行附近),以为找到了问题,后面逐渐深入,发现是IO,最后不得不怀疑网络。

 

尝试绕过域名,直接postman调阿里云服务器,发现直连机器调用非常快,持续稳定在300ms左右。

并且在测试环境上稳定复现。用jmeter尝试多次调用,依然稳定复现,在同时并发调用下,走域名经过负载均衡,100%慢。

 

好了,现在可以怀疑是网络问题了,而且我们有证据。

得出初步结论:小程序4台部署机,其中2台的公网带宽只有1M。

 

马上冲钱,带宽加到10M,马上稳了。

从下图的监控看,share trip接口几乎一瞬间恢复宁静。

所以当时新加两台机器之所以管用,是因为加的机器是10M带宽的,且分摊走了流量。

 

结论

 

真的是网络问题。

服务经过负载均衡走到外网,需要买带宽。就是下图箭头标注出的这个。

如何解决

 

1.开源

首先检查一下机器的带宽配置,如果是1M的就果断加。

如果到了限制带宽,所有接口都会不同程度变慢。

查看节点流量监控可以看当前节点的公网出流量。

 

2.节流

可以在服务上配置压缩http返回体,也试了一下可以解决问题。

server.compression.enabled=true

它的副作用是耗CPU,如果服务本身CPU很闲的话(大多数是的),就可以尽情压榨它。

它还有一些别的参数,比如超过多少字节才压缩之类的,没怎么研究就不写在这里了。

 

 

注意:

  • 方案2是可选的。
  • 云上服务之间的调用是走内网的,不需要这个带宽。所以只有通过公网暴露出去的服务才要关注
  • 无论如何,网络都是最后怀疑的对象,不要动摇这个原则
0条评论
0 / 1000
肖****睿
13文章数
0粉丝数
肖****睿
13 文章 | 0 粉丝
原创

服务器带宽瓶颈导致的巨大http请求拥堵

2022-12-10 08:40:56
75
0

现象

小程序调这个接口感觉延时明显 /h5/v1/share/trip

小程序统计的延时见截图 ,时间范围是一天内平均:

 

图1

 

后端小程序api服务的日志切面统计的耗时:

图2

 

后端metrix收集的服务监控
http_server_requests_seconds_sum/http_server_requests_seconds_count 与 http_server_requests_seconds_max:

即接口平均耗时和最大耗时

图3

 

抽一个traceId去看调用链:

图4

 

图5

 

排查过程

 

图1小程序给的统计来看,share trip接口的平均耗时非常突出。

图2日志切面统计的耗时,绝大多数调用都在200ms内,日志切面覆盖的范围包括controller层以及api服务调用其他各服务的耗时。说明其他服务没问题,业务处理的代码也没问题。

图3是spring boot自带的统计上报,不太确定其范围,不过可以看出服务内的耗时已经很高。

图4的调用链看,在小程序api内耗时很高,而且是其他服务都早已返回。

图5的机器jvm的metaspace有点高。

另外,查看kibana上的日志发现,慢调用的trip接口返回的报文非常大。约200KB以上。

 

有一些疑点:

如果是http线程阻塞,应该所有的接口慢的机会均等。

部署机器内存和CPU不高。jvm的metaspace有点高。metaspace配置过低,max只有128M。

报文大就慢,可能是序列化慢,或者是网络拥堵。

 

初步怀疑metaspace问题,本着先抢通后抢修原则,且网络出事概率远低于其他可能,先加metaspace,扩容机器。

原来小程序api有2个机器,配置都是4核16G,启动参数中jvm堆内存是4G,metaspace是128M。

先加了2台机器8核16G,然后老机器未调整配置,启动参数改为堆内存8G,metaspace 1G。两个操作大概间隔了半个小时。观察发现加机器效果比较明显,老机器调参数没有明显再改善了。

好了,充钱变强之后暂时扛住了,然后我们开始定位问题,

为了避免以后再次踩坑。

而且奇怪的是,生产上还是有零星的慢调用,10s以上的那种。

 

首先尝试postman直接调用服务,大报文的情况,看能否复现问题。

运气不错,复现了,猜想是对的,跟大报文直接相关。

到机器上用arthas跟踪线程,从spring mvc的 dopost接口开始,滤除cost>3s的,逐层下钻。

 

中途遇到json序列化方法慢(16行附近),以为找到了问题,后面逐渐深入,发现是IO,最后不得不怀疑网络。

 

尝试绕过域名,直接postman调阿里云服务器,发现直连机器调用非常快,持续稳定在300ms左右。

并且在测试环境上稳定复现。用jmeter尝试多次调用,依然稳定复现,在同时并发调用下,走域名经过负载均衡,100%慢。

 

好了,现在可以怀疑是网络问题了,而且我们有证据。

得出初步结论:小程序4台部署机,其中2台的公网带宽只有1M。

 

马上冲钱,带宽加到10M,马上稳了。

从下图的监控看,share trip接口几乎一瞬间恢复宁静。

所以当时新加两台机器之所以管用,是因为加的机器是10M带宽的,且分摊走了流量。

 

结论

 

真的是网络问题。

服务经过负载均衡走到外网,需要买带宽。就是下图箭头标注出的这个。

如何解决

 

1.开源

首先检查一下机器的带宽配置,如果是1M的就果断加。

如果到了限制带宽,所有接口都会不同程度变慢。

查看节点流量监控可以看当前节点的公网出流量。

 

2.节流

可以在服务上配置压缩http返回体,也试了一下可以解决问题。

server.compression.enabled=true

它的副作用是耗CPU,如果服务本身CPU很闲的话(大多数是的),就可以尽情压榨它。

它还有一些别的参数,比如超过多少字节才压缩之类的,没怎么研究就不写在这里了。

 

 

注意:

  • 方案2是可选的。
  • 云上服务之间的调用是走内网的,不需要这个带宽。所以只有通过公网暴露出去的服务才要关注
  • 无论如何,网络都是最后怀疑的对象,不要动摇这个原则
文章来自个人专栏
线上问题排查
4 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0