connect() to unix:/xxx/www.sock failed (11: Resource temporarily unavailable) while connecting to up


## Error现象 ##
linux连接socket错误 11: Resource temporarily unavailable

常见于Redis、MySQL、PHP-fpm这些应用连接socket时出现错误。

一般系统处于高负载时会出现Error,导致服务不可用。例如使用Nginx代理时,业务出现502 Bad Gateway,常见如下日志:

...
[error] 10615#0: *172810754 connect() to unix:/xxx/www.sock failed (11: Resource temporarily unavailable) while connecting to upstream
...
定位原因
系统net.core.somaxconn值过低导致backlog不够用。

原理
net.core.somaxconn是Linux中的一个内核(kernel)参数,表示socket监听(listen)的backlog上限。学习更多:https://www.cnblogs.com/my-show-time/p/15206020.html

对于一个TCP链接,Server与Client需要通过三次握手来建立网络链接,当三次握手成功之后,我们就可以看到端口状态由LISTEN转为ESTABLISHED,接着这条链路上就可以开始传送数据了

net.core.somaxconn是Linux中的一个内核(kernel)参数,表示socket监听(listen)的backlog上限。

什么是backlog?backlog就是 socket的监听队列,当一个请求(request)尚未被处理或者建立时,它就会进入backlog。

而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。

当Server处理请求较慢时,导致监听队列被填满后,新来的请求就会被拒绝。

backlog参数主要用于底层方法int listen(int sockfd, int backlog), 在解释backlog参数之前,我们先了解下tcp在内核的请求过程,其实就是tcp的三次握手:

1.client发送SYN到server,将状态修改为SYN_SEND,如果server收到请求,则将状态修改为SYN_RCVD,并把该请求放到syns queue队列中。

2.server回复SYN+ACK给client,如果client收到请求,则将状态修改为ESTABLISHED,并发送ACK给server。

3.server收到ACK,将状态修改为ESTABLISHED,并把该请求从syns queue中放到accept queue。

在linux系统内核中维护了两个队列:syns queue和accept queue

syns queue
用于保存半连接状态的请求,其大小通过/proc/sys/net/ipv4/tcp_max_syn_backlog指定,一般默认值是512,不过这个设置有效的前提是系统的syncookies功能被禁用。互联网常见的TCP SYN FLOOD恶意DOS攻击方式就是建立大量的半连接状态的请求,然后丢弃,导致syns queue不能保存其它正常的请求。
 accept queue

用于保存全连接状态的请求,其大小通过/proc/sys/net/core/somaxconn指定,在使用listen函数时,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值。

如果accpet queue队列满了,server将发送一个ECONNREFUSED错误信息Connection refused到client。

解决方法
Linux系统net.core.somaxconn默认值128,查看方法如下

sysctl net.core.somaxconn
调高该值

立即修改

sysctl -w net.core.somaxconn=65535
配置文件修改

echo "net.core.somaxconn=65536" >> /etc/sysctl.conf
sysctl -p
重启相关服务,比如Redis、MySQL、PHP-fpm,业务恢复正常。

=========================================================================

错误消息表明由于资源不可用,与 PHP-FPM 套接字的连接失败。这可能是由于对服务器的请求数量过多,超出了服务器可以处理的最大连接数。

尝试增加服务器可以处理的最大连接数

可以通过修改文件中的pm.max_children和pm.max_requests设置来实现此目的php-fpm.conf。

还可以尝试增加pm.max_requests设置来限制每个子进程在终止之前可以处理的请求数。

进行这些更改后,需要重新启动 PHP-FPM 服务以使更改生效。

以下是如何将设置增加到 50 的示例pm.max_children:

/usr/local/php74/etc/php-fpm.d  

pm.max_children = 50

pm.max_requests = 4000

/etc/init.d/php-fpm restart 
套接字的最大连接数已超出

这种情况的发生也有可能因为操作系统拒绝了 nginx 连接 Unix 套接字的尝试。原因可能是套接字的最大连接数已超出,或者套接字的最大未处理连接数已达到。

要检查限制,请运行:

sysctl net.core

net.core.somaxconn = 128
net.core.netdev_max_backlog = 200
出现该错误的原因是最大连接数为128,而最大未处理连接数为200。

要更改限制,请将以下行更改为 /etc/sysctl.conf 文件:

net.core.somaxconn = 20000
net.core.netdev_max_backlog = 65535

重新启动 php-fpm:

/etc/init.d/php-fpm restart 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值