前言
公司业务处于稳定发展期,前期系统快速迭代,业务快速支持,堆积了很多技术债务,其中,系统的性能就是关键的一部分,随着业务代码的堆叠,性能逐步裂化,需要快速优化,这里主要对接口SLA性能的稳定性保证做一个梳理。
影响SLA的关键点
影响服务/接口的SLA的关键点主要在:
- 依赖RPC下游服务:
主要是下游的服务,微服务化后,单一服务职责、边界更清晰,需要资源或者数据,会直接从下游获取,比如依赖订单信息,调用订单服务;依赖用户信息,调用用户服务。下游的服务SLA是否裂化,也是影响自身服务SLA的关键点。 - 内部自身代码设计、逻辑:
a. 线程池: 参数、队列等 b. 调用下游RPC合理性: 编排是否合理, 有没有重复PRC调用 对下游超时之后的处理 c. 代码是否高效: 循环、序列化、锁 、算法等 - 系统指标:
GC、磁盘、load、网络等
接口示意图
如下图: 一个普通服务的接口内部逻辑如下: 该接口提供上游查询服务功能,服务本身依赖下游商品、订单、营销、用户、规则、展销服务的接口,并且这些服务之间互相有依赖,不能同时并行调用(比如调用展示服务的接口,需要商品、订单、营销服务的数据),这样多个服务,其实变为三个阶段,基本阶段之间是串行调用。 拿到依赖数据之后,做相应逻辑处理,这块儿就是服务的自身代码逻辑。 最终将所有数据 + 业务逻辑处理后,组装返回给上游。
优化策略
1. 依赖RPC下游服务: 这个其实没有什么好的办法,需要根据下游的RPC服务的SLA来定。如果下游超过了它们的SLA,需要推动下游去进行优化,这个一般上游没有办法控制。 如果需要控制,保证自己SLA不裂化,只能根据重要性对下游进行降级,比如下游超时后,直接返回空数据。 2. 内部自身代码设计、逻辑 a.线程池: 这里主要关注线程池的配置,高流量情况下线程池出现大量等待情况,会导致该线程池的处理结果不能返回。 过多的线程池是否可以合并,有些服务线程池可能会很多,这里好处是可以不同业务逻辑做一定隔离,坏处就是导致线程资源的膨胀、浪费,进而影响系统的容量,导致过多的ygc,进而影响服务执行时间,SLA。 b.调用下游RPC合理性: 编排合理性:目前RPC的调用顺序是合理的,有没有不需要串行的调用,进行了串行调用? 重复RPC:这个比较好理解,循环对下游的调用,要求下游提供批量接口进行合并调用。笔者之前优化过的代码有过拿出一批id,对数据库循环获取每条的数据。 下游超时:下游的超时时间必须做好严格的控制和设计,因为一旦下游超时,而服务设置的超时间较久的话,会直接拖垮自身服务,导致自身服务性能急剧下降。 c.代码是否高效: 循环:有没有无效的循环,是否可以用空间换取一定时间?比如冒泡排序的算法,其中一种算法就是存储一个标记位,让整个算法的复杂度降低。 序列化:序列化是否高效,这个也是非常关键的一环,选用合适的高效的序列化算法,节省的时间也是可观的。可看笔者之前的文章:点击这里 锁 :并发过程中锁的使用,有没有热锁,如果解开。有没有更好的实现方式? 锁粒度是否过细了?笔者之前优化过循环过程中加锁,其实可以将锁放在循环外。 算法:从自身业务逻辑特性考虑,是否有更好的顺序、逻辑处理。 3. 系统指标: 这里提到的gc、load、磁盘、网络,需要其他运维同学一起关注。
总结:
常见的优化策略和优化工具结合,才能达到保证自己的系统的SLA的目的。除此之外,还需要做一些定期的压测和演练,保证自己的系统不裂化。
|