php-fpm是master/worker架构模式,master 进程负责监控、管理worker进程,worker进程负责处理用户请求。
php-fpm可以通过配置worker进程的数量等信息避免内存泄漏。那我们应该如何去作出最优的配置呢。
概念
内存溢出
内存溢出就是用户进程向操作系统申请了一块内存,但是写入的内容却大于内存的大小。就是我们常见的OOM(out of memory)。
内存泄漏
内存泄漏就是用户进程向操作系统申请了一块内存,使用完成之后并不会释放该内存,造成该内存无法被操作系统回收再次被利用。就是我们常见的 Memory Leak。如果内存泄漏长期堆积必然会耗尽内存,造成内存溢出。
php中内存溢出的场景
整型越界
测试代码
<?php
$i = 9223372036854775807;
$j = $i + 1;
var_dump($i,$j);
运行结果
php整型内存溢出
可以看到整型内存泄漏,php并不会报错,只是将int类型转化为了float类型。
php-fpm内存泄漏
测试代码
<?php
ini_set("memory_limit", "4M");
var_dump(ini_get("memory_limit"));
$arr = [];
while (true) {
$arr[] = "hello world";
}
运行结果
php-fpm设置的最大内存被耗尽
可以看到php-fpm允许的内存已经被消耗殆尽 ,此时该php-fpm进程会被kill。
控制php-fpm OOM的方法
php.ini配置文件内的 memory_limit 配置可以限制单个 php-fpm内使用内存的大小。
通常来说只要程序员开发中注意内存的消耗,再加上 php-fpm 本身的 kill & fork 机制,很少会出现内存溢出。
php-fpm的配置文件可以控制 php-fpm 进程的数量。
php-fpm不仅仅只是控制 worker 进程数量,还有 worker 进程的 kill & fork。如果一个 worker 进程一直在运行,一定会出现泄漏,进而导致内存溢出。所以php-fpm进程通过一定的策略,kill worker进程,释放内存,内存重新被操作系统回收,然后 fork worker进程,操作系统重新分配内存给新的 worker 进程,这样就有效地防止了内存的溢出。
通过对 memory_limit 、php-fpm进程数量的控制,就可以控制 php-fpm 使用整个主机的内存大小。
php-fpm参数介绍
php-fpm配置文件max_children控制 worker 进程的最大数量。
php-fpm配置文件max_requests 最大处理多少请求就 kill & fork php-fpm。
php-fpm配置max_spare_children控制最大空闲php-fpm数量。
php-fpm配置min_spare_children控制最小空闲 php-fpm 数量。
php-fpm配置start_servers 启动是 php-fpm 进程数量。
php-fpm配置process_idel_timeout 空闲进程超时时间。