问题背景
我们是游戏研发公司, 需要和不同的发行商合作运营
而且很多发行商要求使用自己的服务器(毕竟自己控制更可靠)
所以就出现了这么一种情况
业务不大, 但是不同云厂和区域的服务器不少.
并且我们使用 SaltStack 来管理主机的信息.
从主机的注册到作业的执行, 基本上是这样的
1 | salt-master<----->nginx-stream<----->salt-minion |
这里为啥使用 nginx-stream, 而不是 salt-syndic
主要是因为简单, 稳定, 而且 salt-syndic 无法针对单个 minion 下发 job
把 nginx 部署在docker swarm
上
有一个区域就添加一个docker worker
, 然后自动的部署上去了
大概的思路是这样的, 然而在部署好了后使用salt 'h72g9g19vr391.qcloud.hk' test.ping
有时正常, 有时却返回超时
排查思路
saltstack 排查
先打开 salt-master 日志的 debug 模式
1 | 2020-05-29 16:29:01,272 Sending event: tag = 20200529162901272112; data = {'minions': ['h72g9g19vr391.qcloud.hk'], '_stamp': '2020-05-29T08:29:01.272678'} |
从上面 saltstack 的日志来看, master 已经将 job 信息 publish 到了 zeromq 里面了
然而, 在 salt-minion 上并没有看到相关的日志信息.
也就是说 salt-minion 完全没有收到 salt-master 的 publish 的信息.
salt-master 已经发了, 但是 salt-minion 没有收到
那就说明数据丢在了 nginx 的转发上面
nginx 排查
从上面的抓包数据可以看到, 在第 8 秒时, “客户端”主动发起来断开的数据包(FIN)
到底是 salt-minion 发出的 FIN, 还是 nginx 发出的 FIN
猜测应该是 nginx 发出的 FIN, 理由如下
- 直连的 salt-minion 没有问题.
- salt-minion 的 debug 日志里没有任何信息
- 对比了正常请求的 salt-master 的 debug 日志, 没有任何关于客户端的错误
先看看 nginx 的配置
1 | stream { |
从配置上来看, 问题出在了proxy_timeout 5s;
, 查下文档.
1 | Syntax: proxy_timeout timeout; |
在客户端和代理服务器上设置读取或写入的超时时间, 如果没有数据传输, 则连接断开.
把这个配置文件去掉后, 就都正常了.
复盘总结
- 排查的思路很重要, 一直以为是 saltstack 出了问题, 不停的在查两边的日志.
- 配置文件是完全复制之前的, 所以出了问题才发现.