欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MongoDB 最大连接数 设置失效的异常分析

程序员文章站 2022-03-12 10:13:48
背景介绍: 查询MongoDB配置参数,可以知道关于最大连接数的参数是maxConns。但是连接实例后,查看支持的最大连接数,还是默认的819。 说明:最大连接数是由maxConn (maxIncomingConnections)和操作系统单个进程能打开的最大文件描述符数总量的80%决定的,取两个之 ......

查询mongodb配置参数,可以知道关于最大连接数的参数是maxconns。但是连接实例后,查看支持的最大连接数,还是默认的819。

说明:最大连接数是由maxconn (maxincomingconnections)和操作系统单个进程能打开的最大文件描述符数总量的80%决定的,取两个之间的最小值。默认单个进程能打开的最大文件描述符数为1024,1024*80% = 819.2 取整数819。所以最大可以支持的并发连接数为819。

 

案例重现

 

以下为本次测试mongodb案例配置的参数。

MongoDB 最大连接数 设置失效的异常分析

启动后查看最大连接数。

运行命令:db.serverstatus().connections

 MongoDB 最大连接数 设置失效的异常分析

current表示当前到实例上正在运行的连接数。

available表示当前实例还可以支持的并发连接数。

也就是说此实例最大能支持的并发连接数为:current+available=3+816=819.

所以设置的maxconns参数无效。所以设置的maxconns参数无效!所以设置的maxconns参数无效!所以设置的maxconns参数无效!

 

答案求索

 

此时查看查看网上相关资料,大部分集中在 linux系统最大文件描述符数。查看我们系统配置,此时已经是65535了。不是系统最大文件描述符数限制的了。

MongoDB 最大连接数 设置失效的异常分析

转个弯,因为我们是为操作系统是 centos 7 ,所以我们的mongodb服务是透过systemctl来管理的。那如果是通过service 命令来管理此服务呢?

测试1 测试用service来管理mongodb 服务 对最大连接数的影响

(1)       在/etc/init.d目录下创建名为mongodbtest0903的服务;

(2)       服务的配置如下:

 MongoDB 最大连接数 设置失效的异常分析

(3)       赋予执行权限,然后开启服务

MongoDB 最大连接数 设置失效的异常分析

(4)       此时查看连接数为2500(为maxconns参数值)

 MongoDB 最大连接数 设置失效的异常分析

(5)       关闭 mongodb 服务

MongoDB 最大连接数 设置失效的异常分析

 

以上说明用service 来管理服务,最大连接数参数起作用了。

 

测试2 如果直接用mongodb command打开呢?

(1)       直接开启

MongoDB 最大连接数 设置失效的异常分析

(2)此时查看连接数为2500(为maxconns参数值)

MongoDB 最大连接数 设置失效的异常分析

(3)关闭此服务

MongoDB 最大连接数 设置失效的异常分析

 

以上说明直接开启mongodb服务,最大连接数参数起作用了。

通过service 和  mongodb 命令启动服务,最大连接数都是设置的参数,而通过systemctl 来开启此服务就变成了默认的819.

 

探究

 

我们来具体分析下systemctl 开启的 mongodb 服务(此服务定义为mongodbtest0903)。

(1)查看此服务的所有配置细节的命令

systemctl show mongodbtest0903.service

部分细节如下

MongoDB 最大连接数 设置失效的异常分析

此时 limitnofile=4096

(2)              查看此服务的进程,以及此进程下的资源限制

 MongoDB 最大连接数 设置失效的异常分析

 进程的资源限制

MongoDB 最大连接数 设置失效的异常分析

终于看到了 资源限制是1024。

 

问题1:为什么经过systemctl 启动的mongodb服务变成了默认的819.

回答:因为systemctl 启动的服务进程其最大文件描述符数变成了1024. 1024*80% = 819.2 取整数819.

 

问题2:为什么系统设置的最大是65525 而 systemctl 变成了1024.

在centos7系统中,使用systemd替代了之前的sysv。/etc/security/limits.conf文件的配置作用域缩小了。/etc/security/limits.conf的配置,只适用于通过pam认证登录用户的资源限制,它对systemd的service的资源限制不生效。

其实仔细查看/etc/security/limits.conf文件的注释,说明了对系统服务不生效。

MongoDB 最大连接数 设置失效的异常分析

 

解决方案 

 

解决方案,知道了问题所在,针对此问题寻找解决方案相对容易了。

 

解决方案1:针对单个 systemctl 管理的服务。

在/lib/systemd/system中找到具体的服务,增加

# (open files)
limitnofile=64000

命令。 修改后为:

MongoDB 最大连接数 设置失效的异常分析

重启服务,此时连接查看最大连接数为2500,到达设置的参数。

 

解决方案2 网上有种方案是对systemd全局修改。此方案本作者没有验证,转述如下,意思是修改 /etc/systemd/system.conf 即可:

 

全局的配置,放在文件/etc/systemd/system.conf和/etc/systemd/user.conf。 同时,也会加载两个对应的目录中的所有.conf文件/etc/systemd/system.conf.d/*.conf和/etc/systemd/user.conf.d/*.conf
其中,system.conf是系统实例使用的,user.conf用户实例使用的。一般的sevice,使用system.conf中的配置即可。systemd.conf.d/*.conf中配置会覆盖system.conf。

defaultlimitcore=infinity

defaultlimitnofile=100000

defaultlimitnproc=100000

注意:修改了system.conf后,需要重启系统才会生效。

 

因为服务器上systemctl会管理多种服务,为减少对其它服务的影响,建议在单个服务上修改,即采用第一种方案。

 

其他相关知识

(1)mysql 服务也会遇到类似问题;

(2)* nofiles    - soft limit on the number of file descriptors a process may have;

 

(3) *soft limit与hard limit的不同:soft limit是真正生效的限制值,而hard limit仅仅是soft limit调整范围的一个上限。