启动一个java项目http状态 500 - 内部服务器错误_Java web服务器假死分析

问题现象:

服务端端口开着,客户端可以telnet 服务器上的端口,但访问服务时没有任何返回。

服务器环境 :Java 8 + linux CentOS release 6.5。

用apache ab压力测试工具对基于java web(spring boot) 的访问进行压力测试时当并发量为2000时经常发现请求无法跑完。

分析发现服务器上有很多web端口(8071)的连接,状态为:CLOSE_WAIT,且过很长时间都不会释放(1个小时以上甚至更久):

5d6ddb6dc791a965d657f464e3d6c98d.png

但在ab测试工具所在的客户端机器上并没有web端口的链接:

c64a64021f7f4c1893b8fda97b4e88e9.png

在客户端访问服务时没有任何返回,但客户端可以 telnet 上服务器上的web端口(8071),可以认为此时服务器假死。

一开始认为服务器上的open files开的太小不能再接收新的请求的连接,但用ulimit -a查看

服务器上的Open files时,发现其个数为32768已经调的足够大了(如下图),应该不是这个原因。

d72e9af6c97cd428ad31ce903b0d1825.png

继续排查java启动时的输出文件(nohup.out),发现下面这个OutOfMemoryError错误:

Exception in thread "http-nio-8071-ClientPoller-1" 2018-03-22 10:35:43.958 [http-nio-8071-exec-1262] INFO cn.xxx..web.RedirectController - {"hostName":"localhost.localdomain","msg":"redirectUrl() is running..., uri: /NRr2EbY","traceId":"auto_gen_trc_9aa51ca9-8faa-4475-95e0-50892f321a86"}

java.lang.OutOfMemoryError: unable to create new native thread

at java.lang.Thread.start0(Native Method)

at java.lang.Thread.start(Thread.java:717)

at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957)

at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1378)

at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:163)

at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:141)

at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:828)

at org.apache.tomcat.util.net.NioEndpoint$Poller.processKey(NioEndpoint.java:849)

at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:825)

at java.lang.Thread.run(Thread.java:748)

经研究,出现该异常可能是jvm内存太小,或者linux用户可以开启的线程数设置太小造成jvm无法启动所需的大量线程。之前的jvm启动时没有加任何内存配置,linux max user processes值为默认值1024,重新调整jvm启动参数,增大堆内存,缩小线程栈内存,重新启动程序:

nohup java -Xmx3800m -Xms3800m -Xmn2g -Xss256k -jar war &

同时修改文件:/etc/security/limits.d/90-nproc.conf 中的nproc值为31413(默认最大值的一半):

10d5e4a43a7bb2fe9b1fceb7154c843b.png

退出后重新登录查看max user processes已改变:

673b6c06e8609b5c19fd25cbe2ea70c8.png

再次启动服务并进行压力测试,压力测试可以跑完,也没有发现状态为CLOSE_WAIT的链接,服务器假死问题解决。

总结:java web出现大量状态为CLOSE_WAIT的连接的原因是:tomcat在接收到新请求后由于无法开启新线程进行处理,造成客户端在主动断开连接后,服务器端无法进行连接释放造成的。和服务端的open files配置无关,因为不管有多少个请求连接(connection)在服务端只有一个端口在运行。

备注:在客户端用apache ab工具进行并发请求测试时,经常会报:

socket: Too many open files (24)

原因:客户端需要开启多个端口模拟多个用户连接,所有需要增大客户端机器的open files配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值