假期突发404!性能优化是时候要反思一下( 二 )


文章图片
图1-3单车道限速100km/h
二、怎么做性能优化
1、系统性思考性能优化点
我们先来看下性能优化的落地过程 , 性能优化是由人来执行 , 然后服务于产品的 , 人和产品共同参与性能优化的落地 , 见图2-1 。

假期突发404!性能优化是时候要反思一下
文章图片
图2-1性能优化落地过程
从人维度出发 , 性能优化是属于技术团队的 , 技术团队包括开发、测试和运维 , 其中 , 运维负责提供一些监控数据 , 测试负责提供一些压测数据 , 开发基于压测、监控数据 , 明确具体的优化点以及优化手段;从产品维度出发 , 性能优化是业务功能的一部分 , 是为了满足某些业务场景 。 于是 , 在做性能优化时 , 一般会考虑以下几点:
本次性能优化的业务场景是什么 , 有哪些场景需要优化;这些场景的运维监控数据、测试压测数据是什么 , 要优化哪里;这些数据里面反映的系统瓶颈在哪里 , 如何去优化;重复(2)、(3)过程 , 直至满足优化目标 。结合性能优化的本质 , 整个优化过程其实就是:先从业务需求角度出发 , 思考待优化场景是否值得投入 , 比如:一个任务每次需要跑半小时 , 从技术层面 , 可以做下优化 , 但结合业务情况却发现 , 此任务的执行频次是每周一次 , 如果优化此场景需要耗费较大人力 , 那么 , 这个投入就是不值得的;
然后再从技术实现角度出发 , 不停地去思考怎么优化时间、怎么优化空间、怎么牺牲空间换时间、怎么牺牲时间换空间等问题 。
总之 , 我们在做性能优化时 , 需要以一个更全面的视角去看待它 , 避免进入头痛医头脚痛医脚的误区 。
2、常见性能优化方式
在实际业务场景中 , 一个外部请求进入系统后 , 会先后经历多个软硬件节点 , 所有节点的处理时间加起来才是用户请求的处理时间 , 如果其中任意一个节点性能有问题 , 系统整体的性能就会上不去 。
而且 , 由于节点自身差异性 , 其性能提升的方法也会不一样 , 但总体概括起来 , 可以分为两大类:提升单个请求处理效率;并行处理多个请求 。
1)提升单个请求处理效率
这种方式 , 简单来说 , 就是一个外部请求进来后 , 让其在尽可能短的时间内处理完成 。 常见的方法有以下几种:
①提升调用链上各节点的处理速度 。
从技术角度考虑:在数据库层面 , 可以考虑加索引、读写分离、分库分表等;在应用层层面 , 可以考虑加缓存(本地缓存 , 分布式缓存 , 或两者叠加)、复杂查询走ES索引;在代码编写时 , 可以考虑更高效的算法和数据结构 , 比如:读多写少用数组、写多读少用链表、取余采用位运算等 。 从业务角度考虑:尽量避免重复查询;对于一些查询类操作 , 尽可能采用批量查询;上游调用方尽可能使用更合适的下游接口 。 比如:下游服务方有分别返回A、B、AB的三类接口 , 如果上游使用方仅需要A信息 , 应使用A接口;如果同时需要AB信息 , 应使用AB接口 , 而不是依次调用A、B接口 , 再在内存中做聚合 。②请求内部做并行化处理 。
这种思想 , 就是将单个请求拆分为多个子请求 , 各子请求并行处理 , 最后对子请求结果合并后返回 。 在实践中 , 我们基于CompletableFuture实现了一套并行处理框架 , 并成功运用到了商品详情页加载场景中 。
③请求处理异步化 。
此思想 , 最典型的方法是采用消息队列 , 比如:下单操作时 , 除了扣减库存、生成订单外 , 还会给用户发送支付成功消息、赠送积分等后置操作 。
对于这些非核心的后置流程 , 可以采用消息队列做异步化处理 , 以此提升下单接口的性能 。 其他一些方法还有:在进程内 , 另开一个线程执行这些非核心流程;或者先将非核心操作数据暂存在某种介质(DB表、redis等)中 , 然后采用定时任务定期扫描并执行这些操作 。
2)并行处理多个请求
字面意思来看 , 就是当有多个外部请求进来时 , 可以让系统内部多个节点分别处理这些请求 , 或者节点内部做并行处理 。 比如:节点采用集群部署 , 并通过负载均衡策略 , 将用户请求分摊到不同的节点进行处理;节点内部采用线程池 , 通过另开线程来实现 。
三、我们是怎么做的
在具体讲述之前 , 先带大家一起熟悉下当时的业务场景:用户首先访问直播商品详情页 , 然后购买此商品 , 紧接着再次访问详情页面时 , 会出现直播间入口 , 在进入直播间之前 , 会做一次权限校验 , 校验通过后 , 方才可以进入直播间与讲师进行互动 。 详细的流程可见图3-1 。