PHP调优
php.ini
PHP解释器在 php.ini 文件中配置和调优。web和cli使用的路径不同,如果必要我觉得可以调成一样或者共用。路径一般都在/etc下。
内存
考虑每个PHP进程要使用多少内存?确定分配给PHP多少内存?
共能分配给PHP多少内存?
首先,确定能分配给PHP多少系统内存。例如,我可能会使用一个 Linode虚拟设备,这个设备一共有2GB内存。可是,这台设备中可能还有其他进程(例如,nginx、 MySQL或 memcache),而这些进程也要消耗内存。我觉得留512MB给PHP就足够了。单个PHP进程平均消耗多少内存?
然后,确定单个PHP进程平均消耗多少内存。为此,我要监控进程的内存使用
量。如果使用命令行,可以执行top命令,查看运行中的进程的实时统计数据。除
此之外,还可以在PHP脚本的最后调用 memory_get_peak usage()函数,输出当前
脚本消耗的最大内存量。不管使用哪种方式,都要多次运行同一个PHP脚本,然后
取内存消耗量的平均值。我发现PHP进程一般会消耗5-20MB内存(具体消耗可能
有差异)。如果要上传文件、处理图像,或者运行的是内存集中型应用,得到的平
均值显然会高些。能负担得起多少个 PHP-FPM进程?
假设我给PHP分配了512MB内存,每个PHP进程平均消耗15MB内存,我拿内存总
量除以每个PHP进程消耗的内存量,从而确定我能负担得起34个 PHP-FPM进程。这
是个估值,应该再做实验,得到精确值。有足够的系统资源吗?
最后我会问自己,确信有足够的系统资源运行PHP应用并处理预期的流量吗?如果
答案是肯定的,那太好了。如果答案是否定的,就需要升级服务器,添加更多的内
存,然后再回到第一个问题。
查了测试环境
#查询内存
[root@localhost data]# grep MemTotal /proc/meminfo
MemTotal: 1884808 kB
总内存:1884808/1024*1024 = 1.8
配置内存:
memory_limit = 128M
负担PHP-FPM进程:128M/10M(平均耗用内存) = 13,大约13个PHP-FPM进程。
Zend OPcache
确定分配内存后,配置PHP的Zend OPcache扩展,来缓存字节码。
如:
opcache. memory consumption=64
opcache interned strings buffer 16
opcache. max accelerated files=4000
opcache. validate timestamps =1
opcache revalidate fred=0
opcache. fast shutdown=1
opcache. memory consumption =64
为操作码缓存分配的内存量(单位是MB)。分配的内存量应该够保存应用中所有PHP脚本编译得到的操作码。如果是小型PHP应用,脚本数较少,可以设为较低的值,例如16MB;如果是大型PHP应用,有很多脚本,那就使用较大的值,例如64MB。opcache interned strings buffer =16
用来存储驻留字符串( interned string)的内存量(单位是MB)。那么驻留字符串是什么呢?我首先也会想到这个问题。PHP解释器在背后会找到相同字符串的多个实例,把这个字符串保存在内存中,如果再次使用相同的字符串,PHP解释器会使用指针。这么做能节省内存。默认情况下,PHP驻留的字符串会隔离在各个PHP进程中。这个设置能让PHP-FPM进程池中的所有进程把驻留字符串存储到共享的缓冲区中,以便在 PHP-FPM进程池中的多个进程之间引用驻留字符串。这样能节省
更多内存。这个设置的默认值是4MB,不过我喜欢设为16MB。opcache interned strings buffer =16
用来存储驻留字符串( interned string)的内存量(单位是MB)。那么驻留字符串
是什么呢?我首先也会想到这个问题。PHP解释器在背后会找到相同字符串的多个
实例,把这个字符串保存在内存中,如果再次使用相同的字符串,PHP解释器会使
用指针。这么做能节省内存。默认情况下,PHP驻留的字符串会隔离在各个PHP进
程中。这个设置能让 PHP-FPM进程池中的所有进程把驻留字符串存储到共享的缓
冲区中,以便在 PHP-FPM进程池中的多个进程之间引用驻留字符串。这样能节省
更多内存。这个设置的默认值是4MB,不过我喜欢设为16MB。opcache. max accelerated files=4000
操作码缓存中最多能存储多少个PHP脚本。这个设置的值可以是200到100000之间
的任何数。我使用的是4000。这个值一定要比PHP应用中的文件数量大opcache.validate timestamps=1
这个设置的值为1时,经过一段时间后PHP会检查PHP脚本的内容是否有变化。检
查的时间间隔由 apache, revalidate freq设置指定。如果这个设置的值为0,PHP
不会检査PHP脚本的内容是否有变化,我们必须自己动手清除缓存的操作码。我建
议在开发环境中设为1,在生产环境中设为0。opcache. revalidate freq 0
设置PHP多久(单位是秒)检查一次PHP脚本的内容是否有变化。缓存的好处是,
不用每次请求都重新编译PHP脚本。这个设置用于确定在多长时间内认为操作码
缓存是新的。在这段时间之后,PHP会检查PHP脚本的内容是否有变化。如果有变
化,PHP会重新编译脚本,再次缓存。我使用的值是0秒。仅当 apache. validate
timestamps设置的值为1时,这么设置会在每次请求时都重新验证PHP文件。因
此,在开发环境中,每次请求都会重新验证PHP文件(这是好事)。这个设置在生
产环境中没有任何意义,因为生产环境中 opcache. validate timestamps的值始终
为0。opcache. fast shutdown =1
这么设置能让操作码使用更快的停机步骤,把对象析构和内存释放交给Zend
Engine的内存管理器完成。这个设置缺少文档,你只需知道要把它设为1。
文件上传
file_uploads = 1
upload_macx_filesize = 10M #文件最大空间限制,调整幅度不能过高,上传文件过大,Web服务器会抱怨HTTP请求主体太大。
max_file_uploads = 3 #允许单次上传文件数
最长执行时间
max_execution_time = 5
PHP脚本可调用函数 set_time_limit() 设置。
web脚本时间不宜过长,web服务器会超时。如时间过长,可交由任务单独运行。
建议:PHP中的exec()函数调用bash的at命令。这个命令的作用是派生单独的非阻塞进
程,不耽误当前的PHP进程。使用PHP中的exec()函数时,要使用 escapeshellarg()函数
(hp/ php. net/manuallfunction escapeshellarg php)转义shell参数。
假设我们要生成报告,并把结果制作成PDF文件。这个任务可能要花10分钟才能完成,
而我们肯定不想让PHP请求等待10分钟。我们应该单独编写一个PHP文件,假如将其命
名为 create-report,php,让这个文件运行10分钟,最后生成报告。其实,web应用只需几
毫秒就能派生一个单独的后台进程,然后返回HTTP响应,如下所示:
<?php
exec(echo "create-report php"I at now);
echo" Report pending…’;
creare- report.php脚本在单独的后台进程中运行,运行完毕后可以更新数据库,或者通
过电子邮件把报告发给收件人。可以看出,我们完全没有理由让长时间运行的任务拖延
PHP主脚本,影响用户体验。
太多脚本服务,使用专门的作业队列或许更好。
处理会话
大型应用或者多机器,不宜存贮,一种是占用文件I/O,降低读写速度,一种是无法多机器公用。存贮与内存中,解决此类问题。可使用memcache、redis,即使空间不够,也可扩展。
session.save_handler = 'redis';
session.save_path = '127.0.0.1:11211'
或者使用PHP的函数
session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid [, callable $validate_sid [, callable $update_timestamp ]]] )
缓冲输出
缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.
缓冲区最本质的作用就是,协调高速CPU和相对缓慢的IO设备(磁盘等)的运作.
当执行PHP的时候,如果碰到了echo print_r之类的会输出数据的代码,PHP就会将要输出的数据放到PHP自身的缓冲区,等待输出.
echo、print => php output_buffering => webServer buffer => browser buff => browser display
即:脚本输出 => php的缓冲区设置 => 系统的缓冲区设置(apache、nginx) => 浏览器的缓冲区设置 => 显示给用户
推荐配置:
output_buffering = 4096 #缓冲区字节大小
implicit_flush = false
使用场景:
- PHP断点续传
- 静态文件缓存
缓冲区相关函数:ob_*
真实路径缓存
对文件的真实路径缓存,并且include_once、require_once可用到。
这样每次包含或导入文件时就无需不断搜索包含路
径了。这个缓存叫真实路径缓存( realpath cache)。如果运行的是大型PHP文件(例如
Drupal和 Composer组件等),使用了大量文件,增加PHP真实路径缓存的大小能得到更
好的性能
真实路径缓存的默认大小为16k。这个缓存所需的准确大小不容易确定,不过可以使用
个小技巧。首先,增加真实路径缓存的大小,设为特别大的值,例如256k。然后,在
个PHP脚本的末尾加上 print_ r( realpath cache size()};,输出真实路径缓存的真
正大小。最后,把真实路径缓存的大小改为这个真正的值。我们可以在 phpin件中设
置真实路径缓存的大小:
realpath cache size= 64k
服务器马力十足。
PHP调优的更多相关文章
- 46张PPT讲述JVM体系结构、GC算法和调优
本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...
- 《深入理解Java虚拟机》调优案例分析与实战
上节学习回顾 在上一节当中,主要学习了Sun JDK的一些命令行和可视化性能监控工具的具体使用,但性能分析的重点还是在解决问题的思路上面,没有好的思路,再好的工具也无补于事. 本节学习重点 在书本上本 ...
- Spark Shuffle原理、Shuffle操作问题解决和参数调优
摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuff ...
- 搭建 windows(7)下Xgboost(0.4)环境 (python,java)以及使用介绍及参数调优
摘要: 1.所需工具 2.详细过程 3.验证 4.使用指南 5.参数调优 内容: 1.所需工具 我用到了git(内含git bash),Visual Studio 2012(10及以上就可以),xgb ...
- jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)
文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...
- jvm系列(六):jvm调优-从eclipse开始
jvm调优-从eclipse开始 概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程 ...
- web前端性能调优
最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...
- JVM调优总结
堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作 ...
- Elasticsearch 调优 (官方文档How To)
How To Elasticsearch默认是提供了一个非常简单的即开即用体验.用户无需修改什么配置就可以直接使用全文检索.结果高亮.聚合.索引功能. 但是想在项目中使用高性能的Elasticsear ...
- 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL
周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...
随机推荐
- jdbc oracle clob
import java.io.BufferedReader; import java.io.Reader; import java.io.Writer; import java.sql.Callabl ...
- ORA-04091: table xxx is mutating, trigger/function may not see it
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 Connected as tbcs SQL> SQL ...
- malloc/free 与 new/delete 区别
malloc/free 是c++/c的标准库函数,new/delete 是c++的运算符.两者都可以申请动态内存和释放内存.对于非内部数据类型的对象而言,光用malloc/free是无法满足动态对象的 ...
- SpringBoot MockMvc的单元测试
对于类的测试,可以有很多的方式进行实现,比如可以使用PostMan,使用HttpClient请求等,这里主要讲的是MockMcv的测试 一:引入依赖 <dependency> <gr ...
- 八、window搭建spark + IDEA开发环境
本文将简单搭建一个spark的开发环境,如下: 1)操作系统:window os 2)IDEA开发工具以及scala插件(IDEA和插件版本要对应): 2-1)IDEA2018.2.1:https:/ ...
- ssm项目快速搭建(注解)
dao层配置 dao层配置注意事项: 1.Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同 2.Mapper.xml 接口方法名和 Mapper.xml 中定义的 ...
- K:求取数组中最大连续子序列和的四个算法
相关介绍: 求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...
- python学习之老男孩python全栈第九期_day023知识点总结——类和对象命名空间、组合
一. 类和对象命名空间类里 可以定义两种属性: 1. 静态属性 2. 动态属性 class Course: language = 'Chinese' def __init__(self, teache ...
- python中字典,没键加键,有键操作其键对应的值,的思想
cars = ['鲁A32444', '鲁B12333', '京B8989M', '黑C49678', '黑C46555', '沪B25041', '黑C34567'] locations = {'沪 ...
- [HAOI2009]逆序对数列(加强)
ZJL 的妹子序列 暴力就是 \(\Theta(n\times m)\) 如果 \(n,m \le 10^5\) ? 考虑问题的转换,设 \(a_i\) 表示 \(i\) 小的在它后面的数的个数 \( ...