虽然systemd并不是一个真正的故障定位工具,但它输出的信息为解决问题指明了方向。没有人会认为systemd是一种故障定位工具,但是当我的Web服务器遇到问题时,我对systemd及其一些功能的不断增长的了解帮助我找到并规避了这些问题。我遇到的问题是,我的服务器yorktown为我的家庭办公网络提供名称服务、DHCP、NTP、HTTPD和SendMail邮件服务,但无法在正常启动时启动ApacheHTTPD守护进程。在我意识到它没有运行后,我不得不手动启动它。这个问题已经持续了一段时间,我最近才开始尝试解决这个问题。你们中有些人会说systemd本身是问题的原因,根据我现在的理解,我同意你的看法。但是,我在使用SystemV时遇到了类似的问题。(在本系列的第一篇文章中,我探讨了围绕systemd替代遗留SystemV启动器和启动脚本的争议。如果您有兴趣了解更多关于systemd的信息,您还可以阅读第二篇文章1和3。)没有软件是完美的,systemd和SystemV也不例外,但systemd提供的解决问题的信息远比SystemV多。确定问题定位此问题根源的第一步是确定httpd服务的状态:[root@yorktown~]#systemctlstatushttpdhttpd.service-TheApacheHTTPServerLoaded:loaded(/usr/lib/systemd/system/httpd.service;已启用;供应商预设:已禁用)活动:失败(结果:退出代码)自美国东部时间星期四2020-04-1611:54:37起;15分钟前Docs:man:httpd.service(8)Process:1101ExecStart=/usr/sbin/httpd$OPTIONS-DFOREGROUND(code=exited,status=1/FAILURE)MainPID:1101(code=exited,status=1/失败)状态:“读取配置...”CPU:60msApr1611:54:35yorktown.both.orgsystemd[1]:启动ApacheHTTP服务器...4月16日11:54:37yorktown.both。orghttpd[1101]:(99)无法分配请求的地址:AH00072:make_sock:无法绑定到地址192.168.0.52:80Apr1611:54:37yorktown.both.orghttpd[1101]:没有可用的侦听套接字,正在关闭downApr1611:54:37yorktown.both.orghttpd[1101]]:AH00015:无法打开日志Apr1611:54:37yorktown.both.orgsystemd[1]:httpd.service:主进程退出,code=exited,status=1/FAILUREApr1611:54:37yorktown.both.orgsystemd[1]:httpd.service:Failedwithresult'exit-code'.Apr1611:54:37yorktown.both.orgsystemd[1]:FailedtostartTheApacheHTTPServer.[root@yorktown~]#这种状态信息是systemd的功能之一。我认为它比SystemV提供的任何功能都更有用。这里有很多有用的信息,使我很容易得出合乎逻辑的结论并使我朝着正确的方向前进。我从旧的chkconfig命令得到的只是服务是否正在运行,如果是,进程ID(PID)是什么。那没有多大帮助。此状态报告中的一个关键条目显示HTTPD无法绑定到IP地址,这意味着它无法接受传入请求。这表明网络启动不够快,因为尚未设置IP地址,因此HTTPD服务尚未准备好绑定到IP地址。这不应该发生,所以我查看了我的web服务的systemd启动配置文件;所有这些似乎都适合正确的after和requires语句。下面是我服务器上的/lib/systemd/system/httpd.service文件:#不推荐就地修改这个文件,因为更改#将在包升级期间被覆盖。要自定义#行为,运行“systemctledithttpd”来创建一个覆盖单元。#systemctledit)并输入以下内容:#[Service]#Environment=OPTIONS=-DMY_DEFINE[Unit]Description=TheApacheHTTPServerWants=httpd-init.serviceAfter=network.targetremote-fs.targetnss-lookup.targethttpd-init.serviceDocumentation=man:httpd.service(8)[Service]Type=notifyEnvironment=LANG=CExecStart=/usr/sbin/httpd$OPTIONS-DFOREGROUNDExecReload=/usr/sbin/httpd$OPTIONS-kgraceful#发送SIGWINCH优雅的停止KillSignal=SIGWINCHKillMode=mixedPrivateTmp=true[Install]WantedBy=multi-user.targethttpd.service单元文件明确指出它应该在network.target和httpd-init.service(以及其他)之后加载我尝试使用systemctllist-units命令查找所有这些服务并在结果数据流中搜索它们。所有这些服务的存在应确保在设置网络IP地址之前不会加载httpd服务。在互联网上搜索第一个解决方案,确认其他人对httpd和其他服务也有类似的问题。这似乎是由于其中一项必需的服务向systemd指示它已完成启动,而实际上它启动了一个尚未完成的子进程。通过更多搜索,我想到了一个解决方法。我不确定为什么为NIC分配IP地址需要这么长时间。所以我想,如果我可以将HTTPD服务的启动延迟一段合理的时间,那么IP地址将在那个时候分配。幸运的是,上面的/lib/systemd/system/httpd.service文件提供了一些指导。虽然说不要修改,但是指出了如何修改:使用systemctledithttpd命令,会自动创建一个新文件(/etc/systemd/system/httpd.service.d/override.conf)并打开GNUNano编辑器(如果您是Nano新手,请务必查看Nano界面底部的提示)。将以下代码添加到新文件并保存:[root@yorktown~]#cd/etc/systemd/system/httpd.service.d/[root@yorktownhttpd.service.d]#lltotal4-rw-r--r--1rootroot243Apr1611:43override.conf[root@yorktownhttpd.service.d]#catoverride.conf#Tryingtodelaythestartupofhttpdsothatthenetworkis#fullyupandrunning以便httpd可以绑定到正确的#IP地址##作者DavidBoth,2020-04-16[Service]ExecStartPre=/bin/sleep30在这个覆盖文件的[Service]部分中有一行代码,它延迟HTTPD服务的启动时间30秒。以下状态命令显示等待期间的服务状态:[root@yorktown~]#systemctlstatushttpdhttpd.service-ApacheHTTPServerLoaded:loaded(/usr/lib/systemd/system/httpd.service;enabled;供应商预设:禁用)插入:/etc/systemd/system/httpd.service.d└─override.conf/usr/lib/systemd/system/httpd.service.d└─php-fpm.conf活动:激活(start-pre)自美国东部时间周四2020-04-1612:14:29起;28s前Docs:man:httpd.service(8)CntrlPID:1102(sleep)Tasks:1(limit:38363)Memory:260.0KCPU:2msCGroup:/system.slice/httpd.service└─1102/bin/sleep30Apr1612:14:29yorktown.both.orgsystemd[1]:启动ApacheHTTP服务器...4月16日12:15:01yorktown.both.orgsystemd[1]:启动ApacheHTTP服务器。[root@yorktown~]#此命令显示30秒延迟后HTTPD服务的状态。该服务已启动并正常运行。[root@yorktown~]#systemctlstatushttpd●httpd.service-加载的ApacheHTTP服务器:加载(/usr/lib/systemd/system/httpd.service;启用;供应商预设:禁用)插入:/etc/systemd/system/httpd.service.d└─override.conf/usr/lib/systemd/system/httpd.service.d└─php-fpm.conf活动:活动(运行)自周四2020-04-1612:美国东部时间15:01;1分钟18秒前文档:man:httpd.service(8)进程:1102ExecStartPre=/bin/sleep30(code=exited,status=0/SUCCESS)MainPID:1567(httpd)Status:"Totalrequests:0;Idle/繁忙的工作人员100/0;请求/秒:0;字节服务/秒:0B/秒”任务:213(限制:38363)内存:21.8MCPU:82msCGroup:/system.slice/httpd.service├─1567/usr/sbin/httpd-DFOREGROUND├─1569/usr/sbin/httpd-DFOREGROUND├─1570/usr/sbin/httpd-DFOREGROUND├─1571/usr/sbin/httpd-DFOREGROUND└─1572/usr/sbin/httpd-DFOREGROUNDApr1612:14:29yorktown.both.orgsystemd[1]:启动ApacheHTTP服务器...4月16日12:15:01yorktown.both.orgsystemd[1]:启动了ApacheHTTP服务器。我本可以尝试更短的延迟,但我的系统并没有那么严格,所以我觉得现在的系统即使不这样做也能正常工作,所以我很高兴。由于我收集了所有这些信息,因此我将其作为Bug1825554报告给RedHatBugzilla。我相信报告错误比抱怨它们更有用。更好的解决方案将此问题报告为错误几天后,我收到回复说systemd只是一个管理工具,如果满足某些要求后需要拉起httpd,则需要在单元文件中表达。此回复将我定向到httpd.service的手册页。我希望我能早点发现这一点,因为它比我自己想出的解决方案要好得多。该方案明确针对目标前单元,而不仅仅是随机延迟。来自httpd.service手册页:默认情况下禁用在启动时提供httpd.service和httpd.socket单元。启动时启动httpd服务,执行:systemctlenablehttpd.service。在其默认配置中,httpd守护程序将接受来自任何配置的IPv4或IPv6地址的端口80上的连接(或端口443上的TLS连接,如果安装了mod_ssl)。如果httpd配置为依赖任何特定的IP地址(例如使用Listen指令),该地址可能仅在启动期间可用,或者如果httpd依赖于其他服务(例如数据库守护程序),则该服务必须配置为确保正确的启动顺序。例如,要确保httpd在所有已配置的网络接口都已配置后运行,可以使用以下代码片段创建一个插入文件(如上所述):[Unit]After=network-online.targetWants=network-online。target我仍然认为这是一个错误,因为在httpd.conf配置文件中使用Listen指令是很常见的,至少在我的经验中是这样。我一直使用Listen指令,即使在只有一个IP地址的主机上,它显然在具有多个NIC和IP地址的机器上也是必要的。在/usr/lib/systemd/system/httpd.service默认配置文件中加入以上几行,对于不使用Listen命令的不会造成问题,但是对于使用Listen命令的会避免这个问题。同时,我将使用建议的方法。后续步骤本文描述了我在服务器上启动ApacheHTTPD服务时遇到的一个问题。它向您介绍了我对解决这个问题的想法,并解释了我如何使用systemd来帮助解决这个问题。我还描述了我使用systemd实现的解决方法,以及我从错误报告中获得的更好的解决方案。正如我在开头提到的,这很可能是一个systemd问题,特别是httpd启动的配置问题。尽管如此,systemd还是提供了一些工具,使我能够找到问题的可能根源并制定和实施解决方法。这两种解决方案都没有真正让我满意地解决问题。目前,这个问题的根源仍然存在,必须解决。如果我只是在/usr/lib/systemd/system/httpd.service文件中添加推荐的代码,它对我有用。我在此过程中发现的一件事是,我需要了解有关定义服务启动顺序的更多信息。我将在我的下一篇文章(本系列的第五篇)中探讨这个领域。资源网上有大量关于systemd的参考资料,但其中大部分都有些粗略、晦涩,甚至具有误导性。除了本文中提到的材料之外,以下页面还提供了有关systemd入门的更可靠、更详细的信息。Fedora项目有一篇方便的GettingStartedwithsystemd文章,涵盖了关于使用systemd配置、管理和维护Fedora计算机所需了解的几乎所有内容。Fedora项目还有一个很好的备忘录,将过去的SystemV命令与systemd命令进行了交叉引用。有关systemd的技术细节以及创建此项目的原因,请参阅Freedesktop.org上的systemd描述。Linux.com的“更多systemd乐趣”部分提供了更多高级systemd信息和技巧。
