我们所有的错误都logging到NewRelic,我们总是在错误日志中看到session_write_close的一些警告。 但是,错误率增加了,现在正在淹没我们的24h日志。
我们的服务器是高度填充的,并且很多用户同时login。 大多数这些用户不会看到这些session_write_close警告。 有些是这样做的,这使我们几乎不可能find原因并加以解决。
这是完整的错误信息:
Error message E_WARNING: session_write_close(): Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/opt/php55/var/lib/php/session-nginx)
所以我做了一个检查,看看目录9431有多less个文件,以及哪些权限是-rw------- 1 nginx nginx 。
我没有看到我的configuration,文件权等问题。
我们没有select。 我能做些什么来解决这个问题? 目前影响<1%的用户,我们只是想保持尽可能低的利率。
这里是我的php.iniconfiguration列表。
Directive Local Value Master Value session.auto_start Off Off session.cache_expire 180 180 session.cache_limiter nocache nocache session.cookie_domain no value no value session.cookie_httponly Off Off session.cookie_lifetime 0 0 session.cookie_path / / session.cookie_secure Off Off session.entropy_file /dev/urandom /dev/urandom session.entropy_length 32 32 session.gc_divisor 1000 1000 session.gc_maxlifetime 1440 1440 session.gc_probability 1 1 session.hash_bits_per_character 5 5 session.hash_function 0 0 session.name PHPSESSID PHPSESSID session.referer_check no value no value session.save_handler files files session.save_path /opt/php55/var/lib/php/session-nginx /opt/php55/var/lib/php/session-nginx session.serialize_handler php php session.upload_progress.cleanup On On session.upload_progress.enabled On On session.upload_progress.freq 1% 1% session.upload_progress.min_freq 1 1 session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS session.upload_progress.prefix upload_progress_ upload_progress_ session.use_cookies On On session.use_only_cookies On On session.use_strict_mode Off Off session.use_trans_sid 0 0
一些服务器统计:CentOS 6.6 PHP 5.5.28 Nginx 1.6.2欢迎任何帮助!
有了一个高负载的服务器,我会使用memcached (甚至redis ?)会话存储。 所以,如果我处于你的境地,我可能只是为了自己的利益而设置,然后看看问题是否偶然地消失了。
我也不会使用PHP的会话垃圾收集,挂起的Web请求作业的垃圾收集。 我会自己设定一个工作来处理这个问题,要么从cron运行,要么从某个排队系统运行。
在php会话垃圾收集之外,你是否已经有了任何types的会话清理系统?
这是发生在0.1%的时间,这将符合您的session.gc_divisor设置?
您的php进程是否以nginx用户身份运行? 这是基于session.gc_*设置进行清理的php而不是nginx。 如果php运行的是nginx,这对于访问php会话文件来说是很好的,但是在与nginx服务器共享一个用户id方面可能是不好的。
您可能需要该会话目录的执行权限,以便您的垃圾回收可以看到有什么清理。
如果你没有将session.save_path设置为特定于你的应用程序的东西,我也会担心。 这意味着如果您有多个应用程序共享相同的会话目录,那么当垃圾回收运行时,最短截止时间的应用程序将胜出,清除其他应用程序的会话。
我从你的问题中得出的明显的观察结果是,你将文件保存到/ opt / php55 / var / lib / php / session-nginx有太多的瓶颈。 所以你的解决scheme是缓解瓶颈,首先诊断出什么地方出了问题。
假设它正在竞速,写入磁盘,错误是它放弃的标志,我希望dmesg错误显示问题写入磁盘。 如果是这样的话,你可以写入内存,或者其他解决scheme,这些解决scheme相当于一个更快的“磁盘”。
mc0e提到memcached而不是使用save_handle = files,这是一个不错的select。 memcached的替代scheme可能是使用tmpfs,它基本上将会话放在内存中(所以写入时间很快),但不需要新的应用程序。
我还会问这个问题/ opt / php55 / var / lib / php / session-nginx是什么types的文件系统? 对于基本上是mktmptypes的操作,您不需要所有复杂的ext3 / 4日志logging。 您可能需要在/ tmp中创build一个文件夹并将其符号链接到位以确保创build文件的开销较小。
什么是硬件设置? 如果这是一个没有caching的单个磁盘,那么如果你正在调整它的性能极限,你应该会在dmesg中看到问题。 我在所有的服务器上都使用了带有Raid-1的AMCC Raid控制器。 如果是Raid-1(镜像),读取速度会很快,但是写入速度取决于raid的实现程度(我知道AMCC可以在Raid-1中的磁盘间传播写入,但不是所有的RAID-1实现这样做,我知道软件RAID没有)。 由于这个原因,我的老板发誓Raid-5,只要是真正的硬件RAID(如果不是RAID-5就可能在CPU上很贵),这将大大加快你的磁盘吞吐量。 另一个select是固态硬盘,但是如果你走这条路,我会build议使用memcached或tmpfs,因为更多的内存总是一个很好的计划(通过任何其他新的硬件)。
最简单的解决方法是创build/ tmp / session-nginx和符号链接,或者将/ opt / php55 / var / lib / php / session-nginx挂载到/ tmp / session-nginx /
部分问题是难以跟踪这些types的错误,那么我可能会build议在try / catch块中显式closures代码中的会话。 处理exception,睡觉,然后再试一次。
问题的另一部分描述了一个似乎是随机性的写错误。 这不是我所期望的不正确的权限。 我会怀疑你有太多打开的文件。
有几个configuration我会调整看看会发生什么:
增加打开的文件的限制,你可能有一些下限设置在你的操作系统的一部分。 例如,我的笔记本支持成百上千个打开的文件,但只有4000个来自同一个用户。
降低maxrequestperchilds到1000这将使每个http服务器在服务1000个客户端后重新启动。
减lessMaxClients并增加ListenBacklog 。 这是非常违反直觉的,但是如果你将MaxClients / Servers设置得太高,很多进程将争夺你的服务器资源并造成瓶颈。 这很大程度上取决于你所拥有的瓶颈。 我的是数据库服务器。