我正在运行 Nginx 1.6.2(nginx-full
来自nginx/stable
PPA 的软件包)。我正在使用未修改的配置/etc/nginx/nginx.conf
:
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
如果我进行以下站点配置并将其链接到sites-enabled
:
# /etc/nginx/sites-available/serve-files
server {
listen unix:/run/serve-files.socket;
root /var/www/files;
location / {
try_files $uri =404;
}
}
并重新启动 nginx(使用),使用以下权限创建sudo service nginx restart
套接字:/run/serve-files.socket
srw-rw-rw- 1 root root 0 Oct 29 14:35 serve-files.socket
如果我随后停止 nginx(使用sudo service nginx stop
),套接字会意外保留。当我启动 nginx 备份(使用sudo service nginx start
)时,我收到以下错误报告/var/log/nginx/error.log
:
2014/10/29 14:36:32 [emerg] 21680#0: bind() to unix:/run/serve-files.socket failed (98: Address already in use)
2014/10/29 14:36:32 [emerg] 21680#0: bind() to unix:/run/serve-files.socket failed (98: Address already in use)
2014/10/29 14:36:32 [emerg] 21680#0: bind() to unix:/run/serve-files.socket failed (98: Address already in use)
2014/10/29 14:36:32 [emerg] 21680#0: bind() to unix:/run/serve-files.socket failed (98: Address already in use)
2014/10/29 14:36:32 [emerg] 21680#0: bind() to unix:/run/serve-files.socket failed (98: Address already in use)
2014/10/29 14:36:32 [emerg] 21680#0: still could not bind()
看来 nginx 不会覆盖上次关闭时留下的套接字。为什么是这样?我是否配置错误?有办法解决这个问题吗?
注意:没有其他站点在运行 nginx,当我停止 nginx 时,没有任何延迟进程,并且我在运行 14.04.1 LTS 的 Ubuntu 服务器和桌面上重现了这一点。
更新:当 nginx 运行时,netstat -lx | grep serve-files
将指示套接字正在使用:
unix 2 [ ACC ] STREAM LISTENING 6543310 /run/serve-files.socket
当 nginx 停止时,netstat -lx | grep serve-files
表示没有使用套接字(如预期),但套接字文件仍保留在/run/serve-files.socket
.
答案1
根据 Nginx 文档,信号退出将执行“正常关闭”信号术语将执行“快速关闭”。至少从版本 1.8.0 开始,Nginx 在停止使用时将留下过时的 UNIX 域套接字信号退出信号。但是,使用以下命令时,UNIX 域套接字会被正确删除:信号术语信号。
/etc/init.d/nginx
PPA提供的Nginx 服务脚本nginx/stable
发送信号退出sudo service nginx stop
当 Nginx 用或停止时,发送给 Nginx restart
。要修补脚本,请修改以下行:
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}"
到:
STOP_SCHEDULE="${STOP_SCHEDULE:-TERM/5/KILL/5}"
但是,Ubuntu 存储库中的 Nginx 服务脚本已经使用信号术语代替信号退出并且不需要修改。
答案2
我不认为这与优雅或快速关闭有关,因为我一直在使用优雅的停止我也遇到这个问题。
就我而言,我注意到可能相关/附加的问题,nginx
即使在套接字和对它的所有调用都已被删除之后,仍然继续尝试连接到一个早已不存在的套接字(至少到目前为止,我故意创建或更改)。
将套接字放入/tmp
似乎是一种可以避免此问题的解决方法,但我仍然无法摆脱以前在其他地方创建的幽灵套接字。
所以我不明白问题出在哪里。你什么时候nginx
决定记住永远是一个套接字,有没有办法重置它?
答案3
作为 16.04 Xenial 的快速修复,我只需删除有问题的套接字:
sudo systemctl stop nginx
sudo rm /var/run/serve-files.socket
sudo systemctl start nginx