常见接口优化方法

接口优化

线上接口很慢,线上生产问题,我们绝对不能马虎放过抱着侥幸心理,必须要找到根本原因及时处理,防止下次留下更大的坑.大致思路要定位接口问题,然后具体问题具体分析,讨论不同解决方案.

定位问题

要快速定位接口哪一个环节比较慢,性能瓶颈在哪里,可以使用应用性能监控工具(APM)定位问题。常见工具: skywalking、pinpoint、cat、zipkin。

如果应用程序没有接入APM,可以在生产环境装一下arthas,利用trace接口方法和火焰图,大概能分析是那一块比较慢,定位能力稍微有点粗糙。亦可以利用程序中的告警日志定位问题。

解决办法

  • 扩容;哪里扛不住了哪里扩容,应用自动扩容、redis扩容、mysql在线扩容、kafka分区扩容等;
  • 应用重启;如果部分节点线程已经扛不住了,就需要重启释放对应资源;
  • 优化代码逻辑;上面两种是比较应急的做法,如果已经定位出来,就需要优化代码逻辑,完成后走hotfix灰度发版;

常见优化接口性能方案

数据库慢sql

如果是数据库sql慢,可以使用执行计划去分析一下,常见sql慢的几种情况:

  • 锁表;先把锁表的sqlkill一波,在分析具体原因;
  • 未加索引;添加索引,有可能会锁表,引发一系列问题,需要综合评估;
  • 索引失效;分析索引失效原因,如:索引列区分度(值大都相同)很低、索引列大量空值、对所索引列加方法转换等;
  • 小表驱动大表;在连接查询时尽量过滤数据,使用小表驱动大表,使笛卡尔积尽量小一些;
  • sql太复杂;join超过3张表或者子查询比较多,建议拆分为多个sql,接口间相互调用;比如先从某个著接口查询某个表数据,然后关联字段作为条件从另一个表查询,进行内存拼接;
  • 返回的数据量数据太多;当超过数据库一定限制的时候返回大量数据就会很慢,可以使用分页多批次完成,针对访问量不多的接口可使用多线程批量查询;
  • 单表数据量太大;(mysql超500w较慢)如果单表数据量较大,考虑在数据库设计做文章,如:分片分库、利用es存储等;
调用第三方接口慢
  • 设置合理的超时时间;调用第三方接口一定要设置合理的超时时间,在设置时一定要大于调用接口的平均相应时间;
  • 第三方接口大量超时;可以集成sentinel或hystrix限流熔断框架,防止第三方接口拖垮自己的接口(兜底逻辑);
  • 事务型操作根据实际情况决定是否采用补偿机制(本地消息表);比如新增、修改等操作要考虑对方接口是否支持幂等,防止超发;
  • 循环调用,改为单次批量调用,减少IO损耗;如:调用根据id查询单条数据的接口,可优化为批量查询接口;
  • 缓存查询结果;考虑当前查询结果是否能做缓存,如用户信息等短时间内不会变化的信息,根据业务形态来决定;
中间件慢
  • redis慢;是否有大key、热key,可接入hotkeys监控;针对热key可以使用本地缓存来抗,针对大key可以将其拆分,采用set结构的sismember等方法
  • kafka慢;生产端慢:可以使用堵塞队列接收,批量丢消息;消费端慢:消费端慢会造成消息积压,可以扩分区、增加消费节点、增加消费线程,用数据机构接受批量写入库;
程序逻辑慢
  • 非法校验逻辑前置;避免无用数据穿透小号系统资源,减少无效调用;
  • 循环调用改为单次批量调用;在查询数据库或调用第三方接口,能批量就批量,数据在内存组装处理;
  • 同步调用改为异步调用;在接口没有相互依赖的关系的时候可以将其优化为异步查询;
  • 非核心逻辑剥离;将接口的大事务拆分为小事务,一些非核心逻辑可以异步处理,可以使用mq异步解耦;
  • 线程池合理设置参数;不要使用JDK默认参数,如果在高并发的情况下容易OOM,线程池满了以后要重写拒绝策略,考虑告警加数据持久化处理;
  • 锁合理设置;本地读写锁设计使用不合理,要控制锁的力度,尽量小一些;分布式锁合理使用防止热key;
  • 优化GC参数;考虑GC是否频繁,调整GC算法,新生代老年代比例,根据长时间观察可以设置出来;
  • 只打印必要日志;当并发量比较高的时候打印日志也会损耗性能,所以日志应加上开关能不打就不打;
架构优化
  • 高并发读逻辑走redis,尽可能不要穿透到DB;redis查询不到也不要查DB,可通过定时任务,MQ写入redis。尽量不要把风险给DB,DB如果挂了整个应用就用不了了;
  • 设计写逻辑数据,尽量异步、批量处理、分库分表提升写入性能;
  • 接口接入限流熔断兜底;
  • 接入监控告警;error日志告警、接口慢查询或者不可用或限流熔断告警、DB告警、中间件告警、应用系统告警等;
  • 接口需要加动态配置开关;能够快速切断流量或降级某些非核心服务调用;
  • 设计程序自愈能力;比如如果数据有问题,用配置好的程序逻辑自动去修复;

相关推荐

  1. 常见接口优化方法

    2024-04-13 22:50:03       41 阅读
  2. tomcat 常见优化方案

    2024-04-13 22:50:03       33 阅读
  3. Redis常见异常及优化方案

    2024-04-13 22:50:03       27 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-13 22:50:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-13 22:50:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-13 22:50:03       82 阅读
  4. Python语言-面向对象

    2024-04-13 22:50:03       91 阅读

热门阅读

  1. Go语言并发编程(三)——初窥管道

    2024-04-13 22:50:03       43 阅读
  2. 【LeetCode热题100】45. 跳跃游戏 II(贪心)

    2024-04-13 22:50:03       41 阅读
  3. C# WPF故障记录

    2024-04-13 22:50:03       33 阅读
  4. 【00150】金融理论与实务-2023年4月自考真题

    2024-04-13 22:50:03       37 阅读
  5. 设计模式-里氏替换原则

    2024-04-13 22:50:03       41 阅读
  6. PyTorch 中的【高级索引】 或 【花式索引】

    2024-04-13 22:50:03       40 阅读
  7. 【图论】链式前向星实现图的BFS搜索

    2024-04-13 22:50:03       31 阅读
  8. Soulver v3.10.3.1 mac版 智能文本计算器 兼容 M1/M2/M3

    2024-04-13 22:50:03       58 阅读
  9. Ant Design Vue Table 自定义渲染与自定义单元格

    2024-04-13 22:50:03       42 阅读
  10. 【LeetCode刷题记录】76. 最小覆盖子串

    2024-04-13 22:50:03       35 阅读
  11. dfs板子

    dfs板子

    2024-04-13 22:50:03      34 阅读
  12. 蓝桥杯 2021 省 AB 2 洛谷P8755 负载均衡

    2024-04-13 22:50:03       35 阅读