【CNMP系列】PHP配置和调优
上一节我们说到PHP5.6.30在CentOS7.0下的整个安装过程,http://www.cnblogs.com/riverdubu/p/6428226.html
今天我来和大家讲解一下PHP-FPM安装的一些配置和调优。
PHP-FPM配置相关
再来解释下php-fpm的概念,PHP-FPM(PHP FastCGI Process Manager的简称,意思是“PHP FastCGI进程管理器”),是用于管理PHP进程池的软件,用于接收和处理来自Web服务器(例如nginx)的请求。
PHP-FPM软件会创建一个主进程(通常以操作系统中根用户的身份运行),控制何时以及如何把HTTP请求转发给一个或多个子进程处理。
这个master process就是PHP-FPM的主进程。
PHP-FPM主进程还控制着什么时候创建和销毁子进程,PHP-FPM进程池中的每一个进程存在的时间都比单个HTTP请求长。因为这章不是讲进程的,所以,进程这个概念不在此赘述,不懂的朋友可以去百度好好了解下。
PHP-FPM的配置文件在/usr/local/php/etc/里面。打开该文件。
vim /usr/local/php/etc/php-fpm.conf
可以看到很多注释掉的代码段(这里的分号是注释符)。vim快速查找单个单词的方式,在非编辑模式,按'/'这个符号,输入你想要查找的单词,然后按'n'字母跳到下一个。
全局配置相关
先来解释一下这两个配置参数。
emergency_restart_threshold:在指定的一段时间内,如果失效的PHP-FPM子进程超过这个值,PHP-FPM子进程就重启。emergency_restart_interval这个值就是指定的一段时间。这是PHP-FPM进程的基本安全保障,建议设置成如下值。
关键配置相关
各个PHP-FPM进程池都以指定的操作系统用户和用户组的身份运行,个人建议以单独的非根用户身份运行各个PHP-FPM进程池,这样你在命令行中使用top的时候便于识别每个PHP的应用的PHP-FPM进程池。
PHP-FPM进程池监听的IP地址和端口号。
拥有这个PHP-FPM进程池中子进程的系统用户(组),要把这个设置的值设置成运行PHP应用的非根用户的用户(组)名。
可以向这个PHP-FPM进程池发送请求的IP地址(一个或多个),为了安全,我是将其设为本机或者注释掉,如果你有需求,可以打开。
PHP-FPM进程池中最多能有多少进程。具体的进程数按照自己分配给php服务的内存决定,具体算法如下。
一共分配给PHP多少内存?我在阿里云申请了一台2G内存的VPS,除去分配给Nginx,MySql,Memcache的内存,我觉得给PHP分配个512MB差不多。
单个PHP进程平均消耗多少内存?PHP进程一般消耗5~20MB的内存,上传文件,图像处理等另算。
能负担起多少个PHP-FPM进程?做个简单的除法,我发现此VPS能够承担30个左右的进程,如果你觉得这样不够,可以考虑增加服务器的内存数量。
PHP-FPM启动时PHP-FPM进程池中立即可用的进程数。保持默认值即可,这么做是为了保证有2个进程,等待请求进入,不让PHP应用的头几个HTTP请求等待PHP-FPM初始化进程池中的进程。
PHP应用空闲时PHP-FPM进程池中可以存在的进程数量最小值/最大值。
PHP-FPM进程池中每个进程最多能处理的HTTP请求数量,还是各位根据需求计算出来的。
日志,各位可以配置下,用于记录处理时间超过n秒的HTTP请求信息,可以找出PHP慢的原因。
上面的n秒,一般设为5s。
保存退出,重启PHP-FPM服务。
#service php-fpm restart
可能没有日志文件,我们新建一个即可。
#mkdir -p /usr/local/php/log/ #touch /usr/local/php/log/www.log.slow
PHP调优原理
我们来分析一下每次HTTP请求时通常是如何处理PHP脚本的。
首先,nginx把http请求转发给PHP-FPM,PHP-FPM再把请求交给某个PHP子进程处理。
PHP进程找到相应的PHP脚本后,读取脚本,把PHP脚本编译成操作码(或字节码)格式,然后执行编译得到操作码,生成响应。
最后,把HTTP响应发给nginx,nginx再把响应发给HTTP客户端。
PHP调优计划
PHP解释器在php.ini文件中配置和调优,首先,我们得找到php.ini文件的所在地。
我们回想一下昨天打开的那个phpinfo.php文件,获取到php的一些信息,心细的朋友可能在里面就找到了php.ini的位置。
打开该文件。
#vim /usr/local/php/lib/php.ini
内存配置
比较科学的默认值,如果网站比较大,可以考虑到512M,如果只是一个个人网站,这个足够,或者降到64M即可。
Zend OPcache配置
字节码缓存不是PHP的新特性,很多独立的扩展可以实现缓存,例如APC、eAccelerator、XCache。从PHP 5.5.0开始,PHP内置了字节码缓存功能,名为Zend OPcache。
Zend OPcache会自动在内存中缓存预先编译好的PHP字节码,如果缓存了某个文件的字节码,就执行对应的字节码。PHP是解释型的语言,PHP解释器执行PHP脚本的时候会解析PHP脚本代码,把PHP代码编译成一系列Zend操作码,然后执行字节码。就和C汇编转机器码一样的,缓存的是可执行的字节码。
如果php.ini文件中的opcache.validate_timestamps指令的值为0,Zend OPcache就会察觉不到PHP脚本的变化,我们必须要手动去清空Zend OPcache缓存的字节码,让它发现PHP文件的变动。
下面推荐一组Zend OPcache的配置:
只是推荐,针对每个打开的属性,我下面做详解。
首先,需要打开opcache。opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP ;opcache.enable_cli=0 ; The OPcache shared memory storage size. opcache.memory_consumption=64
为操作码缓存分配的内存量。
; The amount of memory for interned strings in Mbytes. opcache.interned_strings_buffer=16
用来存储驻留字符串的内存量,何为驻留字符串,PHP解释器在背后会找到相同字符串的多个实例,把这个字符串保存在内存中,如果再次使用相同的字符串,PHP解释器就会使用指针这么做能节省内存。
; The maximum number of keys (scripts) in the OPcache hash table. ; Only numbers between 200 and 100000 are allowed. opcache.max_accelerated_files=4000
操作码缓存中最多能存储多少个PHP脚本。
; When disabled, you must reset the OPcache manually or restart the ; webserver for changes to the filesystem to take effect. opcache.validate_timestamps=1
这个值设置为1时,经过一段时间后PHP会检查PHP脚本的内容是否有变化。
; How often (in seconds) to check file timestamps for changes to the shared ; memory storage allocation. ("1" means validate once per second, but only ; once per request. "0" means always validate) opcache.revalidate_freq=0
设置PHP多久(时间是秒)检查一次PHP脚本的内容是否有变化。这么设置会在每次请求时都重新验证PHP文件,适用于线上生产环境。
; If enabled, a fast shutdown sequence is used for the accelerated code opcache.fast_shutdown=1
这么设置能让操作码使用更快的停机过程,把对象析构和内存释放交给Zend Engine的内存管理器完成。
最长执行时间
默认最长执行时间为30秒,PHP进程运行到30秒,那还不把Web应用的访问者等死啊,所以我们不能让访问者等这么长时间,设置为5即可。如果要处理长时间的运行任务,放到单独的进程中运行即可。
会话处理
如果大家对Memcache和Redis比较熟悉,可以将这里面的session存储换成这两种内存存储,速度快,也便于以后大小的伸缩。
好的,关于PHP的配置和优化就先说到这里,如果各位需要对文件上传、缓冲设置以及其他的相关设置,可以参见php.net,在官网上可以学到更多,还有什么不明白的,可以在评论区留言评论,我会一一给大家解答。^_^
注1
zend opcache的打开还需要新增一个配置属性,在刚才的opcache区间内加入这句
zend_extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/opcache.so
重启php-fpm。重启Nginx。即可在phpinfo里看到opcache的相关信息。