Java生产问题收集

查询数据过大拖垮核心节点并导致全渠道交易失败

【问题场景】

页面和 API 网关共用同一个关键节点,该关键节点用于查询 DB,结果页面进行大数据量的查询导出,导致该关键节点内存不足崩溃,并导致页面和 API 网关都不能接入,系统所有渠道停止对外服务。

【经验教训】

  1. 关键节点。

  2. 所有的操作都要有数据量限制,如限制只能查询六个月的数据,或者最多返回 5000 条数据。

  3. 不同的接入渠道使用不同的关键节点,而且分布在不同的单板上。

消息消费 Sleep 导致消息积压

【问题场景】

某服务先发消息后写库,测试时发现消费者在消费消息时,某些写库操作尚未完成导致查不到数据,开发同事简单的在消费消息时先 Sleep 1 秒,测试环境功能测试没有问题,但上生产后发现消息消费缓慢,造成大量消息积压。

【经验教训】

  1. 程序应该理顺逻辑,而不是加一些奇奇怪怪的代码让功能看起来正确;
  2. 上线前要做必要的压测
  3. 做好代码评审

浮点数使用 Double 造成精度误差

【问题场景】

有三个比例保存在 List 中,值为 0.1、0.2、0.7,有同事使用 Double 类型保存数字,并通过判断这三个比例之和是不是 1.0 来做一些事情。但因为查询的顺序不一定,所以这三个数字在 List 中的顺序是不确定的,

double a = 0.1 + 0.2 + 0.7; // a = 1.0
double b = 0.7 + 0.2 + 0.1; // a = 0.9999999999999999

【经验教训】

浮点数计算使用 BigDecimal

日志中打印大对象导致OOM

不规范日志打印,将音频流打印到日志中,导致 Full GC 后老年代内存使用率仍然超过 80%,并导致 OOM。

写代码时一定要注意,只打印必要信息,不要打印大对象,尤其是二进制流。

正则表达式回溯导致 CPU 飙升

有个功能是通过正则表达式过滤日志中到敏感信息,主要是由于正则表达式回溯引起但,参考文章《一个由正则表达式引发的血案》