记一次产线打印json导致的redis连接超时

服务上线后,频繁出现Redis连接超时,初步检查Redis服务器和业务服务未发现明显问题。深入分析发现,服务CPU使用率飙升、goroutines增加、GC时间增长,同时核心接口性能下降。通过火焰图定位到LogToJson函数占用大量CPU资源,原因是并发打印包含大缓存对象的debug日志,导致内存压力和GC延迟,从而影响到Redis连接。关闭debug日志输出后,问题得到解决。

服务在中午十一点上线后,服务每分钟发出三到四次redis连接超时告警。错误信息为:

Dial err:dial tcp: lookup xxxxx: i/o timeout

排查过程

先是检查redis机器的情况,redis写入并发数较大,缓存中保留了一小时大概400w条数据。redis服务器cpu和内存跟出问题前都差不多,非常接近,看不出什么问题。接下来看看服务的情况。

> LLEN xxxServ:price:change
(integer) 4100314
> ZCARD xxxServ:price:change:zSet
(integer) 963090

业务简单图

业务简单图

服务关键监控指标

  • cpu 从 12%飙升到150%
    cpu

  • 内存平稳,在 150M 上下
    内存

  • goroutines翻倍,从300到600
    goroutines

  • gc时间暴涨,从110us涨到7.5ms
    gc

  • redis 连接数达到了配置的上限20
    redis连接数

  • 文件描述符翻倍了,从100到250
    文件描述符

消息监控

  • 消息消费的qps
    mq-qps

  • 消息平均耗时
    mq耗时

核心接口监控

  • 核心接口qps减半,从200减少到100
    接口qps

  • 接口耗时涨到6倍,从250ms涨到1.5s
    接口耗时

火焰图

火焰图

定位原因

异常的指标有cpu使用率飙升,goroutines翻倍,gc时间暴涨,文件描述符翻倍,核心接口qps减半且耗时暴涨。再看看火焰图,LogToJson函数占用了83%的cpu。

出问题前上线了打印debug日志的代码,产线debug日志默认不会输出,但是debug日志入参是LogToJson的输出,输出的数据为全局的缓存数据,缓存数据比较大,且每次请求都打印一次。

并发数较高,大量打印json导致cpu过高,每次请求后这些大对象要被回收,从而导致gc时间过长,进而导致时不时出现redis io timeout 的错误。取消打印json的debug日志,问题就解决了。

经验教训

大对象不要在并发高场合打印。看到的问题可能只是现象,未必是根本原因,就像这次看起来是redis问题,但实际是打印json的问题。Code Review未必能细致到每个方法,有地方一不小心就踩坑了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值