SpringCloud从入门到进阶(九)——单点部署Zuul的压力测试与调优(二)

内容html

  做为微服务架构系统的入口,毫无疑问,Zuul的并发性能直接决定了整个系统的并发性能。本文结合前几篇文章的内容,在云服务器中部署了包含Eureka Server,Zuul等组件的1.0版本的微服务架构,并进行单点部署Zuul的压力测试,对其并发性能一探究竟。git

环境github

image

说明apache

  转载请说明出处:SpringCloud从入门到进阶(九)——单点部署Zuul的压力测试与调优(二)后端

问题回顾

​  在上文中,咱们在默认配置状况下,使用ApacheBench对微服务架构1.0中的Zuul和Service分别进行了压力测试,每次测试共50000个请求,并发用户数分别为50、200、500。在测试过程当中咱们遇到了以下三个问题:tomcat

​  问题一:Zuul端转发请求的线程数与后端Service处理请求的线程数不一致,它们之间是什么关系呢?服务器

​  问题二:Zuul为何会在Serivce正常的状况下出现服务熔断呢?网络

​  问题三:为何后端Service的并发线程数量达到200后没有随并发用户数的进一步增大而增大呢?架构

​  下面,咱们按照由易到难的顺序进行剖析这些问题,探究Zuul如何进行调优。并发

问题三

问题剖析

​  为何后端Service的并发线程数量达到200后没有随并发用户数的增大而增大呢?

​  SpringBoot默认使用8.5版本的Tomcat做为内嵌的Web容器。所以Zuul或Service接收到的请求时,都是由Tomcat中Connector的线程池数量决定,也就是worker线程数。

  Tomcat中默认的worker线程数的最大值为200(官方文档中有说明),能够在yaml中增长server.tomcat.max-threads属性来设置worker线程数的最大值。

配置调优

  所以,问题三的解决方案是在Zuul端和Service端的yaml中增长以下配置:

#增大tomcat中worker的最大线程数量
server: tomcat:
   max-threads: 500

  Service端完整的yaml配置文件:GitHub连接

问题二

问题剖析

​  为何Zuul会在Serivce正常的状况下出现服务熔断呢?

​  默认状况下,当某微服务请求的失败比例大于50%(且请求总数大于20次)时,会触发Zuul中断路器的开启,后续对该微服务的请求会发生熔断,直到微服务的访问恢复正常。在Serivce正常时出现服务熔断,有多是请求端或网络的问题,但一般是因为hystrix的信号量小于Zuul处理请求的线程数形成的。Zuul默认使用semaphores信号量机制做为Hystrix的隔离机制,当Zuul对后端微服务的请求数超过最大信号量数时会抛出异常,经过配置zuul.semaphore.max-semaphores能够设置Hystrix中的最大信号量数。也就是说zuul.semaphore.max-semaphores设置的值小于server.tomcat.max-threads,会致使hystrix的信号量没法被acquire,继而形成服务熔断。

问题解决

​  确保zuul.semaphore.max-semaphores属性值大于server.tomcat.max-threads。

问题一

问题剖析

  ​Zuul端转发请求的线程数与后端Service处理请求的线程数之间是什么关系呢?

  ​Zuul集成了Ribbon与Hystrix,当使用Service ID配置Zuul的路由规则时,Zuul会经过Ribbon实现负载均衡,经过Hystrix实现服务熔断。这个过程能够理解为这三个动做:Zuul接收请求,Zuul转发请求,Service接收请求。其中第一个和第三个动做,由问题三可知,分别由Zuul和Service的server.tomcat.max-threads属性配置。

  第二个动做使用了Ribbon实现负载均衡,经过设置ribbon.MaxConnectionsPerHost属性(默认值50)和ribbon.MaxTotalConnections属性(默认值200)能够配置Zuul对后端微服务的最大并发请求数,这两个参数分别表示单个后端微服务实例请求的并发数最大值和全部后端微服务实例请求并发数之和的最大值。

  第二个动做同时使用Hystrix实现熔断,Zuul默认使用semaphores信号量机制做为Hystrix的隔离机制,当Zuul对后端微服务的请求数超过最大信号量数时会抛出异常,经过配置zuul.semaphore.max-semaphores能够设置Hystrix中的最大信号量数。

