Heim  >  Artikel  >  Backend-Entwicklung  >  nginx - mysql+php如何解决大并发下端口映射不足的问题

nginx - mysql+php如何解决大并发下端口映射不足的问题

WBOY
WBOYOriginal
2016-06-06 20:28:071496Durchsuche

现在的情况是小规模 1mysql服务器1web服务器 数据操作很快 几十ms级的处理逻辑
但是每次访问本地都会映射出一个端口来去访问3306 这样在大并发的情况下端口就会映射不出来了
比如秒并发有500 30秒就够映射出15000个端口 但是linux默认释放time_wait要60s
试过pdo的持久化连接似乎没什么用
配了unixodbc 开启pooling 大概有20%的概率崩溃 php-fpm直接被干死了
另外这个场景比较简单 整个系统只会开启一种连接 不存在根据权限或者场景切换连接的情况

回复内容:

现在的情况是小规模 1mysql服务器1web服务器 数据操作很快 几十ms级的处理逻辑
但是每次访问本地都会映射出一个端口来去访问3306 这样在大并发的情况下端口就会映射不出来了
比如秒并发有500 30秒就够映射出15000个端口 但是linux默认释放time_wait要60s
试过pdo的持久化连接似乎没什么用
配了unixodbc 开启pooling 大概有20%的概率崩溃 php-fpm直接被干死了
另外这个场景比较简单 整个系统只会开启一种连接 不存在根据权限或者场景切换连接的情况

Nginx和PHP-FPM用UNIX Domain Socket通信(不经过TCP),
PHP-FPM跟MySQL用持久连接(一个FPM工作进程保持一个到MySQL的长连接),
这样可以避免频繁创建TCP短连接而导致TIME_WAIT连接过多的问题.

下图即是2个PHP-FPM工作进程跟MySQL建立了2个持久的数据库连接,连接没有操作时处于Sleep状态:
nginx - mysql+php如何解决大并发下端口映射不足的问题

<code><?php $dsn = "mysql:dbname=mysql;host=127.0.0.1;port=3306;charset=utf8";
$dbh = @new PDO($dsn, 'root', 'root_pass', array(
    PDO::ATTR_PERSISTENT => true,
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
));
print_r($dbh);
// mysql -uroot -p -e "show processlist"
// sudo netstat -antp|egrep "php|mysqld"|grep ESTABLISHED</code>

保持php脚本尽快执行完毕,延迟大的操作放队列去,这样500并发30秒的话,释放端口就会很快了(或者tcp连接是reuse就很快可以被重用).
假如你连接mysql或者你的http被连接时,不是正常断开,如连mysql没有close,或者http请求不等返回直接关闭,会出现time_wait,系统回收time_wait很费劲,最后导致端口被消耗完了.
time_wait产生原因可以找资料看看断开连接时四次握手的资料.

如果并发实在太大就考虑分布式了

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn