NGINX 重启时信号量变为孤立信号量(4294967295)

NGINX 重启时信号量变为孤立信号量(4294967295)

每次重新启动 NGINX 时,都会留下两个信号量数组。鉴于信号量是一种有限的共享资源——服务器总是缓慢地向配额限制失败的方向倾斜。

重启后留下的信号量归“4294967295”(-1)所有,权限为 600。除非重启,否则它们不会通过传统方式被删除,例如:

$ sudo ipcrm -s 5111851  
cannot remove id 5111851 (Operation not permitted)

以前有人处理过这个问题吗?显然,找到一种方法来通过 NGINX 配置阻止孤立数组是非常棒的,但除此之外,我完全赞成修改 init.d 脚本来清理遗留的信号量数组,我似乎无法使用标准 ipc* 实用程序删除它们。

除了重新启动之外,有没有其他方法可以删除分配给不存在用户的信号量数组?

$ sudo ipcs -st
------ Semaphore Operation/Change Times --------
semid    owner       last-op   last-changed
...
9568370  4294967295  Not set   Fri Feb 13 03:38:02 2015 <-- logrotate
9601139  4294967295  Not set   Fri Feb 13 03:38:02 2015
9633908  4294967295  Not set   Sat Feb 14 03:31:06 2015
9666677  4294967295  Not set   Sat Feb 14 03:31:06 2015
9764982  4294967295  Not set   Sun Feb 15 03:47:06 2015
9797751  4294967295  Not set   Sun Feb 15 03:47:06 2015
9830520  4294967295  Not set   Mon Feb 16 03:37:02 2015
9863289  4294967295  Not set   Mon Feb 16 03:37:02 2015
9994362  4294967295  Not set   Mon Feb 16 11:34:08 2015 <-- manual restart
10027131 4294967295  Not set   Mon Feb 16 11:34:08 2015
10125436 4294967295  Not set   Mon Feb 16 13:47:25 2015
10158205 4294967295  Not set   Mon Feb 16 13:47:25 2015
10256510 4294967295  Not set   Mon Feb 16 13:52:47 2015
10289279 4294967295  Not set   Mon Feb 16 13:52:47 2015


$ nginx -V
nginx version: nginx/1.6.2
TLS SNI support enabled
configure arguments: 
--prefix=/usr/share/nginx 
--sbin-path=/usr/sbin/nginx 
--conf-path=/etc/nginx/nginx.conf 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body 
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy 
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi 
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi 
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi 
--pid-path=/var/run/nginx.pid 
--lock-path=/var/lock/subsys/nginx 
--user=nginx 
--group=nginx 
--with-file-aio 
--with-ipv6 
--with-http_ssl_module 
--with-http_spdy_module 
--with-http_realip_module 
--with-http_addition_module 
--with-http_xslt_module 
--with-http_image_filter_module 
--with-http_geoip_module 
--with-http_sub_module 
--with-http_dav_module 
--with-http_flv_module 
--with-http_mp4_module 
--with-http_gunzip_module 
--with-http_gzip_static_module 
--with-http_random_index_module 
--with-http_secure_link_module 
--with-http_degradation_module 
--with-http_stub_status_module 
--with-http_perl_module 
--with-mail 
--with-mail_ssl_module 
--with-pcre --with-debug 
--add-module=/builddir/build/BUILD/nginx-1.6.2/modsecurity-2.8.0/nginx/modsecurity 
--add-module=/builddir/build/BUILD/nginx-1.6.2/ngx_cache_purge-2.1 
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector 
--param=ssp-buffer-size=4 -m64 -mtune=generic' 
--with-ld-opt=-Wl,-E

CentOS 6,NGINX 1.6.2。

答案1

您可能需要升级到 nginx 1.8 - 这为我解决了信号量泄漏问题(至少乍一看如此)

答案2

我没有找到问题的根源,但这里有一个解决方法。

/etc/init.d/nginx,找到 stop() 函数并在之前添加以下行return $retval

ipcs -s | grep "4294967295" | awk ' { print $2 } ' | xargs -I  % ipcrm -s %

nginx 脚本更改

通过此更改,sudo service nginx restart现在应该清除旧的信号量数组。

首先,无法删除信号量怎么办?这与 sudo 权限不在整个命令中级联有关。切换到 root 不会遇到此类问题。

[user@example ~]$ sudo ipcs -s | grep "4294967295" | awk ' { print $2 } ' | xargs -I  % ipcrm -s %
ipcrm: permission denied for id (819214)
ipcrm: permission denied for id (851983)
ipcrm: permission denied for id (1114130)
[user@example ~]$ sudo -i
[root@example ~]# ipcs -s | grep "4294967295" | awk ' { print $2 } ' | xargs -I  % ipcrm -s %
[root@example ~]# 

相关内容