我有一台 64 位服务器,但只有 256MB 的 RAM。因此,我使用 fast-cgi 移至 nginx 服务器来连接 PHP。我运行的是 PHP 5.3.6。
问题是,每隔两三天,当我尝试访问任何 PHP 页面时,就会收到服务器内部错误。唯一的解决方法是手动重新启动 php-fpm。这意味着我应该设置了一些错误的参数,导致它阻塞。下面我列出了相关的配置。
/etc/php-fpm.conf:
include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0
/etc/php-fpm.d/www.conf:
[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500
/etc/nginx/php.conf:
location ~ \.php {
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_pass unix:---some-location---;
}
更新 1
我有四个 nginx 进程正在运行。平均每个 php-fpm 进程占用 35MB RAM(每个虚拟内存大小为 320MB)。我还有一个 MySql 进程正在运行。
更新 2
我忘了粘贴日志。
php-fpm 错误日志:-
WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...
php-fpm www.error 日志:-
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
答案1
一个随意的建议是降低你的设定值 - 可能将其减半。
您有:pm.max_children = 10 如果您说35MB/process = 350MB;在256MB的盒子上,这意味着大量交换或内存不足 - 两者都不好。
我认为至少为其他进程留出 100MB,甚至为安全起见留出 150MB,然后将该数字除以 35MB 即可得到 max_children。保持所有其他数字一致:
pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500
停止 PHP-FPM 并运行free
以了解您的可用内存 - 除以 35MB 以获得您的 max_children。
根据 MySQL 占用的内存量,您可能必须将 max_children 降低到 3。
我确实发现 PHP-FPM 进程共享了大量内存,做一个快速实验来确定实际使用了多少内存。停止 PHP-FPM 并运行free
。启动 PHP-FPM 访问一些常用页面(这是必要的,因为内存会根据加载的页面而增加),并检查使用的总内存,再次使用free
- 将差值除以进程数。这不是一个完美的系统,但我确实发现它相当准确(有时 top 中的数据列也不错)。
答案2
您的 php-fpm 设置似乎正常。
但是你运行的服务器资源有些受限。从日志中可以明显看出,PHP 进程正在耗尽可用内存。
添加 cyberx86 提供的建议:
您可以尝试编辑 php.ini 文件中的 memory_limit 参数(请参阅这里)(尽管我不确定这会带来多大好处)
考虑到系统内存量较小,我认为您应该认真考虑切换到 32 位操作系统。使用 x64 操作系统实际上对您有害无益。
如果您没有在 MySql 数据库中使用 InnoDB 存储,您也可以考虑在 my.cnf 中关闭 InnoDB - 这将节省另外 100 MB 的 RAM。
低端箱有一个关于如何优化低内存配置服务器的精彩教程。
答案3
一个非常方便的命令来查找 php 占用的内存:
ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'
然后,您划分想要专用于 php 的 RAM,并得到 max_children 值!
另外,您可以手动监控(您必须设置端点 php-status)或使用 Nagios 进行监控。