大型网站分布式架构(五)—— Apache Bench与JVisualVM联调

职责分配:

  • Apache Bench 负责模拟用户请求
  • JVisualVM负责观察Tomcat的Java虚拟机内存、线程、CPU的变化

首先博主需要启动Tomcat,再使用JVisualVM远程连接Tomcat,远程连接配置详见:大型网站分布式架构(四)—— JVisualVM远程监控Tomcat

启动Tomcat

[root@centos6-1 ~]# jps
94202 Jps
[root@centos6-1 ~]# cd /export/servers/apache-tomcat-8.0.53/bin/
[root@centos6-1 bin]# ./startup.sh 
Using CATALINA_BASE:   /export/servers/apache-tomcat-8.0.53
Using CATALINA_HOME:   /export/servers/apache-tomcat-8.0.53
Using CATALINA_TMPDIR: /export/servers/apache-tomcat-8.0.53/temp
Using JRE_HOME:        /export/servers/jdk1.8.0_65/jre
Using CLASSPATH:       /export/servers/apache-tomcat-8.0.53/bin/bootstrap.jar:/export/servers/apache-tomcat-8.0.53/bin/tomcat-juli.jar
Tomcat started.
[root@centos6-1 bin]# jps
94273 Jps
94224 Bootstrap
[root@centos6-1 bin]# 

查看是否能够访问
这里写图片描述

JVisualVM远程连接Tomcat
这里写图片描述
我们可以得到以下信息:

  • 可以看到CPU使用率不到2%
  • 堆使用为不到100M
  • 启动后装载的类有7299个
  • 目前活动的线程共有40个。

下面使用Apache Bench对Tomcat发起1000个请求,一次发起100个

[root@centos6-1 bin]# ab -k -n 1000 -c 100  http://192.168.214.150:8080/appdemo-0.0.1-SNAPSHOT/ 

执行结果

Server Software:        Apache-Coyote/1.1
Server Hostname:        192.168.214.150
Server Port:            8080

Document Path:          /appdemo-0.0.1-SNAPSHOT/
Document Length:        197 bytes

Concurrency Level:      100
Time taken for tests:   1.742 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    0
Total transferred:      365147 bytes
HTML transferred:       197985 bytes
Requests per second:    574.20 [#/sec] (mean)
Time per request:       174.156 [ms] (mean)
Time per request:       1.742 [ms] (mean, across all concurrent requests)
Transfer rate:          204.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   6.6      1      36
Processing:     2  133  99.3    107     497
Waiting:        2  107  81.9     84     496
Total:          2  136 101.4    108     498

Percentage of the requests served within a certain time (ms)
  50%    108
  66%    146
  75%    175
  80%    195
  90%    328
  95%    363
  98%    383
  99%    420
 100%    498 (longest request)

再观察JVisualVM
这里写图片描述

可以发现以下情况:

  • CPU使用率达到了80%
  • 堆的最大内存扩展到了200M,同时堆内存一下子出现了50M左右的内存使用(前面的部分是启动到Apache Bench发起并发请求之间一段时间的变化)
  • 类装载数达到了7859个,比启动后增加了许多,同时有47个类杯卸载
  • 线程数从50不到突增至130多个

现在过去了几分钟,我们再来看看
这里写图片描述

得到以下信息:

  • CPU恢复了平静
  • 堆最大内存在刚才的并发访问后动态缩减了几兆,同时堆内存使用率处在不断地增长又下降,下降又增长的过程中
  • 装载数没有变化
  • 活动的线程数变回了40

出现以上情况的原因是:

  1. 请过过来的时候,CPU需要给请求创建线程,然而短时间内创造过多的线程占用了过多的CPU,当并发结束后,CPU又开始处于半闲置状态
  2. Java虚拟机在请求到来时不断地创建线程等对象,致使堆空间的使用率急速上升,从而虚拟机动态地扩展了堆空间的大小。一段时间后,随着虚拟机的GC动作,大量的新生代的对象和少量的老年代的对象被垃圾回收,导致堆空间使用率又再次下降。而不断地折线上升下降的过程就是创建对象和垃圾回收导致的必然结果
  3. 类装载的数量在tomcat启动和大量请求过来的时候才会发生变化,因为一个类只要被虚拟机加载一次即可用来创建许多个对象,所以类装载的情况一般不是真正影响程序运行的主要因素
  4. 请求需要线程来处理,所以大量的请求会导致短时间内创建出许多的线程,那为什么不是1000个请求对应1000个县城呢?因为线程能够被复用。当一段时间后,不再被使用的线程对象就被虚拟机垃圾回收了,所以活动的线程数又回到了当初的稳定状态

总结

通过上面的操作,可以帮助我们对JVM内部运行原理进行基本的了解,从而为后面服务器的性能调优提供必要基础。博主很早之前就想开一个JVM的专栏,但是并没有施行,希望后面有契机与大家分享吧。下一章博主将引入Nginx,来优化我们的单机版网站服务器架构。