基础
性能指标
- TPS : 每秒能达到的请求数,随着压力上涨成抛物线
- QPS
- RPS
- 95th & 99th
- 95%的请求所用时间
- 99%的请求所用时间
pinpoint
资料
安装与配置
New Relic
资料
Jprofiler
资料
实践
Tomcat Thread pool
- maxThreads : SERVER_TOMCAT_MAXTHREADS
- 最大线程池的数量
- tomcat默认200
- thread pool与cpu的关系
- 与core成正比
- 对于cpu密集型服务,thread pool可以设小,减少cpu切换的性能消耗
- gcp环境在1 core的服务处理最简单业务时,thread pool设置成2,20,200,1000,tpc都是900
- 对于io密集型服务,thread pool需要增大
- io等待越长,thread pool应该越大,从而充分利用cpu
- 但是也要看瓶颈在哪里,下游慢,你处理的再快也没有用,所以thread pool的设置只需要不变成瓶颈所在就行
- 越是上游服务,pool应该越大
- 注意内存是否成为thread pool瓶颈
hikari连接数
-
资料
-
spring.datasource.hikari.maximum-pool-size=cores*2+磁盘数
- 公式原理: 最大连接数应该等于服务本身的核心数,也就是数据库处理请求的并发能力(单核的顺序处理永远比CPU切片并发快),系数2不是一定的,只是为了给它更多并发可能
- 如果是SSD,不需要加上磁盘数
- core size指的是app的core,而不是数据库的core
-
spring.datasource.hikari.minimum-idle
- 建议不设置,从而使用固定大小对pool size
-
长短事务综合对服务
- 建议使用两个pool分别处理
- 对于长事务,适当增加pool size?
-
测试分析
- 4核I7用9个pool size处理简单查询,在3000用户并发下,能达到6000TPS
- 实际测试1cpu的中等数据量查询只能达到500TPS
- 测试存在抖动是因为k8s pod的cpu的request和limit造成,最好配置成一样
- 3 cores单个服务和1 cores3个服务在总连接数相同的情况下tps相同
-
结论:数据库tps与app的cpu基本成正比
-
还需要注意服务器是否具体足够的文件句柄
Postgresql数据库性能分析与优化
- 数据库的磁盘吞吐量throughput
- GCP Postgres 数据库的吞吐量在15G存储下是7GB/s
- IOPS:每秒传输次数
- 数据库的吞吐量和每次操作的数据量决定量数据库的IOPS
- 7 GB/s的吞吐量在16kb的数据量下的IOPS是450
- explain
- 数据库执行计划,可以看出sql是否走索引,预计耗时多少
- Index
- 不加index的查询会锁全表,并且造成数据库cpu爆表,是首先应该优化的
- like模糊查询理论上%在后面会走索引,但是postgresql默认的btree索引在执行计划下没有走索引,需要gen索引,或者使用另一个字段
- UNQUE INDEX可以用于幂等校验,insert语句会报错
- 联合查询可以建立联合索引,如果没有联合索引,其中一条有索引,会通过索引查询,然后进行filter
- 事务
- 将多条语句做成事务可以减少commit和getConnection的次数
- 性能改善有待测试
- hibernate二级缓存
- 通过redis实现分布式二级缓存
微服务的资源分配
- 纵横术
- 横向扩展对tps的影响成正比,知道达到瓶颈
- 纵向扩展可以用于降低瓶颈,比如数据库连接数的瓶颈,可以将数据库操作分散在不同服务内
- 纵向扩展在不分担其他服务功能的情况下对tps的影响成反比,公式类似与瓶颈服务的tps*n%
- 比如处理10000个请求A服务需要10s,B服务需要8s,那么总共需要并不是18s,而是10+8*n%,可能13s
- 分配资源时,我们需要平衡纵向服务链路的TPS,给TPS小的服务跟多的横向扩展
- cpu
- cpu的分配需要符合纵横术