背景
最近遇到2个线上问题,记录一下,总结经验。
- 机器网络丢包
- 服务进程启动不了
机器网络丢包
有业务反馈线上服务有时候查询不出来结果,自己用业务反馈的请求,试了几次果真会出现查询不到的问题。
先说一下我们的整体架构,最上层是vip,负责负载均衡和机器谈话,中间是proxy,底层才是实际的存储服务节点。
排查过程:
- 绕过vip,直接访问proxy,发现有一个proxy每次查询都不能返回结果,必现。其他的proxy都很正常。
- 立即从vip摘除这个proxy,业务那边也反馈问题恢复了。
- 登录有问题的机器,tcpdump抓包,发现proxy请求另外一个服务A的时候,返回的数据包不对,出现丢包现象,下图1。
- 在正常的机器也用tcpdump抓包,对比结果,确认是返回数据出现丢包了。
- 登录服务A的机器准备在那边也抓包看看,发现出现tcp 200ms超时重传,下图2。
- 对比有问题机器和没问题机器的网络配置,发现mtu值不一样,有问题的机器是1600,正常机器是1500,服务A的机器mtu也是1600。
- 咨询了网络组同事,vip机器的mtu也是1500, 修复有问题机器的mtu为1500,问题修复。
图1:
我们可以看到3次握手成功以后,客户端36972端口发送了一个请求,服务端3028端口回报了,但是回报的seq号和前面不连续。
3次握手里面3028端口发送的seq是4072672142,但是看3028端口回的数据包的seq是4022679883,明显中间有丢包了。当然有可能是tcpdump抓包的时候丢的。
图2:
看图中的红框,出现了tcp经典的200ms重传。验证了图1所说的丢包问题。图1和图2,端口对不上的原因是中间还有一层vip服务。
最后解释一下原因:
mss值会取客户端和服务器之间的最小值,mtu为1600机器之间协商出来的mss大小1540,mtu1500和mtu1600机器协商是1440。
所以2台mtu1600之间传输大包的时候会在vip机器进行分片,分片之后的包没有4层头信息,所以没办法顺利转发,出现丢包现象。
不知道这算不算vip的问题,在tcp3次握手的时候,没有把本机的mtu值传给通信双方。
服务进程启动不了
某天组内同事服务的时候,发现有一台机器突然出现出core,其他机器正常,而且诡异的是出core是另外的服务,和本次升级服务,没有任务逻辑关系。
排查过程:
- 先让同事暂停操作,登录机器查看core文件没有发现有价值信息,supervised拉起服务以后马上又core。
- 尝试手动启动服务,发现问题了,进程资源受限,rocksdb后台线程创建不了。
- 使用ulimit -a命令看到当前账户的最大进程数1024,使用pstree命令查看当前账户的进程情况,刚好同事升级了另外服务,新版本会多创建几个线程,触发上限了,导致其他服务出现core,莫名躺枪。其他正常机器这个值都是4096。
- 使用root命令修改limits.conf里面的限制,切回到原来账户发现并不生效,在网上搜索到一篇文章,按照教程修改了一下,生效。重启服务解决问题