技术博文 · 2025-03-11 0

java应用并发1000压测失败,提示javax.net.ssl.SSLHandshakeException:

背景:业务使用springboot框架,前端使用的nginx再并发量大的时候出现后端异常告警。

资源配置:服务端 单节点 4c16g nginx 2c4g 中间件seata 2c8g 后端数据库 rds2c8g,默认连接6000

压测工具:jemerter性能测试 单接口1000并发压测,多接口串联500并发压测

出现问题:

1、压测提示报错,系统异常

2、服务日志报错

3、压测过程中提示

4、nginx返回报错

5、服务生产环境,日常提示告警内容包含关键词java.util.concurrent.TimeoutException、java.sql.SQLException

处理过程:

压测后端排查.xlsx

调整后端服务对应的连接参数

根据压测结果和服务日志报错结果进行后端服务的连接参数排查,考虑到jdbc的连接参数和dubbo的参数配置问题。于是修改java应用对应参数如下:

at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)

其中尝试调整的参数有:

1、尝试修改数据库超时时间,问题暂未解决;
2、尝试修改seata超时时间,问题暂未解决;
3、尝试修改中间件DUBBO超时时间,问题暂未解决;
4、尝试分析中间件参数,发现DUBBO使用默认配置,尝试修改线程数,问题解决,修改参数如下:

dubbo:
protocol:
port: -1 # 协议端口。使用 -1 表示随机端口。
name: dubbo
threads: 500

当压测的并发数再往上提的时候又出现问题,于是

1.重新启动一个seata服务,与生产配置保持一致;
2.调整seata配置参数如下:

retry-times: 40 # 试获取全局锁时的最大重试次数为40 默认30
retry-interval: 50 # 每次重试之间的等待时间50ms 默认10ms
retry-policy-branch-rollback-on-conflict: true # 发生锁冲突时回滚分支事务
500条失败率为0

nginx的参数调整

根据报错日志,可以判断是因为nginx的连接数不够导致,默认nginx的worker 线程连接数是1024

javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
    at sun.security.ssl.SSLSocketImpl.handleEOF(SSLSocketImpl.java:1511)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1328)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1233)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:417)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:389)

除去日常使用的连接,在并发压测的时候肯定是扛不住的。于是将nginx的默认配置worker_connection调整为10000

再次进行压测不再提示如上报错,问题解决

其中也还针对前端的入口进行了一些keepalive的超时时间配置,但是那些超时配置默认的已经完全够用,如果超时时间超过60s还不能返回数据的话,这个对于ng是一个巨大的压力,说明后端服务肯定出问题了

seata中间件参数调整

1、选择seata中间件及其版本的理由

我们的业务有一个数据的动账调整,因为之前服务各接口之间的结算都是走事务,而且事务控制的不是特别好,导致了线上数据的很多不一致问题。于是引入了seata中间件,用于满足接口间对于数据处理的事务完整性。

根据我们spring boot的框架使用的版本,我们选择seata 1.6的版本

我们spring boot的框架版本是2.7.18。


对应版本选择可以参考https://wenku.csdn.net/answer/4nqrho8zwh

2、服务日志报错一直提示的java.sql.SQLException: io.seata.core.exception.RmTransactionException: RPC Timeout

1、通过seata官方文档查找和一系列推敲,最后定位到了如下几个参数

# 数据库初始连接数 默认1
store.db.minConn=500
# 数据库最大连接数 默认20
store.db.maxConn=1000
# 获取连接时最大等待时间 默认5000,单位毫秒
store.db.maxWait=15000
# 查询全局事务一次的最大条数 默认100
store.db.queryLimit=10000
#对于批量请求消息的并行处理开关,1.6.1 默认为 true,建议为 false,1.6.1 中存在并行处理时数组越界异常
server.enableParallelRequestHandle=false
#TC 批量发送回复消息开关,建议为 true,可解决 client 批量消息时的线头阻塞问题
transport.enableTcServerBatchSendResponse=true

2、还有一个需要注意的点:因为seata采用的docker +db的高可用部署模式,通过nacos作为配置中心,直接在nacos中修改配置文件之后需要重启seata才能生效

问题解决后效果:

单接口1000并发压测通过

5个接口串联进行500并发压测,通过

总结:

在出现这种问题的时候需要潜下心来好好的排查,查阅官方文档,然后采用各种不同的姿势进行测试。其中我们就尝试了更换服务器节点,做分布式部署等措施虽然最后证明是无效的动作。但是整体排查过程还是需要考虑更多的可能性。dd