本文目录

1. 情景描述
2. 配置环境
3. 解决方案
4. 问题分析
5. 总结

情景描述

  vps配好了基本的typecho博客环境后,重启了一下打算看看结果,于是喜闻乐见地502了,赶紧上服务器端查看,systemctl status php-fpm -l返回的结果是failed to start php-fpm(timout)(下图)。

php-fpm启动失败

php-fpm在重启时无法自行启动 提示failed(timeout),但手动运行

    systemctl restart php-fpm    

后却能够正常启动,重试几次后发现这是一个仅在启动时出现的问题,经过数次排查和万能谷狗大法,终于找出了解决的方法,现将解决方案按照建议程度从高到地在下一节列出,以供需要者使用。

解决方案

方案一:安装haveged方法来源

linux系统对服务进程的管理与随机数密切相关,而haveged就是一款能帮助linux系统生成随机数的工具,具体描述见haveged的github首页,这一解决方案由笔者亲自实验可行。
使用apt安装haveged

    sudo apt install -y haveged

(补充)在有关文档中指出haveged由于长期未更新而不予推荐,不过目前haveged仍在更新中,是否使用就请根据个人情况判断了。

方案二:在systemd设置中加长对fpm超时时间的限制方法来源

ubuntu从16.04LTS版本开始放弃sysv改用systemd管理系统服务,放宽systemd对php-fpm服务超时的判定标准即可
运行以下命令

    sudo vi /etc/systemd/system/multi-user.target.wants/php7.2-fpm.service

并写入

TimeoutStartSec=300s
TimeoutStopSec=300s

按Esc输入:wq保存退出并重启服务

方案三:直接更改systemd的超时设置方法来源

既然可以更改对fpm的超时限制,当然也可以更改systemd对于所有任务的超时限制(但若把握不好度能因此出现其他的衍生问题故不推荐)

    vi /etc/systemd/system.conf

并增大以下设置的数值

DefaultTimeoutStartSec
DefaultTimeoutStopSec

按Esc输入:wq保存并退出

方案四:将php-fpm的任务重启设为常驻(有消耗服务器资源的风险)方法来源

不推荐使用!
不推荐使用!!
不推荐使用!!!

即每隔一定时间(3s)检测并重启服务

同样使用文本编辑器打开/etc/systemd/system/文件夹内的php-fpm.service文件

    vi /etc/systemd/system/multi-user.target.wants/php7.2-fpm.service

添加

Restart=always
RestartSec=3 

按Esc输入:wq保存并重启服务。

问题分析

首先想到的是配置出了问题,打开errorlog、syslog之类的日志文件翻找,结果什么也没看出来,遂百度之

然而查到的大多是“request_terminate_timeout”、“request_slowlog_timeout”之类的问题,根据指示在安装路径下的配置文件php-fpm.conf和php.ini、www.conf中找来找去,还是没有发现能导致启动timeout的语句

无奈之下转战谷狗,“fpm failed start timeout”,还真找到了一些相关的讨论
谷狗大法好

谷狗大法好啊

找到的网页中,许多回复提到“failed to start after reboot”,其中又以云主机上的系统居多,比较典型的有linode主机4.17.x版本内核的问题(见方案二链接)以及DO的主机上(见方案四链接)。

并且出现问题的多是16.06LTS及以上版本的ubuntu系统、centos7及以上版本和7.1以上版本的php-fpm。这就很奇怪了,难道新版本有什么新特性导致了这种bug的发生吗?

提到ubuntu 16.04与之前版本的区别,最容易想到的应该就是init被systemd所取代这件事(centos7同上),而启动并提示我们php-fpm超时的也正是systemd,也就是说超时与systemd本身应该有着某种联系。

于是继续查找,在github中找到了关于libsodium在启动时超时导致php-fpm启动timeout的讨论(方案一链接),并举例出官方文档以指出云主机在初始化时调用libsodium而可能导致的超时问题,Archlinux的讨论版中找到了“systemd等待的时间过短”这样的解释,综合其他观点,得出这样一个结论:

“systemd由于产生随机数的算法问题影响启动速度,从而kill掉了受到影响的php-fpm”

由于云主机和少数虚拟机在对libsodium的支持上有一些问题,导致随机值的熵不够而造成系统初始化效率下降。

  关于查看系统熵值的方法和更多解释请移步这里

快速安装了haveged,至此问题解决,万岁!乌拉!


总结

  笔者并非什么环境变量都自己设置好然后编译安装的大牛,不用一键安装包也只是限于服务器配置和希望多一些可选择的余地,网上关于个人用linux+nginx+sqlite+php搭建typecho博客的中文的资料文档实在是难找,没有前人铺路只好自己来总结,也希望这篇博文能帮助到有需要的读者,笔者才疏学浅,关于系统和软件的观点若有错误还强读者多多包涵,不吝指正!

引用内容及链接
1.https://download.libsodium.org/doc/usage/
解释了libsodium的用途(安全)和比haveged更好的选择:Jitterentropy
2.https://www.linode.com/community/questions/17135/php72-fpmservice-failing-after-reboot-nginx-error-502
提到了php7.2-fpm在linode的vps上启动时遇到timeout问题并指出原因可能与linode kernel版本有关 据称换回4.16及以下版本或ubuntu kernel有助于解决问题(可能已经修复);另一种解决的方案是在systemd的设置中针对fpm加入延迟启动
3.https://github.com/jedisct1/libsodium-php/issues/94
提到了fpm启动时timeout错误并提出一种解决方案:安装haveged或回退使用7.0版本的PHP-fastcgi-manager
4.https://github.com/oerdnj/deb.sury.org/issues/833
提到在kvm架构上的vps也有这种情况的发生但php7.1-fpm并不会出现,并指出这种情况似乎仅在云主机上出现,一种解决的方案是将systemd的任务重启设为常驻 即每隔一定时间(3s)检测并重启服务(有内存风险)
5.https://github.com/jedisct1/libsodium-php/issues/111
提到在虚拟机上也会出现这样的情况(centos7 over VMare)
6.https://unix.stackexchange.com/questions/412996/services-timed-out-at-boot-but-could-start-manually-what-could-be-the-problem
提出通过更改systemd或服务本身的超时设置可以解决
7.https://bbs.archlinux.org/viewtopic.php?id=170127
提到在Archlinux早期版本上也出现过的类似情况并提供相应的patch(或将/etc/systemd/system/php*-fpm.service中的fpm启动选项改为-daemonize,默认为-nodaemonize)
8.https://bugs.archlinux.org/task/37007
Archlinux上的相关情况(同样附有patch地址)
9.https://forums.fedoraforum.org/showthread.php?311729-php-fpm-fails-on-boot-but-works-when-manually-started
在fedora上出现的同样问题

文章版权:备长炭

本文链接:https://charcoalblog.top/index.php/archives/3/

转载请注明文章原始出处 !

仅有一条评论

  1. lbq lbq
    回复

    zzy zzy.jpg

添加新评论

百度已收录
返回顶部