前几天遇到了这样的问题。
在一台 Godaddy Linux 环境的 VPS 中,我编译安装了 Nginx、PHP 和 MySQL。由于服务器上运行的网站比较多,我选择安装 eAccelerator 来缓存 PHP,以提高网站的响应速度。
eAccelerator 编译完成后,通过模块的方式载入 PHP,一切运行都很正常。
但是后来通过 eaccelerator_control.php 控制脚本查看缓存状态时,发现共享内存只有 32M。
于是我想把缓存空间调大一些,将:
eaccelerator.shm_size = "128"
设置为 128M。
修改配置并重启服务之后,却发现:
PHP-FPM 无法启动。
而且启动的时候没有看到明显的错误提示。
为什么 PHP-FPM 无法启动?
后来查找了很多资料,最终在 GitHub 上找到了相关说明。
其中的核心意思是:
eaccelerator.shm_size 用来控制 eAccelerator 用于缓存 PHP 脚本的共享内存大小,单位是 MB。
例如:
eaccelerator.shm_size = 128
表示希望分配 128MB 的共享内存用于缓存。
但是,这个值并不是完全由 eAccelerator 自己决定的。
在 Linux 系统中,共享内存的大小还受到内核参数:
/proc/sys/kernel/shmmax
的限制。
如果 eAccelerator 需要分配的共享内存超过了系统允许的最大值,就可能导致 eAccelerator 初始化失败,进一步导致 PHP-FPM 启动失败。
也就是说:
eaccelerator.shm_size 设置得再大,如果系统的 shmmax 没有跟着调整,也不一定能够正常工作。
如何查看系统的 shmmax?
可以直接查看:
cat /proc/sys/kernel/shmmax
这里显示的是系统允许的共享内存上限,单位是 字节。
如果这个值小于你希望设置的共享内存大小,就需要对它进行调整。
临时修改 shmmax
第一种方法是直接修改:
echo value > /proc/sys/kernel/shmmax
例如需要设置为 128MB,可以根据实际需要换算成对应的字节数。
这种方式修改后会立即生效,但是有一个缺点:
系统重启以后,这个设置会恢复。
所以这种方法更适合临时测试。
永久修改 shmmax
如果希望系统重启以后仍然保持这个设置,可以修改:
/etc/sysctl.conf
增加:
kernel.shmmax = value
保存后,再让系统重新加载 sysctl 配置。
这样设置以后,系统重启也可以保留这个参数。
解决问题
按照这个方法调整系统共享内存限制后,我再次启动 PHP-FPM:
service php-fpm restart
这次 PHP-FPM 就可以正常启动了。
问题也就解决了。
这次遇到的问题比较有意思,表面上看起来只是:
eaccelerator.shm_size = 128
设置大了一些。
但实际上,真正限制它的并不是 eAccelerator 本身,而是 Linux 内核对共享内存大小的限制。
所以,在 Linux 环境下配置类似的缓存或共享内存参数时,不能只关注应用程序本身的配置文件,还需要注意操作系统层面的限制。
附:什么是共享内存?
共享内存(Shared Memory)是一种进程之间共享数据的机制。
多个进程可以通过同一块内存区域交换数据,相比使用文件等方式进行数据交换,共享内存通常具有更高的效率。
在这种机制下,不同进程可以访问同一块内存区域,因此系统需要对共享内存的大小以及访问进行相应的管理。
对于 eAccelerator 来说,它就是利用共享内存保存 PHP 脚本缓存,从而减少重复编译和解析带来的开销。
这也是为什么调整 eaccelerator.shm_size 时,还需要同时关注 Linux 系统的共享内存限制。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。