从大约2周开始,我正在处理LAMP堆栈中最奇怪的问题之一 . 长篇短信随机连接到MySQL服务器失败,并显示错误消息:
Warning: mysqli::real_connect(): (HY000/2002): Cannot assign requested address in ..
MySQL处于不同的“盒子”,托管在Rackspace Cloud今天我们将它的版本降级为
Ver 14.14 Distrib 5.1.42, for debian-linux-gnu (x86_64).
根据它的状态变量,DB服务器非常忙于处理每秒查询数:5327.957 .
MySQL处于log-warnings = 9但没有记录连接拒绝的争用 . 站点和齿轮工作者脚本都会因为错误而失败,假设概率为1% . 没有服务器负载似乎不是我们监控的因素 . (CPU负载,IO负载或MySQL负载)最大数据库连接数(max_connections)设置为200但我们从未与数据库同时连接超过100个连接
它有和没有防火墙软件 .
我怀疑TCP网络问题而不是PHP / MySQL配置问题 .
任何人都可以告诉我如何找到它?
更新:
连接代码是:
$this->_mysqli = mysqli_init();
$this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 120);
$this->_mysqli->real_connect($dbHost,$dbUserName, $dbPassword, $dbName);
if (!is_null($this->_mysqli->connect_error)) {
$ping = $this->_mysqli->ping();
if(!$ping){
$error = 'HOST: {'.$dbHost.'};MESSAGE: '. $this->_mysqli->connect_error ."\n";
DataStoreException::raiseHostUnreachable($error);
}
}
4 回答
使用Vicidial我经常遇到同样的问题,由于所使用的编程类型,必须(非常)频繁地从许多vicidial组件 Build 新的MYSQL连接,我们有系统锤击数据库服务器每秒超过10000个连接,其中大部分都在几毫秒内完成服务,并在一秒或更短的时间内关闭 . 根据经验,我可以告诉您,在本地网络中,几乎没有丢失的软件包,tcp_fin_timeout可以一直降低到3而不会出现任何问题 .
用于诊断等待关闭的连接是否是您的问题的典型linux命令是:
这将显示等待完全关闭的连接数 .
它将显示每个连接主机的连接,允许您识别哪个其他主机正在折叠您的系统(如果有多个候选者) .
要测试修复,你可以
这将暂时将tcp_fin_timeout设置为3秒,并告诉您它之前的秒数,因此您可以恢复到旧值进行测试 .
作为永久性修复,我建议您将以下行添加到/etc/sysctl.conf中
在一个良好的本地网络内,不应该造成任何麻烦,如果你遇到问题,例如因为丢包,你可以试试
Wiche允许更多时间连接关闭并尝试重用相同的ip:端口组合,以便与同一主机:服务组合的新连接 .
要么
哪个会更积极地尝试重用连接,但是可以通过您的网络服务器为其他应用程序创建新问题 . 所以你应该首先尝试简单的解决方案,在大多数情况下,它已经解决了你的问题,没有任何不良副作用!
祝好运!
Vicidial服务器经常需要增加MySQL中的连接限制 . 许多安装(我们已经看到并在很多设备上工作)必须通过修改限制来实现
此外,有报道称conntract_Max需要增加
当问题变成网络相关时 .
另请注意,Vicidial具有一些特定的建议设置,甚至还有一些用于mysql配置的企业设置 . 看看/ usr / src / astguiclient / conf中的my-bigvici.cnf中的一些配置想法可能会打开你的mysql服务器 .
到目前为止,连接限制没有增加,只使用了额外的资源 . 由于服务器的目的是使该应用程序工作,因此将资源专用于此应用程序似乎不是问题 . 大声笑
我有这个问题,并使用持久连接模式解决了它,可以通过使用'p:'预先修复数据库主机名在mysqli中激活它
来自:http://php.net/manual/en/mysqli.persistconns.php:
MySQL: Using giant number of connections
频繁连接有什么危险?
它运作良好,除了一些极端情况 . 如果您从同一个盒子每秒获得数百个连接,则可能会耗尽本地端口号 . 修复它的方法可能是 - 在linux上减少"/proc/sys/net/ipv4/tcp_fin_timeout"(这打破了TCP / IP标准,但你可能不关心你的本地网络),在客户端增加"/proc/sys/net/ipv4/ip_local_port_range" . 其他OS有类似的设置 . 您也可以为同一个数据库主机使用更多Web框或多个IP来解决此问题 . 我真的在 生产环境 中看到了这一点 .
关于这个问题的一些背景:
TCP / IP连接由localip:localport标识remoteip:远程端口 . 在这种情况下,我们有MySQL IP和端口以及客户端IP固定,所以我们只能改变有限范围的本地端口 . 注意 even after you close connection TCP/IP stack has to keep the port reserved for some time ,这是tcp_fin_timeout来自的地方 .