​  所以经过配置上述三个属性能够增长每一个路径下容许转发请求的线程数。这三个属性的关系用下图粗略的进行表示:

1543722570822

​  Zuul端转发请求的线程数与Service端处理请求的线程数的关系:

  限制一:单点部署的Zuul同时处理的最大线程数为server.tomcat.max-threads;

  限制二:向全部后端Service同时转发的请求数的最大值为server.tomcat.max-threads、ribbon.MaxTotalConnections和zuul.semaphore.max-semaphores的最小值,这也是全部后端Service可以同时处理请求的最大并发线程数;

  限制三:单个后端Service能同时处理的最大请求数为其server.tomcat.max-threads和ribbon.MaxConnectionsPerHost中的最小值。

  注意:不少博客提到使用zuul.host.maxTotalConnections与zuul.host.maxPerRouteConnections这两个参数。通过查阅和实践,这两个参数在使用Service ID配置Zuul的路由规则时无效,只适用于指定微服务的url配置路由的情景。

配置调优

  在Zuul端的yaml配置文件中增长以下配置,为了不由于等待时间过长形成请求处理失败,增长Ribbon和Hystrix的超时设置:

ribbon:
  #Ribbon容许最大链接数,即全部后端微服务实例请求并发数之和的最大值。
  MaxTotalConnections: 500
  #单个后端微服务实例能接收的最大请求并发数 
  MaxConnectionsPerHost: 500
  #建议设置超时时间,以避免由于等待时间过长形成请求处理失败(一)
  #Http请求中的socketTimeout
  ReadTimeout: 5000
  #Http请求中的connectTimeout
  ConnectTimeout: 10000#hystrix信号量semaphore的设置,默认为100,决定了hystrix并发请求数
zuul: semaphore:
   max-semaphores: 500 
    
#建议设置超时时间,以避免由于等待时间过长形成请求处理失败(二)
hystrix: command:
   default: execution: isolation: thread: timeoutInMilliseconds: 10000

  Zuul端完整的yaml配置文件:GitHub连接

再测2.1.2经过Zuul调用sayHello接口(200并发用户数)

​  系统吞吐量达到了4200左右,请求平均处理时间为0.236ms,请求平均等待时间为47.165ms,50000次请求所有成功

​结果:请求所有成功,问题2成功解决。

[user@ServerA6 ab]$ ab -n 50000  -c 200 -p params -T 
application/x-www-form-urlencoded http://172.26.125.117:7082/v1/routea/test/hello/leo Time taken for tests: 11.791 seconds Complete requests: 50000 Failed requests: 0 Requests per second: 4240.46 [#/sec] (mean) Time per request: 47.165 [ms] (mean) Time per request: 0.236 [ms] (mean, across all concurrent requests)

  Zuul资源使用状况:

  ​压测过程当中,Zuul服务器的CPU使用率为100%,堆内存的使用最大为500MB(堆空间为512MB)而且伴有频繁的GC,实时线程从79增长到269。

1543895324875

​  Service资源使用状况

​  压测过程当中,Service服务器的CPU使用率为55%,堆内存的使用最大为390MB(堆空间为580MB),实时线程从49增长到80。

1543895283120

再次测试3.1.2经过路由Zuul调用sayHello接口(500并发用户数)

​  系统吞吐量在4000(请求/秒)左右,请求平均处理时间为0.246ms,请求平均等待时间为123.168ms,50000次请求所有成功。相对于上一节中的3.1.2,在并发用户数增大2.5倍以后,系统的吞吐量有略微的减少。

​  结果:请求所有成功,问题2成功解决。

