xy项目第二次压测报告总结

1 第二次测试报告

由于上周测试的TPS员工端与管理端均高于或等于300TPS与开发讨论线上暂时可以满足需求,但在测试的过程中也暴露了一些问题,比如我们资源的整体利用率并不高,如何能把资源充分利用起来,更高效的提升我们的整体性能

本周分别挑选了一个管理端和一个员工端的接口,方便快速的把各自共同的服务抛出来,管理端涉及到的和erp交互的服务比较多,设计上使用了大量的异步双写,采用了mongodb,验证下性能是否有提升;员工端用户有更高的性能需求,需要重点验证下服务的整体性能

1.1.1.1 管理端-首页压测问题排查及定位

查看skywalking耗时情况,发现售后列表耗时较长,查看该接口调用链路,

com.leading.gmcoreservice.aftersale.domain.service.impl.MgmtAfterSaleServiceImpl.findOrderAfterSaleList

方法和/after-sale/list接口耗时较长

com.leading.gmcoreservice.aftersale.domain.service.impl.MgmtAfterSaleServiceImpl.findOrderAfterSaleList经开发排查代码初步定位为线程堵塞或数据库连接导致的耗时长 image.png 下面进行响应时间的拆分,通过arthas trace进行链路追踪,对skywalking上的方法进行追踪时,发现arthas报错,通过查看日志及开发排查发现trace的类是代理类为私有类,trace追踪不进去,于是通过日志发现了目标类,需要对目标类在进一步追踪

image.png 在目标类进行追踪后发现好多6s多的链路,于是在进一步追踪

再去追踪org……..intercept方法 image.png image.png 继续往下追踪时,发现提示没有方法 image.png 反编译类看看这个方法,发现该类继承了父类,子类中并没有该类,所以该方法为父类继承过来的,所以想继续trace需要用父类进行追踪 image.png 父类进行追踪后继续追踪invokeJoinpoint方法 image.png image.png 追踪这个方法时又碰到没有改方法于是继续反编译 image.png image.png 此时追踪的方法与返回的方法一致,代表就是这个方法自身耗时问题。其中有springFramwork.aop怀疑可能跟AOP代理有关 image.png 内存分析,不同的callback中有的是abvised有的是target,而获取到target的callback中拿到了Repository层的代理,Repository层的代理类主要是获取mysql的连接,执行sql语句。

内存分析与上图的线程分析,上面图trace 与追踪一致,因为方法没有进行执行一直在等待目标类 image.png 在看一下skywalking的链路追踪该接口后面是在执行mysql,而mysql执行时间很短,代理主要做的工作是建立连接等工作,所以开发尝试更改数据库连接池

image.png 查看apollo配置中心发现之前是没有配置数据库连接池的,在开发添加数据库连接池后压测 image.png 之前的

com.leading.gmcoreservice.aftersale.domain.service.impl.MgmtAfterSaleServiceImpl.findOrderAfterSaleList

gm-core-service服务的接口已经没有长耗时,现在反应出customer-service的接口耗时较高,需继续排查 image.png Customer-service 与之前的gm-core-service表现一样所以直接找到叶先亮增加数据库连接池 image.png image.png 增加线程池配置后复测 image.png TPS依然跟之前差不多300左右 image.png 时间消耗主要表现在网关及mysql数据库上面 image.png image.png 在于开发讨论后马上更换springcloudgateway新网关,旧网关没有优化的必要,所以我们决定暂时绕过网关nginx直接到服务进行压测

TPS提升了一倍从300到600

image.png 时间消耗主要在mongDB上面 image.png Mongo配置和代码逻辑:

spring.data.mongodb.custom.hosts[0] = XXXXX
spring.data.mongodb.custom.hosts[1] = XXXXX spring.data.mongodb.custom.hosts[2] =XXXXX spring.data.mongodb.custom.ports[0] = 28017
spring.data.mongodb.custom.ports[1] = 28018
spring.data.mongodb.custom.ports[2] = 28019

spring.data.mongodb.custom.replica-set = mongotest
spring.data.mongodb.custom.authentication-database = admin

