笔者使用jmeter做压测发现,并发使用200线程(5秒全部启动)时就会出现不少错误,为了解决这个问题做了一番优化,一下是优化后的总结经验。
增加MySQL的最大连接数
MySQL 5.7的默认最大连接数为151,如果要增加该值,需在数据库配置文件*.cnf里增加如下设置项,重启容器服务即可
[mysqld]
max_connections=500
增加.Net Core的数据库连接池最大值
.Net Core的MySQL连接字串的数据库连接池最大默认是100,当并发测试超过这个数时,会提示相关错误,可以在数据库连接字串里使用maximumpoolsize定义数据库连接池最大值
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;maximumpoolsize=200;
验证方法
在MySQL验证设置
show variables like '%max_connections%';
并发测试时,在MySQL里输入以下命令查看并发连接数
show processlist;
看看过去达到的最大连接数,使用如下命令
show global status like '%Max_used_connections%';
结果类似如下:
增加容器的TCP连接队列最大值
笔者使用Jmeter做压测发现,应用和数据库都部署在docker里时,偶尔会出现数据库连接超时,查MySQL日志提示Aborted Connection, 查应用提示 Command Timeout, 怀疑是两个容器之间的tcp连接的性能问题,后查询到linux默认的TCP监听队列只有128,将该值改大后再做压测,问题出现次数减少。
设置方法如下,在docker-compose.yml里对MySQL容器增加如下配置。
sysctls:
- net.core.somaxconn=500
启动后,docker exec -it mysql sh 附加到容器里,使用如下命令查看值是否生效
cat /proc/sys/net/core/somaxconn
数据库容器使用Host的网络模式
数据库超时尽管减少,但多次压测仍会有少量偶发数据库连接超时失败,如果直接用本地window环境运行应用去连接docker里的数据库却一直不会出现这个问题。经反复研究和查找网上资料,发现根本原因是: 数据库容器和其他容器都是采用bridge网络模式,应用服务和数据库服务之间的通信是“容器”和“容器”之间通信,其网络性能不如“容器”与“宿主机”之间的通信。
见参考文章 理解Docker单机容器网络_xuguokun1986的博客-CSDN博客 结论
笔者将数据库容器的网络模式改成host, 再用jmeter压测多次后问题不再复现。
docker-compose.yml配置网络模式为host方法
network_mode: "host"
host模式意味着容器直接使用宿主机的IP和端口, 应用容器要访问数据库容器时需使用docker0接口的IP地址。可在宿主机使用命令 : ip addr 查看docker0的ip地址,如下图:
参考:
理解Docker单机容器网络_xuguokun1986的博客-CSDN博客Docker容器是近两年最 火的IT技术之一,用“火山爆发式“来形容Docker的成 长也不为过。Docker在产品服务的devops 运维、云 计算(CaaS)、大数据以及企业内部应用等领域正在被越来越多的接受和广泛应用。Docker技术的本质在于提升计算密度和提升部署效率,高屋 建瓴的讲,它的出现符合人类社会对绿色发展的追求,降低资源消耗,提升资源的单位利用率。不过经历了两年多的发展,https://blog.csdn.net/xuguokun1986/article/details/53513397 How to make Network_Mode : "host" work in docker-compose.yml file - Stack Overflowhttps://stackoverflow.com/questions/56521484/how-to-make-network-mode-host-work-in-docker-compose-yml-file