好吧,这真是太难了。我在 Ubuntu 16.04 服务器实例上运行 Apache 2.4。我对生产和测试实例使用几乎相同的环境,并且使用 Vagrant 管理用于开发的几乎相同的 VirtualBox 实例。长期以来,我能够以 Apache 所运行的同一用户身份通过 SSH 进入这些服务器实例中的任何一个,部署一些应用程序代码更改,然后运行exit
以终止 SSH 会话,之后 Apache 就可以正常运行。但是现在,我做不到,exit
因为 Apache 服务会遇到致命错误:
[mpm_prefork:emerg] [pid 23466] (43)Identifier removed: AH00144: couldn't grab the accept mutex
[core:alert] [pid 17750] AH00050: Child 23466 returned a Fatal error... Apache is exiting!
笔记:
- Apache 用户是
app
。 - 如果我以 身份运行 SSH
app
,切换到root
,restart
以 身份运行服务root
,切换回app
,然后终止会话,它会终止 Apache。 - 如果我以 的身份通过 SSH 登录
root
该restart
服务,然后终止会话,Apache 就没问题。 - 如果我以 的身份通过 SSH 使用
root
服务restart
,切换到app
,切换回root
,然后终止会话,Apache 就可以正常工作。 - 如果我以 的身份通过 SSH 登录服务
root
,restart
终止会话,再次以 的身份通过 SSH 登录app
,然后再次终止会话,那么 Apache 就会被终止。 - 本周之前,我一直能够以 的身份持续进行 SSH 操作
app
,切换到root
,restart
以 的身份运行服务root
,然后终止会话,而无需终止 Apache。 - 我尝试修改
/lib/systemd/system/apache2.service.d/apache2-systemd.conf
和将该行更改RemainAfterExit=no
为RemainAfterExit=yes
,执行systemctl daemon-reload
,最后执行,但service apache2 restart
没有任何效果。
有什么原因可以解释这种突然的行为变化吗?是否有合理的解决方案来恢复以前的行为?如果没有,那么部署应用程序代码更改并授予 Apache(用户app
)读取它的权限而无需以 身份登录 SSH 会话的最佳做法是什么root
?以 身份登录的全部原因首先app
是为了限制以 身份登录的需要。root
我完全不知所措,不明白一切怎么会突然被打破。
答案1
造成这种情况的根本原因是 systemd(自 219 起)处理登录用户创建的 IPC 对象的方式发生了变化。默认情况下,它会删除用户注销后留下的任何 IPC 对象。这适用于所有非系统用户(uid >= 1000)。系统用户(uid < 1000)不受影响。
由于您已将 Apache 更改为在非系统用户下运行,因此每当您退出该用户帐户时,systemd 都会删除 Apache 的所有 IPC 对象,然后 Apache 会抱怨丢失了互斥锁并死亡。
您可以通过设置RemoveIPC=no
(/etc/systemd/logind.conf
Ubuntu 上的默认设置是yes
)并重新启动来更改此行为systemd-logind.service
。
最好让 Apache 以系统用户身份运行(例如www-data
在 Ubuntu 上),并使用权限和 ACL 来授予www-data
其需要读/写的文件的访问权限。