nginx: [emerg]无法绑定到0.0.0.0:8080(48:地址已在使用中)在mac上

9

我对Nginx还不熟悉,在这里遇到了一些问题。

我使用的是Mac OSnginx version: nginx/1.17.7

第一次下载Nginx是在一段时间之前,当时一切运行得很完美。但是当我尝试修改nginx.conf文件时,不知怎么搞就把它弄乱了。因此,今天重新开始学习Nginx时,我将之前的所有文件都删掉了,然后通过homebrew重新安装了Nginx。接着我遇到了一个问题,希望有人可以帮忙解决。

初始化Nginx后,我遇到了这个错误:

nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] still could not bind()

我在网上搜索了这个问题,看到了很多答案,但是要么是针对Linux而非Mac的解决方案,要么就是无法解决问题。

其中最有希望的一个答案是关闭那些正在使用该端口的进程顺便说一句,即使我遇到了这个错误,我仍然可以访问页面localhost:8080,但显示为403 Forbidden page然后我在终端上尝试了一个命令:ps ax -o pid,ppid,%cpu,vsz,wchan,command|egrep '(nginx|PID)' (来源)

以下是输出结果:

  PID  PPID  %CPU      VSZ WCHAN  COMMAND
21827     1   0.0  4291640 -      nginx: master process nginx
21828 21827   0.0  4301348 -      nginx: worker process
21831 93689   0.0  4267768 -      egrep (nginx|PID)

我不理解这句话的含义,所以我试着用kill -9 <PID>命令杀死了所有进程,例如kill -9 21827kill -9 21828kill -9 21831
然后我收到了错误信息:-bash: kill: (21827) - Operation not permitted。我想也许可以使用sudo来解决这个问题,于是我尝试使用sudo kill -9 21827。这次成功了,我杀死了除第三个进程外的所有进程。当我尝试使用sudo kill -9 21831时,我得到了No such process的错误。然后我发现因为某种原因,这个进程的PID在不断地变化,所以如果我没有在那个确切的时刻捕捉到该进程的确切PID,则无法将其杀死。于是我就把它放在那里了。
然后我尝试在Terminal上运行nginx。以下是输出内容:
nginx: [emerg] open() "/usr/local/var/run/nginx.pid" failed (13: Permission denied)

这一次我没有找到一个潜在可以解决问题的答案...所以我尝试通过命令 sudo nginx -s stop && sudo nginx来源)来重启nginx。但是这并没有起作用,它报告了nginx: [alert] kill(21827, 15) failed (3: No such process)。于是我尝试了在同样的来源提供的另一个答案:brew services list 然后是 brew services start nginx

但是我仍然得到了 nginx: [emerg] open() "/usr/local/var/run/nginx.pid" failed (13: Permission denied)错误消息。

现在我不知道如何解决这个问题。我也试图通过homebrew重新安装nginx。但是之前的进程仍会像之前那样弹出。

此外,我也尝试了这条命令:ps aux | grep nginx。 这给了我三个进程,直到我杀掉了进程。最终,我只剩下了

apple            22922   0.0  0.0  4267768    832 s003  S+    3:09AM   0:00.00 grep nginx

不确定这能说明什么。

有人能帮忙解决这里出了什么问题吗?或者,你能分享一下启动Nginx的正确初始步骤吗?

4个回答