spring.data.mongodb.custom.minConnectionsPerHost = 50
spring.data.mongodb.custom.connectionsPerHost = 200
spring.data.mongodb.custom.threadsAllowedToBlockForConnectionMultiplier = 5
spring.data.mongodb.custom.serverSelectionTimeout = 30000
spring.data.mongodb.custom.maxWaitTime = 120000
spring.data.mongodb.custom.maxConnectionIdleTime = 0
spring.data.mongodb.custom.maxConnectionLifeTime = 0
spring.data.mongodb.custom.connectTimeout = 10000
spring.data.mongodb.custom.socketTimeout = 600000
spring.data.mongodb.custom.socketKeepAlive = true
spring.data.mongodb.custom.sslEnabled = false
spring.data.mongodb.custom.sslInvalidHostNameAllowed = false
spring.data.mongodb.custom.alwaysUseMBeans = false
spring.data.mongodb.custom.heartbeatConnectTimeout = 20000
spring.data.mongodb.custom.heartbeatSocketTimeout = 20000
spring.data.mongodb.custom.minHeartbeatFrequency = 500
spring.data.mongodb.custom.heartbeatFrequency = 10000
spring.data.mongodb.custom.localThreshold = 15

除优化以上配置外还优化代码逻辑,先读取从库,如果从库没有再读取主库,之前的代码是直接从主库读取

订单接口mysql和mongodb 交替出现慢的情况,之前是基本都是mongodb慢的问题,而且响应效率整体有大幅提升 image.png image.png 发现售后列表和订单列表都存在Mysql执行慢问题,重点改为优化mysql: image.png 优化mysql增加索引:gm_order_aftersale表 customer_id,create_time 联合索引 gm_order 表 order_no索引 gm_order_address表 order_no索引,复测: image.png image.png 上图在开始已经定位过,是鉴权服务的连接池问题,由于服务与服务之间都需要鉴权,所以这里问题又暴露出来了。 leading-service-core 1.1.5 加上了LeadingUserInfoRestTemplateFactory,升级组件服务后,重新测试,不走网关,tps由600变成了1300左右 image.png image.png image.png 增加mgmt 和core服务实例由1个变成2个,查看tps情况 image.png 查看skywalking链路,主要耗时基本在feign ,mongodb,mysql三个方面,增加连接数,发现数据库的吞吐量并未上去 image.png image.png image.png 查看数据库增加连接数后吞吐情况,发现Qps未提升。 image.png 调整了数据库配置,之前主从都一个地址 ,更改不同地址且增加三个从库后压测 image.png image.png image.png

1.1.1.2 员工端-商品详情页压测

绕过网关后压测结果如下,入口就开始堵塞SpringMVC 怀疑tomcat线程池问题 image.png image.png image.png 发现了上三个图的问题 优先排查入口springMVC的问题所以增大了tomcat线程池

server.tomcat.max-connections = 20000 ---在给定时间接受和处理的最大连接数,默认值10000

server.tomcat.max-threads = 300 ---处理的最大并发请求数,默认值200

server.tomcat.min-SpareThreads = 20 --初始化时创建的线程数默认值10

优化配置后继续压测,springMVC依然存在而且占整体耗时比例较高 image.png 查看dashboard面板线程情况 发现很多waiting情况,在中间出现了红色的block状态,证明线程现在存在堵塞情况(没有截到死锁的线程,一闪而过) image.png 查看线程死锁发现输出流锁住了,在看下面信息都是跟log相关的 image.png 开发查看log等级 现在是debug级别,为了减少io情况等级提升为info级别后在压测TPS从350提升到700 image.png 在700tps下查看skywalking的链路耗时情况,发现跟之前表现一样都是连接池的问题所以让相应服务的开发增加连接池后在压测,发现mapping服务也有该问题 让响应的开发负责人增加连接池 image.png 增加连接池后压测 700提升到800 image.png 时间消耗主要在商品服务的getskudetail接口 image.png 后面的获取详情页接口还是大接口(返回数据太大90%数据员工端用不到),没有接入定式化开发的接口,后续接入定制化开发接口后,理论来说时间耗时应该更短。

优化日志,sql索引,数据库主从配置,使用优化定制化接口后复测:(与开发讨论后决定目前先优化到这里) image.png

测试小结

通过调优,我们tps 平均已经达到了1300,高的可达1700左右,响应效率大幅提升。本次已经不仅仅是定位问题本身,更多的是透过这些问题整理出一套通用的排查分析方法,更高效的去定位问题

优化项如下:

1、压测过程中出现大量user鉴权耗时较长,不同的服务都要更改连接池配置,龙义上周对个别服务增加了优化处理,开发沟通,本周该代码被封装到了公共组件,后续相关服务直接引用新的组件,进行相关版本升级就可以(版本leading-service-core 1.1.5和leading-common1.7.4包一起升级)

2、不同的接口在连接mysql数据库时没有数据库连接池,需要单独配置

3、开发分别优化了mongodb与mysql的问题

4、网关层造成拥堵,因为马上进行更换新网关所以旧网关暂时不优化处理

5、Log 级别debug,调整级别为info后tps会有大幅提升,后续压测环境统一设置为info

6、员工端商品详情定制化接口优化