JBOSS并发量过大导致系统假死问题,JBOSS优化
这里我以该流程图来写本篇文章吧
———————————–目录———————————————
问题1:客户反馈说使用我们服务器接口进行大量并发请求报错问题(三百多并发)
分析原因:数据库连接不够用
解决问题
- 打开
%JBOSS_HOME%\standalone\configuration\standalone.xml
文件查看jboss配置文件 - 定位到数据库配置里发现没有对数据库连接池做配置
- 进行数据库连接池配置
主要参数:
min-pool-size
:数据库连接池最小数(既后台能同时请求连接到数据库的最小数)max-pool-size
:数据库连接池最大数(既后台能同时请求连接到数据库的最大数)Prefill
: 是否在系统启动的时候创建最小连接数的线程(如果设置为false,则会在服务器第一次被请求的时候创建)
问题2:连接远程数据库初始化数据库连接池发现创建连接池速度特别慢
配置数据库连接池后在MySQL里使用show full PROCESSLIST命令监控当前数据库连接情况,发现在服务器启动时做数据库连接池的初始化操作太慢(初始化最小连接池),亦会导致大并发请求消耗在创建连接数的时间太多
这个是直接找运维解决的这里我就不讲了。
问题3:创建数据库连接数大于151后无法再创建更多连接
分析原因: 数据库亦有最大连接数限制
使用
show variables like 'max_connections';
命令查看数据库最大连接数发现默认最大连接数为151
使用
set GLOBAL max_connections=500;
命令设置最大连接数到500(数据库重启失效,如需重启有效需要更改配置文件)
问题4:设置最大连接数后当并发量到500时,程序出现崩溃,阻塞,GC不够等问题
分析问题1:发现接口执行效率低下,故先解决效率问题
- 使用
show index from 表名;
命令查看接口所操作的表在关键地方是否有建立索引(两张表的数据量都是50万,再做一个关联查询,不建立索引的话效率太低) - 发现确实没在查询的搜索项上建立索引
- 使用
alter table 表名 add index(列名);
命令创建索引 - 创建索引后情况有所好转,但是不是根本问题。
分析问题2: 既然执行效率提上去了,那为何不限制web的并发请求的处理量呢。
设置web请求的并发响应,将超过并发限制的请求存入队列中
– 参数说明:max-connections
: web服务器最大支持的并发量,超过该限制后将直接拒绝请求连接
注:如果不设置最大并发量,则一千个并发进来,可能导致所有系统假死,系统内存不够,一旦出现这个情况,一千个请求实际处理到的一百个不到,当设置最大并发量后,可以保证系统不会假死,保证实际能处理到的数Executor
: 执行bq-thread-poolbq-thread-pool
<subsystem xmlns="urn:jboss:domain:threads:1.1"> <bounded-queue-thread-pool name="bq-thread-pool"> //最大核心线程数,建议和数据库最大连接数保持一致 <core-threads count="125"/> //最大队列长度,建议最大核心线程数+队列长度 = web服务器最大支持的并发 //量 ,既core-threads count + queue-length count = max-connections <queue-length count="975"/> //表示当队列满了之后能创建的最大线程数,前提是核心线程数小于最大线程数 <max-threads count="150"/> //最大线程数空闲时存活时间 <keepalive-time time="60" unit="seconds" /> </bounded-queue-thread-pool> </subsystem>
bounded-queue-thread-pool - 当前有6种内置的处理器,分别是:
unbounded-queue-thread-pool
(不绑定队列连接池)bounded-queue-thread-pool
(绑定队列连接池)blocking-bounded-queue-thread-pool
(阻塞式不绑定队列连接池)queueless-thread-pool
(较小队列连接池)blocking-queueless-thread-pool
(阻塞式较小队列连接池)scheduled-thread-pool
(调度式连接池)
整个配置说明(至此,就算一千的并发都可以了)
- 官方话:
当客户端同时并发两千请求到服务器,将会有2000 - max-connections
个连接被拒绝而连接成功的有core-threads count
个在运行,其余的将存放在queue-length
里,等待正在执行的执行完毕。 - 普通话 :
去火车站买票,只有10个窗口(core-threads count)
可以办理业务,大厅内能容纳100个人(max-connections)
,此时有120个人(请求)来买票,那能第一时间买到票的只能是前10个人,而最后面20个人只能在大厅外,剩下90人才能在大厅(queue-length)
内排队等待处理。
结尾配置总结
- 修改数据库最大连接数
set GLOBAL max_connections=500;
(这样设置的话数据库每次重启都会变回默认值151) alter table 表名 add index(列名);
创建索引- 限制web请求连接数
max-connections="1125"
- 配置核心线程数
<core-threads count="125"/>
- 配置最大请求线程数
<max-threads count="150"/>
- 配置队列长度
<queue-length count="975"/>
- 配置数据库最大线程池
<max-pool-size>150</max-pool-size>
- 配置数据库初始线程池
<min-pool-size>20</min-pool-size>