微服务之性能设计

104 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

性能设计

5.1 性能指标

  • 响应时间
  • 吞吐量。单位时间内的响应次数

在资源一定的情况下,性能优化的本质就是榨取资源,利用一切可利用的资源。CPU消耗少的时候,可以考虑增加线程榨取CPU的能力。

5.2 定位瓶颈点

  1. 压力测试
  2. 日志分析
  3. 监控工具
  • dstat是一个全能系统信息统计工具
  • sar是目前linux是最为全面的性能分析工具之一,可以查看文件读写情况、系统调用、磁盘IO、CPU、内存、进程活动等。
  • netstat 可以用来查看网络系统的状态信息
  • tcpdump可以用来查看网络连接的封包内容。

5.3 服务通信优化

5.3.1 同步转异步

可以利用ajax技术实现异步

5.3.2 阻塞转非阻塞

阻塞调用是指调用结果返回之前,当前线程被挂起,调用线程只有得到结果才会被返回。当异步调用的时候,如需返回结果,有如下三种方式:

  • 状态:通过变量实现,需要主线程不断轮询变量结果
  • 通知:通过消息的方式,比状态更高效。
  • 回调:本质上和通知类似,如ajax中的回调函数。

在Java中,如果需要返回结果可以采用future模式。因为是异步,调用future.get()的时候不一定能获得结果,如果还没有结果,则会被阻塞。Future是通过轮询或阻塞等待的方式,才能得到结果。更好的方式是通过callback,也就是执行结束的时候异步通知完成状态,然后去future中取执行结果。JDK中有future,但是不支持callback模式。还好Guava给我们提供了ListenableFuture。

5.3.3 序列化

从左往右分别是Avro、Thrift、Protobuf、gRPC、HTTP+json。可以看出前三个是一个级别的,相差不大。gRPC响应时间稍多一点,HTTP+json最慢。

5.4 通过消息中间件提升写性能

当规模不断变大后,数据库通常成为限制系统性能的主要因素。Mysql5.7单表字段个数为8,数据量为500万,写的吞吐量大约在1000TPS左右。而Kafka三节点集群的吞吐量能达到10万TPS。当然水平分表也可以提升吞吐量,但是水平分表带来的复杂度非常难解决。

5.5 通过缓存提升读性能

常见的缓存包括客户端缓存、HTTP缓存、操作系统缓存、CDN、代理缓存、数据库缓存等。

5.5.1 Guava Cache本地缓存

他比HashMap做缓存好的地方在于,他可以设置过期时间,回收空间。

  • maximumSize定义了缓存的容量大小,达到了容量大小就会进行LRU缓存回收
  • concurrencyLevel定义了Segment的数量,因为Guava Cache重写了ConcurrentHashMap,concurrencyLevel越大,并发能力越强
  • expireAfterWrite定义了缓存过期时间
  • refreshAfterWrite定义了缓存定时刷新时间
5.5.2 使用缓存常见问题
  1. 缓存数据需要设置合理的过期时间
  2. 为缓存设置回收策略

常见回收算法:FIFO(先进先出)、LRU(最近最少使用)、LFU(最不常用) 3. 先预热数据

5.6 数据库优化

数据库通常是各个系统中最难以扩展的点。一般有以下可以优化的地方:

  • 索引、冗余、批量写入
  • 减小锁粒度
  • 减少复杂查询
  • 适当转移事务处理
  • 提升硬件性能
  • 读写分离
  • 分库
  • 垂直分表
  • 水平分表
  • 根据业务情况选择其他数据库
5.6.1 优化慢sql
  1. 通过Explain 分析sql语句
  2. 通过慢日志分析瓶颈点

5.7 简化设计

架构是需要全方位考虑的,不可能完全从技术角度去解决问题。除了高性能,还需要考虑架构的复杂度、成本、代码可读性、维护性。

5.7.1 转移复杂度

如让我们设计一个抢红包的功能。抢红包的时候如果通过加锁的方式实现,那么数据库压力会很大。单纯从数据库优化的角度去实现,问题会变得越来越复杂。如果把这些抢红包的请求排序,串行修改数据库,那么数据库就不需要加锁了。

另外拆红包的时候的请求数量肯定比发红包的请求数量大,我们可以在发红包的时候就算好随机金额,拆的时候直接返回,这样并不会降低用户体验。

5.7.2 从业务角度优化

大家通常认为12306网站买票像秒杀,实际上比秒杀复杂的多。秒杀无论前端放出多少流量,后端可以根据库存去抛弃多余的量。12306网站并非如此,除了固定时间放出所有的票,其次用户买票的起始站点都不一样,排列组合有很多。

从业务角度可以这么优化:1.分时段放票。2.分地区放票。3.票的剩余数量不具体显示,只展示有票、无票等文字。4.最终采用排队的方式、满足最终一致性即可。