公司打算举办一场活动,现场参与活动人数比较多。针对于可能访问比较密集的接口进行压力测试。使用jmeter进行测试,请求并发稍微多些,系统就会挂起。数据库
针对压力测试出现的问题,由于并发超过1秒钟100笔就会出现问题,Spring Cloud做为一个成熟的框架,不多是框架不支持。因此首先想到的是配置上须要进行调优。缓存
请求从jmeter发出后,须要经过Zuul网关,而后到Spring Cloud微服务端。因此,整个调优方向分为两个地方:微服务端和zuul网关。架构
当jmeter调整到每秒钟70个并发请求时,服务应用端的日志中出现了不少hystrix回滚,而且有不少HystrixRuntimeException。并发
com.netflix.hystrix.exception.HystrixRuntimeException ... could not be queued for execution...
缘由:Hystrix请求线程池缺省为最大10个线程,在大量请求下,很容易超过这个数值,致使抛出异常。框架
解决方法:在配置文件中修改线程池中的coreSize(properties方式的配置文件)分布式
hystrix.threadpool.default.coreSize=500
配置上测试后,客户端再也不出现hystrix的异常了,可是并发请求数进一步提升到100以上后,依然会没法响应请求。微服务
因为网关也配置使用了Hystrix,在并发请求过大时,也会抛出异常:高并发
com.netflix.hystrix.exception.HystrixRuntimeException: ggx-test short-circuited and no fallback available
显示的异常时,具体的ggx-test服务系统短路而且没有熔断可用,但ggx-test系统还正在运行,因此问题出如今zuul网关上。性能
① zuul内部路由能够理解为使用一个线程池去发送路由请求,因此咱们也须要扩大这个线程池的容量。测试
zuul.host.maxTotalConnections=1000
zuul.host.maxPerRouteConnections=1000
② zuul使用Hystrix,而Hystrix有隔离策略: THREAD 以及 SEMAPHORE ,默认是 SEMAPHORE ,默认大小是100。请求的并发线程超过100就会报错。
zuul.semaphore.max-semaphores=5000
配置完上述配置后,从新进行测试,在日志中不会出现错误了,可是并发请求超过100/S时,系统挂起,再也不响应请求。因而,排查各类可能后,想到了多是数据库链接池的问题。
咱们系统使用数据库链接池是c3p0,最大的数据库配置的链接数为30个,尝试将数据库最大链接数修改到100时,使用jmeter测试,并发请求可以稍微提升些。这样可以定位到问题就在数据库链接池上。
目前市场上主流的开源数据库链接池有:C3P0,DBCP,Druid,HikariCp。其中C3P0和DBCP是出现的比较早的数据库链接,比较稳定,在低并发的状况下,总体表现还不错,可是在高并发下,响应时间变长,性能不好,甚至于死锁。Druid是阿里巴巴开源的高性能数据库链接池,虽然性能不及HikariCp,可是它提供的各类维度的统计分析的功能,在国内市场流行度很高。
相关的数据库链接池对比:
|
C3P0/DBCP |
Druid |
hikariCP |
应用 |
主要在Hibernate |
各大主流平台 |
起源于boneCP |
性能 |
较差 |
强 |
很强 |
线程池容器 |
Blocking Queue |
List Reentrantlock |
|
综合,Druid性能比较优异,网上文档资料很健全,加上可视化的统计分析很适合咱们解决当前问题。咱们将数据库链接池从C3P0换到了Druid。
通过上面优化,压力测试达到了预期,jmeter每秒钟发送1000个并发请求,系统可以在预期时间内顺利返回响应结果。虽然不是很高,可是应对咱们当前业务需求是足够的。没有最优的架构,只有最合适的架构,一切系统设计原则都要以解决业务问题为最终目标,脱离实际业务的技术情怀架构每每会给系统带入大坑。固然这并不能影响咱们对技术的追求,在碰到并发请求大的状况下,有几个维度能够进行尝试优化:首先就是限流,将请求拦截下来,不要对系统形成太大压力;其次使用各类缓存,对于不须要访问数据库的资源缓存起来,提升响应速度,减小数据库压力;而后使用分布式部署,使用集群替代单机;还有优化接口对SQL进行调优等等。