7

我从 php 后端作业和 php 网页日志中随机收到以下错误。有一个运行 php 后端作业和 php 网络服务器的应用服务器。两者都连接到同一个数据库服务器。使用 php mysqli 面向对象的库来连接数据库。在 my.cnf 中将最大连接数设置为 750。没有看到太多的连接。

PHP 警告:mysqli::mysqli(): (HY000/2003): Can't connect to MySQL server on '77.777.120.81' (99) in /usr/local/dev/classes/Admin.php on line 15

无法连接到 MySQL:无法连接到“77.777.120.81”上的 MySQL 服务器 (99)

4

2 回答 2

6

正如这篇Percona 数据库性能博客文章中出色描述的那样,您的问题是您的应用程序无法打开与 MySQL 服务器的另一个连接。您的本地 TCP 端口用完了。作为一种解决方案,我建议调整 TCP 参数设置

  • tcp_tw_reuse(布尔值;默认值:禁用;自 Linux 2.4.19/2.6 起)允许在从协议角度安全的情况下为新连接重用 TIME_WAIT 套接字。未经技术专家的建议/请求,不得更改。

    可以通过将 /proc/sys/net/ipv4/tcp_tw_reuse 设置为 1 来强制内核重用挂起在 TIME_WAIT 状态的连接。实际上发生的情况是,您将一直看到挂在 TIME_WAIT 中的关闭连接,直到它们中的任何一个过期或请求新连接。在后一种情况下,连接将被“重新激活”。

  • tcp_tw_recycle(布尔值;默认值:禁用;自 Linux 2.4 起)启用 TIME_WAIT 套接字的快速回收。不建议启用此选项,因为这会在使用 NAT(网络地址转换)时引起问题。

    当您启用 /proc/sys/net/ipv4/tcp_tw_recycle 时,关闭的连接将不再显示在 TIME_WAIT 下——它们完全从 netstat 中消失。但是,一旦您打开一个新连接(在 60 秒内),它就会回收其中一个。但是每个撰写此替代方案的人似乎都建议不要使用它。底线是:重用连接比回收它更可取。

  • tcp_max_tw_buckets (integer; default: see below; since Linux 2.4) 系统允许的处于 TIME_WAIT 状态的最大套接字数。此限制仅用于防止简单的拒绝服务攻击。NR_FILE*2 的默认值根据系统中的内存进行调整。如果超过此数字,则关闭套接字并打印警告。

    这个参数决定了有多少连接可以同时保持在 TIME_WAIT 状态:内核将简单地杀死挂在该状态以上的连接。例如,在服务器的 TCP 端口范围仅由 6 个端口组成的场景中,如果/proc/sys/net/ipv4/tcp_max_tw_buckets设置为 5,则打开 6 个与 MySQL 的并发连接,然后立即关闭所有 6 个,您会发现其中只有 5 个挂在 TIME_WAIT state - 与 一样tcp_tw_recycle,其中一个会简单地从netstat输出中消失。这种情况允许立即打开新连接而无需等待一分钟*

    • 在连接到数据库服务器时,许多应用程序选择仅为单个请求打开新连接,并在处理请求后立即关闭它。即使连接被客户端(应用程序)关闭,它正在使用的本地端口也不会立即被操作系统释放以供另一个连接重用:它将处于 TIME_WAIT 状态(通常)60秒——这个值不能很容易更改,因为它在内核中是硬编码的。

    但是,在 TIME_WAIT 中的其他 5 个连接之一到期并释放它正在使用的本地端口之前,第二个连接将无法打开。那么,这里的秘诀就是在可用网络端口的数量和我们允许保持在 TIME_WAIT 状态的连接数量之间找到一个折衷方案。此设置的默认值为 65536,这意味着默认情况下,系统允许所有可能的连接在关闭时超过 TIME_WAIT 状态。

PS:您的问题还有更多可能的解决方案,请阅读全文以获取问题的详细描述。
于 2016-11-16T19:11:36.300 回答
1

更新 1

tcp_tw_reuse看起来更好的解决方案。这里描述了原因:

tcp_tw_reuse vs tcp_tw_recycle :使用哪个(或两者)?

原始答案

mysql 错误 (99)表示您的 tcp 端口已用完。

启用 tcp recycle 应该可以修复它。

echo 1 >/proc/sys/net/ipv4/tcp_tw_recycle 

学分

于 2016-11-15T00:08:44.237 回答