记一个API20倍性能优化

同步

我接手的其中一个项目中,有一个核心的业务是提供用户信息同步功能。这个同步API后头还连着其他关联业务,比如创建账号,查询信息,下载信息等。

历史问题

这个业务历史悠久,主要是为各产品部门调用该接口,上传用户信息, 提供线上服务做支撑。而这个同步接口,从上线到目前为止,已经优化了35个版本!目前性能为: 同步26000个用户信息,耗时45分钟左右。调用方也是经常用到心里发毛。所以现在交到我手上了。

动手

  • 了解需求 沟通, 游走各个关口。 读源码, 画流程图。
  • 调查问题瓶颈, 监控系统(prometheus)分析响应时间,耗时。 断点设置,日志,数据库统计耗时。
  • 开会讨论, 讨论痛点,下决心,职责划分,争论方案。
  • 开会讨论, 下决心, 职责划分,争论方案。
  • 开会讨论, 定方案, 开发周期,拉一个架构师和技术副总监一起过。
  • 边写测试单例,边构思。
  • 开会, 了解进度,方案可行性。
  • 完成本地批量测试, 模拟客户端访问。引入 golang 自带的 pprof 工具。
  • 重构数据库, 优化表结构,加索引等。
  • 重构分支流程, 码代码。
  • 开发集中。中间又出几个问题,又来了几次会议,不断切遇到的问题,以及之前问题的盲点,逐一条出解决方案。
  • 合并
  • 单元测试
  • 压测

优化点

  • 数据库表调整,添加索引。
  • 同步阶段,断开一个占用耗时将近1/3的外部接口,将外部接口交互流程滞后执行。
  • 批量处理,单个用户的信息,批次查询,然后本地计算,最后批量入库。
  • 合理地利用goroutine。
  • 等。

效果

部署到测试环境, 26000个用户月50s内同步完。优化后版本同步速度获得约20倍质的提升!暂时做个笔记吧。这个版本部分工作,是在“山竹”台风到达那天完成的。还好人没事,凌晨从公司回到了家。
线上的性能,待我上线确认之后再更新。

小结

遇到问题,找到病因,对症下药,合理使用开源工具(比如 prometheus 和 pprof 在分析瓶颈中发挥重要的作用)。每一个解决掉的问题,都是我下一步前进的动力。