背景描述
一个服务使用了 Prometheus
来进行数据采集,今天对这个项目的 metrics
使用进行了优化:将分散到各处的 metrics
放到同一个 go
文件,并将 metrics
的直接调用封装成了一个方法,这样看起来就整洁多了,当我高高兴兴地将代码打包成新版本,用几台机器先升上去之后,就在 grafana
看到了异常 span
数量急剧增多,这时候就慌了,不过幸亏平时回滚操作运用的很熟练,直接将所有机器一键回滚,万事大吉,然后就开始排查问题了。
排查思路
- 这个问题在第一次遇到的时候是修改了
分位数
统计之后发现的,当时猜测是依赖的包之间有冲突,因为之前输入了go get -u all
更新全部包,在删除本地下载的包之后重新编译,问题解决 - 这次发现问题依旧,使用上述方法之后发现不管用,猜测是方法调用导致写入太慢,下游的服务接收日志有延迟,导致大量日志被丢失,换成前几个版本的代码进行测试:问题依旧
- 在下游的服务中搜索有问题的日志的
traceID
,发现同一个traceID
的span
分布到好几个机器上,正常情况是相同的traceID
的span
会发送到同一台机器,猜测是往kafka
写入日志的时候出现了问题:客户端写入kafka
的时候有个balance
过程,代码中是自己手动实现了一个,猜测是这个出现了问题,换了包自带的balance()
之后问题依旧 - 接着查看
kafka-go
的源码,在相关的地方进行日志的打印(这个是真的难搞),发现当设置的balancer == nil
的时候,会默认调用轮询方法进行balance
,继续深入查看,新版本的kafka-go
(0.4.2)的newWriter()
有问题,漏掉了balancer
变量,导致配置里不管有没有赋值都为空,问题解决:直接使用Writer{}
进行初始化,但是又有个问题,如果配置中的brokers
值为多个,就会出现 bug,只有一个的时候就运行良好,其中排除了赋值可能出现的格式问题 - 最终的解决办法,回退到
0.3.6
版本,go mod
有个很坑的点:它会自己帮你升级到新的版本,所以要想保留在旧版本,那么就需要使用replace