从ESTABLISTEND到数据库连接池

来源:互联网 发布:老a淘宝卖家工具箱 编辑:程序博客网 时间:2024/05/21 00:46

今天在做一个Python应用的压力测试时,闲得没事看了一下网络连接的情况(netstat -an | grep tcp),一看惊呆了本宝宝,439个ESTABLISTEND连接,本来以为这种和大量TIME_WAIT或大量CLOSE_WAIT一样是TCP协议本身造成的,这里说下TIME_WAIT和CLOSE_WAIT

TIME_WAIT是主动发起关闭连接的一方在接收了FIN以及发送ACK之后所处的状态,该连接需要经过2MSL后才会进入CLOSED,也就是真正关闭了,而CLOSE_WAIT是被动关闭连接的一方在发送了ACK之后所处的状态,如有大量的CLOSE_WAIT,一般就是被动关闭连接的一方没关闭连接(发送FIN、接收ACK),导致卡在CLOSE_WAIT状态

言归正传,翻了书,看了博客,最后问学长才知道是数据库连接池的原因,实际数据库都是做了优化的,不可能对每个请求都连接一次数据库,那样开销太大了,所以数据库服务器会在程序运行时生成一个数据库连接池,里面预先放一些已创建连接的对象。因为压力测试,并发数很高,所以会产生很多连接,Pymongo默认的最大连接数是100,至于产生了400多个,因为Python进程和mongod进程都要建立ESTABLISTEND连接,所以平分一下,200多个,差不多就是两个gunicorn worker进程的最大连接数了,这还是说明mongoDB会为每个worker 进程创建一个连接池,后面我又进行了验证,结果如下:

先把最大连接数设置为200

gunicorn workers = 2的时候使用ab -n 10000 -c 500,连接数为350个,没有超过400个,

gunicorn workers = 3的时候使用ab -n 10000 -c 500,连接数为492个,超过400个,但没有超过600个

从上面的数据可以得出压力测试之后的最大连接数是与workers 进程数有关的,差不多成比例,所以说mongoDB会为每个worker 进程创建一个连接池。

总结:对于Pymongo,调用close()会关掉连接池的所有连接,所以很不划算,考虑到端口耗尽问题,让maxPoolSize尽量小点,适中。

下面的来自pymongo docs的话:

close()

Disconnect from MongoDB.

Close all sockets in the connection pools and stop the monitor threads. If this instance is used again it will be automatically re-opened and the threads restarted.







0 0
原创粉丝点击