[user@ServerA6 ab]$ ab -n 50000  -c 500 -p params -T application/x-www-form-urlencoded 
http://172.26.125.117:7082/v1/routea/test/hello/leo Time taken for tests: 12.317 seconds Complete requests: 50000 Failed requests: 0 Requests per second: 4059.48 [#/sec] (mean) Time per request: 123.168 [ms] (mean) Time per request: 0.246 [ms] (mean, across all concurrent requests)

  Zuul资源使用状况:

  ​压测过程当中,Zuul服务器的CPU使用率为100%,堆内存的使用最大为470MB(堆空间为512MB)而且伴有频繁的GC,实时线程从71增长到492。此时CPU和内存都存在瓶颈。

​  结果:Zuul接收请求的线程数超过了200,达到了430+,问题三解决。

1543816603846

  Service资源使用状况

​  压测过程当中,Service服务器的CPU使用率在50%之内,堆内存的使用最大为330MB(堆空间为580MB),实时线程从48增长到89,将近50个线程在处理Zuul转发的请求。​

1543816586071

再测3.2.1直接调用timeConsuming方法(500并发用户数)

​  系统吞吐量在2400(请求/秒)左右,请求平均处理时间为0.423ms,请求平均等待时间为211.451ms,50000次请求都执行成功。跟上一节3.2.1的测试比较,在并发用户数增大2.5倍以后,系统的吞吐量同步增大将近2.4倍,请求平均等待时间从203.467ms变为211.451ms。因为线程增长会增大CPU的线程切换,而且占用更多的内存。所以系统吞吐量没有等比例增大、平均等待时间有微小的波动,也在情理之中。

[user@ServerA6 ab]$ ab -n 50000 -c 500 http://172.26.125.115:8881/test/timeconsume/200

Time taken for tests:   21.145 seconds Complete requests:      50000 Failed requests:        0 Requests per second:    2364.61 [#/sec] (mean)
Time per request:       211.451 [ms] (mean) Time per request:       0.423 [ms] (mean, across all concurrent requests)

​Service资源使用状况

​压测过程当中,Service服务器的CPU使用率稳定在50%之内,堆内存的使用最大为470MB(堆空间扩充到670MB),实时线程从40增长到530。此时CPU和内存仍然有富余,所以系统的吞吐量还会随着并发线程的增长而同步增大,感兴趣的童鞋能够尝试将server.tomcat.max-threads属性设置成1000进行测试。

​结果:实时线程从40增长到530,有500个线程在同时处理请求。问题三解决。

1543812859502

再次测试3.2.2经过Zuul调用timeConsuming方法(500并发用户数)

​  系统吞吐量在2200(请求/秒)左右,请求平均处理时间为1.762ms,请求平均等待时间为880.781ms,50000次请求中有47082次请求出错,发生熔断(问题二)。跟1.2.2的测试状况相比,在并发用户数增大10倍以后,系统的吞吐量同步增加9倍。

[user@ServerA6 ab]$ ab -n 50000 -c 500 http://172.26.125.117:7082/v1/routea/test/timeconsume/200

Time taken for tests:   23.348 seconds Complete requests:      50000 Failed requests:        0 Requests per second:    2141.47 [#/sec] (mean)
Time per request:       233.485 [ms] (mean) Time per request:       0.467 [ms] (mean, across all concurrent requests)

  Zuul资源使用状况

​  压测过程当中,Zuul服务器的CPU使用率在65%附近波动,堆内存的使用最大为370MB(堆空间为512MB),实时线程从70增长到560。Zuul服务器的CPU和内存资源还有富余。

1544065352229

  Service资源使用状况

  压测过程当中,Service服务器的CPU使用率在35%附近波动,堆内存的使用最大为420MB(堆空间为650MB),实时线程从48增长到538。Service服务器的CPU和内存资源还有富余。

1544065335732

  结果:Service端的处理线程数为500,与并发请求用户数一致,问题三解决。

相关文章
相关标签/搜索