微服务高可用的设计手段
- 服务冗余,服务无状态化
- 负载均衡,ApI幂等设计
- 异步设计,添加超时机制
- 数据复制缓存分片,服务限流降级熔断
- 架构拆分 服务治理
服务分级:
按业务划分,主业务要保证可用性,其他业务要保证故障率不会影响主业务,其他系统故障要求不会出现长时间不可用(根据实际情况设定阈值);常见的划分方式是1-3级
无缝停止线上服务:
网关设置热切换开关
IPTABLES 设置只允许流量进入,不允许流出
高并发设计手段
软件性的优化目标
- 缩短相应时间
- 提高并发数,增加吞吐量
- 那系统处于合理的状态
随着用户量的增加,系统占用的资源也会增加,前期两者处于线性关系,达到一定程度后,随着用户量的增加,系统的吞吐量会趋于稳定,如果用户量继续增加,吞吐量会急剧下降,响应时间也会随之增加
空间换时间
若系统响应时间是瓶颈,可以使用缓存复用计算结果。降低时间开销,提高响应速度
时间换空间
若系统数据大小是瓶颈,如直播、下载等,可使用压缩算法,通过消耗时间计算来减小数据大小。此外还有APP全量更新和增量更新,看使用场景。
寻找系统瓶颈
分析系统业务流程,找到关键路径并优化,例如某几个接口承受了90%的QPS,则需要针对这些接口代码单独优化。
当然系统部分也不能忽视,不能出现个别接口拖垮整个服务性能。尤其消耗资源大的线程。
常用的优化手段
RPC接口统计
数据量载入统计
算法性能评估
非核心流程异步化
无数据关联逻辑并行执行
优化层次
架构层优化:关注系统控制,数据流程。思考如何拆分系统,如何使内部整体负载更加均衡,发挥硬件新人的优势,减少系统内部开销。
算法逻辑层优化:评估算法是否高效,是否存在优化空间,是否使用无锁结构数据?时间空间优化任务并行处理等等。是否需要空间换时间或者时间换空间。
代码层优化:关注代码细节,代码实现是否合理?对象创建是否合理?循环是否高效?缓存是否合理?计算结果是否可重用。
总结:从整体的细节,从全局到局部
- 循环遍历是否高效,循环中不要出现调用rpc接口,查询分布式缓存,执行数据库查询,一般可调用接口后再在循环中组装数据。
- 代码逻辑中避免生成过多无效对象,频繁输出日志时使用级别条件判断,避免new出无效的字符串。
- 集合容器,ArrayList, HashMap等容器,设定恰当的初始容量,减小扩容的代价
- 对数据对象是否合理重用,IPC查到的数据能复用必须复用。
- 根据数据访问特性,选择合适的数据结构,如:读多写少,CopyOnWriteArrayList。
- 字符串拼接使用StringBuilder。
- 正确初始化数据,全局共享数据,饿汉模式,访问前先初始化。
数据库层面代码优化
尽量使用小的数据结构,比如TinyInt代替枚举类型。
不使用,Select *,只查询必要的字段,避免浪费io内存CPU和网络带宽
建立适当的索引,分析字段的可选择性,索引的长度,长字符串使用前缀索引
字段尽量使用not null类型,马赛克处理让子弹需要额外的内存,并且很难优化查询
一切都为了降低服务器CPU使用率,IO流量,内存占用,网络消耗,响应时间
算法优化
保持接口,使用更高效的算法替换现有的
增量式算法,复用之前的计算结果,常见于报表中
并发与锁的优化,例如, 读多写少的业务场景,基于CAS的lock Free,比mutex性能更好
需要提高软件响应时间,可采取空间化时间的逻辑算法分配更多的内存空间,节省系统时间,使用缓存计算方式,降低时间开销,Cpu时间比内存容量更加昂贵
系统数据量巨大,可采取空间花时间的策略
网络传输时使用gzip算法,压缩数据节约空间
App请求数据时采用增量的方式,并缓存之前的数据。
逻辑中如无相互依赖,可以使用并行执行来节约时间
多流程中,次要流程可拆分出来异步执行,使用消息队列,与原核心流程结构,提高核心流程执行的稳定性,降低响应时间。
架构设计优化
分布式系统微服务化
分库分表,读写分离,数据分片
系统无状态化设计,动态水平弹性扩展
调用联络梳理,热点数据尽量靠近用户
分布式缓存Catch,多级分类缓存
系统容量规划
柔性可用,提前拒绝访问
如有错误,请不吝指正。谢谢
本文为个人学习笔记,转载请注明出处:
@ MaxZing
https://xzing.github.io/
https://www.jianshu.com/u/4915ed24d1e3