7
这里有很多内容。首先,Mac OS是Linux的近亲。许多Linux解决方案/命令可以在您的Mac上直接运行。那些不能运行的通常可以修改以使它们能够工作。在某些情况下,您可能需要安装默认未安装的其他命令行工具。
其次,“ps”代表“进程状态”。正如名称所示,它是一种报告运行在您计算机上进程状态的命令(取决于您拥有的权限)。当然,有时使用“kill”终止进程是可能且必要的,但如果您不知道自己在做什么,我不建议这样做。如您发现的那样,根据您的操作系统权限/设置,您可能需要使用“sudo”进行覆盖。最好依赖nginx命令来启动和停止正在运行的nginx服务器。其中一件事情是允许这些操作被“优雅地”执行,也就是说“干净”和“没有意外的副作用”。稍后会详细介绍此事。
第三个进程在您的“ps”输出中PID不断变化的原因是该进程本身就是正在报告的“egrep”进程。每次运行命令时,都会执行一个新的“egrep”命令,并获得一个全新的PID。
在您的“ps”输出中另一个需要注意的事项是:有2个“nginx”进程。一个是主进程,另一个是工作进程。只要主进程在运行,您可以一遍又一遍地杀死工作进程,主进程将生成一个新的工作进程(具有另一个新的PID)。文档说:“主要进程的主要目的是读取和评估配置文件,以及维护工作进程。”
现在,听起来另一个进程已经使用端口8080了。您可以通过运行以下命令来发现该进程:
“lsof -nPL-iTCP:8080”
根据“lsof”命令报告的内容,您可以退出程序或终止使用报告的PID的进程。如果由于某种原因,您不能或不想终止有问题的进程,则必须更改“nginx”的配置。
正如错误消息所示,您现在在文件“/usr/local/var/run/nginx.pid”中有一个权限问题,这会防止“nginx”启动。该文件包含启动“nginx”进程时分配给其的PID。当您发布命令“nginx -s stop”时,它正在尝试从该文件中读取先前分配的PID。当其无法读取时,就会出现您看到的错误消息。
使用kill命令终止nginx进程的一个意外副作用是它们没有机会清理自己。关闭时它们要做的一件事是删除包含之前已分配PID的nginx.pid文件。好消息是,如果该文件不存在,则nginx将创建一个新文件。所以您只需要运行sudo rm /usr/local/var/run/nginx.pid,然后再运行nginx即可。

我看了你提到的步骤,但即使删除了nginx.pid文件,我仍然无法停止或重启nginx。当我运行“sudo nginx -s stop”时,我会收到“nginx:[error] open()“/usr/local/Cellar/nginx/1.21.6_1/logs/nginx.pid”失败(2:没有那个文件或目录)”的错误提示。 - Jumper
..........TL;DR - Siraj Alam

3

你遇到的问题是因为在某个地方悄悄地启动了 nginx 并且它已经在运行中。你可以停止它或者使用 ps -ef | grep nginx 命令查找并结束相关进程。


1

解决方案

在终端中运行top并搜索正在运行的NGINX进程。或者按[COMMAND] + [SPACE]键,输入activity并打开活动监视器,然后在那里搜索NGINX。 在活动进程列表中找到正在运行的NGINX实例,它在root用户下运行,请记下其PID号码。

将该PID号码单独写入/usr/local/nginx/logs/nginx.pid文件的第一行中。
打开/usr/local/config/nginx.conf并取消注释以下行:
pid log/nginx.pid

即使您已经停止了NGINX,也请再次停止它,因为现在可以使用PID号码正确地执行此操作:sudo nginx -s stop,然后再次启动它:sudo nginx
如果没有问题,它应该能够正常启动,否则请查找其他正在运行的实例并重复上述步骤。

问题原因

Nginx无法停止自己的进程,因为它不知道正在运行实例的PID号码,并且该实例绑定了相关端口,阻止第二个Nginx实例绑定到同一端口。

这发生在MacOS Ventura上。这是一个新安装的Nginx,我仍在配置/usr/local/nginx/logs/nginx.conf文件。这是因为我在NGINX运行时更改了NGINX配置文件中PID文件的位置,因此它无法停止自己,因为它不知道如何找到自己进程的PID号码。 因此,即使您尚未在/usr/local/nginx/logs/nginx.conf文件中设置PID文件位置,请立即这样做,以便NGINX可以找到其PID号码并在将来正确地停止自己。

希望这可以帮助您。


你可以使用 'pgrep nginx' 命令获取进程号,然后用 'kill -9 <pid>' 来终止它。 - Stephen Harold Smith

0

我也遇到了完全相同的问题,尝试了其他所有方法,但幸运的是,在 Mac 的“活动监视器”网络选项卡中强制退出 nginx 进程解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接