PHP配置优化

来自MordenPHP

PHP-FPM配置优化

全局配置

在Ubuntu中PHP-FPM的主配置文件时 /etc/php7/fpm/php-fpm.conf 在CentOS中PHP-FPM的主配置文件时/etc/php-fpm.conf.

这两个设置的作用是, 如果指定的一段时间内有指定个数进程失效了. 让PHP-FPM主进程重启.这是PHP-FPM进程的基本安全保证,能解决简单的问题. 但是不能解决由于拙劣的PHP代码引起的重大问题.

emergency_restart_threshold = 10
在指定一段时间内,如果失效的PHP-FPM子进程数超过这个值, PHP-FPM主进程就会优雅的重启.emergency_restart_interval = 1m
设定emergency_restart_threshold设置采用的时间跨度更多全局设置的详细信息查看官方手册

配置进程池

PHP-FPM配置文件其余的内容时一个名为Pool Definitions的区域. 这个区域的配置用于设置每个PHP-FPM进程池. PHP-FPM进程池中是一些列相关的PHP子进程. 通过一个PHP应用有自己的一个PHP-FPM进程池.

在Ubuntu中, Pool Definitions 区域只有下面这个一样内容: include=/etc/php7/fpm/pool.d/*.conf ContOS则在PHP-FPM主配置文件的顶部使用下面这行代码,引入进程池定义的文件: include=/etc/php-fpm.d/*.conf

这行代码的作用是让PHP-FPM加载/etc/php7/fpm/pool.d/目录(Ubuntu)或/etc/php-fpm.d/目录(CentOS)中的各个进程池定义文件. 进入这个目录, 应该会看到一个名为www.conf的文件. 这是名为www的默认PHP-FPM进程池的配置文件.

注意: 每个PHP-FPM进程池的配置文件开头都是[符号, 后面跟进程池的名称的名称.然后是]符号. 例如, 在默认的PHP-FPM进程池的配置文件中, 开头是是[www]

各个PHP-FPM进程池都以指定的操作系统用户和用户组的身份运行. 我喜欢以单独的非根用户运行各个PHP-FPM进程池, 这样在命令行中使用top或者ps aux命令时便于识别 每个PHP应用的PHP-FPM进程池. 这是个好喜欢, 因为每个PHP-FPM进程池中的进程都相应的操作系统用户和用户组的权限限制在沙盒中.

我们要配置默认的 www PHP-FPM进程池, 让他以deploy用户和用户组的身份运行.

我建议把以下设置的默认值改为下面列出的值:

  • user = deploy 拥有这个PHP-FPM进程池中子进程的系统用户, 要把这个设置的值设为运行PHP应用的非根用户的用户名.

  • group = deploy 拥有这个PHP-FPM进程池中子进程的系统用户组, 要把这个设置的值设为运行PHP用用的非根用户所属的用户组名.

  • listen = 127.0.0.1:9000 PHP-FPM进程池监听的IP地址和端口号, 让PHP-FPM只接受NGINX从这里传入的请求. 127.0.0.1:9000 让指定的PHP-FPM进程吃监听从本地端口9000进入的连接. 我使用的端口是9000, 不过你可以使用任何不需要特殊权限(大于1024)且没有被其他系统进程占用的端口号. 配置NGINX虚拟主机时,会再次讨论这个设置.

  • listen.allowed_clients = 127.0.0.1 可以向这个PHP-FPM进程池发送请求的IP地址(一个或多个). 为了安全, 我把这个设置为127.0.0.1 即只有当前设备能把请求转发给这个PHP-FPM进程池. 默认情况下, 这个设置可能被注释掉了, 如果需要, 建议去掉这个设置的注释.

  • pm.max_children = 51 这个设置指定任何时间点, PHP-FPM进程池中最多嫩嫩共有多少个进程. 这个设置没有绝对正确的值, 你应该测试你的PHP应用, 确定每个PHP进程需要多少内存. 然后把这个设置改为设备可用内存能容纳的PHP进程总数. 对大小数中小型PHP应用来说,每个PHP进程要使用5-15MB内存(具体用量可能有差异). 假设我们使用的设备为这个PHP-FPM进程池分配了512MB可用内存, 那么我们可以把这个设置为(512总内存)/(每个进程使用10MB) = 512个进程.

  • pm.start_servers = 3 PHP-FPM启动时PHP-FPM进程池中立即可用的进程数. 同样的,这个设置也没有绝对正确的值. 对大多数中小型PHP应用来说, 我建议设为2或3. 这么做是为了先准备好两到三个进程, 等待请求进入. 不让PHP应用的头几个http请求等待PHP-FPM初始化进程池中的进程.

  • pm.min_spare_servers = 2 PHP应用空闲时PHP-FPM进程池中可以存在的进程数量的最小值. 这个设置的值一般与pm.start_servers设置的值一样, 用于确保新进入的HTTP去请求无需等待PHP-FPM在进程池中重新初始化进程.

  • pm.max_spare_servers = 4 PHP应用空闲时PHP-FPM进程池中可以存在的进程数量的最大值. 这个设置的值一般比pm.start_servers设置的值大一点. 用于确保新进入的HTTP请求无需等待PHP-FPM在进程池中重新初始化进程.

  • pm.max_requests = 1000 回收进程前, PHP-FPM进程池中各个进程最多能处理的HTTP请求数量. 这个设置有助于避免PHP扩展或库因编写拙劣而导致不断泄露内存. 我建议为1000, 不过你可以根据应用的雪球做调整.

  • slowlog = /path/to/slowlog.log 这个设置的值是一个日志文件中爱文件系统汇总的绝对路径. 这个日志文件用于记录处理时间超过N秒的http请求信息; 以便找出PHP应用功能的平静, 进行调试,记住PHP-FPM进程池所属的用户和用户组必须有该文件的写权限. /path/to/slowlog.log只是示例, 请替换成真正的文件路径.

  • request_slowlog_timeout = 5s 如果当前的HTTp请求的处理时间超过指定的值,就把请求的回溯信息写入slowlog设置的指定的日志文件. 把这个设置的值设为多少,取决于你认为多长时间算久. 已开始可以设置为5s

编辑并保存PHP-FPM的配置文件后要执行下述命令, 重启PHP-FPM的主进程:

Ubuntu sudo service php7-fpm restart

CentOS sudo systemctl restart php-fpm.service

内存

运行PHP时我最关心的时每个PHP进程要使用多少内存. php.ini文件中的memory_limit设置用于设定单个PHP进程可以使用的系统内存最大值.

这个设置的默认值是128M, 这对大多数小型PHP应用来说或许合适. 但是如果运行的时微型PHP应用, 可以降低这个值, 例如设为64M, 节省系统资源. 如果 运行的时内存集中性PHP应用, 可以增加这个值, 例如设置为512M, 提升性能. 这个设置的值由可用的系统内存决定.确定给PHP分配多少值是一门艺术,而不是科学. 决定给PHP分配多少内存,以及能负担得起多少个PHP-FPM进程时,我会问自己一下几个问题:

  • 一共能分配给PHP多少内存? 首先我会确定能分配给PHP多少系统内存. 例如我可能会使用一个虚拟设备, 这个设备一共有2G内存.可是这台设备还会有其他进程,例如NGINX,MySQL等等. 而这些进程也要消耗内存, 我觉得留给512MB给PHP就足够了.

  • 单个PHP进程平均消耗多少内存 单后,我会确定单个PHP进程平均消耗多少内存. 为此我要监控进程的内存使用量.如果使用命令可以使用top命令, 查询运行中的进程的实时统计数据. 除此之外,还可以在PHP及脚本的最后调用memory_get_peak_usage()函数, 输出当前脚本消耗的最大内存量. 不管使用暗中方式,都要多次运行同一个PHP脚本,然后取内存消耗量的平均值. 我返现PHP进程一般会消耗5-20MB内存(内存消耗可能会有差异). 如果要上传文件,处理图形,或者运行的时内存集中性应用,得到的平均值显然会高些.

  • 能负担得起多少个PHP-FPM进程 假设我给PHP分配了512MB内存,每个PHP进程平均消耗15M内存 我拿内存总量除以每个PHP进程消耗的内存量, 从而确定我能负担得起34个PHP-FPM进程. 这个是估值,应该再做实验,得到精确值.

  • 有足够的系统资源吗 最后我会问我自己,确信有足够的系统资源运行PHP应用并处理预期的流量吗? 如果答案是肯定的, 大太好了.如果是否定的, 就需要升级服务,在回到第一个问题.

注意

我们应该使用Apache Bench 或者Seige, 在类似的伸长环境的条件下对PHP应用做压力测试,
因为最好在吧应用部署到生产环境之前确定是否有足够的资源可用.

PHP开启OPcache

确定要分配多少内存后,我会配置PHP的Zend OPcache扩展. 这个扩展用于缓存操作码.为什么要这么做呢? 我们先来分析每次HTTP请求时,筒仓是如何处理PHP脚本的. 首先NGINX把HTTP请求转发给PHP-FPM,PHP-FPM再把请求交给某个PHP子进程处理. PHP进程找到相应的PHP脚本后,读取脚本,把PHP脚本编译成操作码(或字节码)格式, 然后执行编译得到的额操作码, 生成响应. 最后吧HTTP响应发给NGINX,NGINX再把响应发给HTTP客户端. 显而易见,每次HTTP请求都要消耗很多资源.

我们可以缓存编译每个PHP脚本得到的操作码,加速这个处理过程. 缓存后,我们可以从缓存中直接读取并执行预先编译好的操作码. 不用每次处理HTTP请求时都查找,读取和编译PHP脚本. PHP5.5+内置了Zend OPcache扩展.

PHP默认没有开启Zend OPcache

编译的话需要在执行./configure时添加 --enable-opcache

编译好之后需要再php.ini添加zend_extension=opcache.so

启用Zend OPcache后需要在php.ini中配置Zend OPcache的设置

opcache.memory_consumption = 64
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 4000
//为0时:Zend OPcache不会察觉到PHP脚本的变化,需要我们手动清空Zend OPcache缓存的字节码
//但是这样对开发环境很不利,下面启动自动重新验证缓存的功能
opcache.validate_timestaps = 1 //在生产环境中设置为0
opcache.revalidate_freq = 0
opcache.fast_shutdown = 1

Zend OPcache部分配置注解

  • opcache.memory_consumption = 64 为操作码缓存分配的内存量(单位是MB). 分配的内存量应该足够保存应用中编译得到的操作码. 如果是小型PHP应用,脚本数较少.可以设置为较低的值. 例如:16MB;如果是大型PHP,应该会有很多脚本,那叫使用较大的值,例如64MB.

  • 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脚本的内容是否有变换. 检查的时间间隔由opcache.revalidate_freq设置指定.如果这个值设置为0, PHP不会检查PHP脚本的内容是否变化,我们必须手动清除缓存的操作码. 我建议在开发环境中设置为1,在生产环境中设置为0.

  • opcache.revalidate_freq = 0 设置PHP多久(单位是秒) 检查一次PHP脚本的内容是否有变化. 缓存的好处是,不用每次请求都重新编译PHP脚本. 这个设置用于确定在多长时间内认为操作码缓存时新的. 在这个时间段之后,PHP会检查PHP脚本的内容是否有变化. 如果有变化,PHP会重新编译脚本,再次缓存.我使用的值是0秒. 仅当opcache.validate_timestamps设置为1时这么设置会在每次请求时都重新验证码PHP文件. 因此在开发安环境中,每次请求都会重新验证PHP文件(这是好事). 这个设置在生产环境中没有任何意义,因为生产环境中opcache_validate_timstamps的值审核中为0.

  • opcache.fast_shutdown =1 这么设置能让操作码使用更快的停机步骤,把对象析构和内存释放交给Zend Engine的内存管理器完成. 这个设置缺少文档,你只需要知道把他设置为1即可

文件上传

如果网站不允许上传,为了增强应用的安全性,应该禁止文件上传功能. 如果你的应用运行上传文件,最好设置最大能上传的文件大小. 除此之外,最好还要设置最多能同时上传多少个文件.

file_uploads = 1
upload_max_filesize =10M
max_file_uploads = 3

默认情况下, PHP允许在单次请求中上传20个文件,上传的每个文件最大为2MB. 你可能不想云溪同时上传20个文件,我只允许单次请求上传3个文件.

如果我的PHP应用允许上传文件,通产个都会运行上传大于2MB的文件. 我把upload_max_filesize设置的值增加到了10MB. 或许根据应用的需求设置为更高的值,但是最好不要设置的太大. 如果这个值太大,web服务器会抱怨HTTP请求的主体太大,或者请求会超时.

  • 注意 如果需要上传非常大的文件,web服务器的配置需要做对应的调整. 处理在php.ini中设置之外,还需要调整NGINX虚拟主机配置汇总的client_max_body_size设置

最长执行时间

php.ini文件中的max_execution_time设置用于指定单个PHP进程在终止之前最长可以运行多少时间. 这个设置的默认值是30秒.我们可不想让PHP进程运行30秒. 因为我们想让应用运行的特别快.我建议吧这个设置为5秒:max_execution_time =5

  • 注意
    在PHP脚本中可以调用`set_time_limit()`函数来覆盖这个函数

你可能会问,如果PHP脚本需要运行更长的时间怎么办. 答案是,PHP脚本不能长时间运行. PHP脚本运行时间越长,web应用的访问者等待响应的时间就会越长. 如果有长时间运行的任务,要在单独的进程中执行.

建议

    我会使用PHP中的exec()函数调用bash的at命令,这个命令作用是派生单独的非阻塞进程.不耽误当前的PHP进程.使用PHP中的exec()函数时,要执行escapeshellarg()函数,转义shell参数.

假设我们要生一个报告,并将结果制作成PDF文件. 这个文件可能要花10分钟才能完成. 而我们肯定不想让这个PHP请求等待10分钟. 我们应该单独编写一个PHP文件,例如将其命名为create_report.php让这个文件运行10分钟. 最后生成报告. 其实, web应用只需要几毫秒就可以派生一个单独的后台进程,然后返回http响应. 如下所示

<?phpexec('echo "create_report.php" | at now');echo 'Report pending...';

create-report.php脚本在单独的后台进程中运行. 运行完毕后可以更新数据库,或者通过邮件把报告发给收件人. 可以看出,我们完全没有理由让长时间运行的任务拖延PHP主脚本,影响用户的体验.

建议 如果发现自己派生了很多后台进程,或许最好使用专门的作业队列. 比如PHPResque

处理回话

PHP默认的回话处理程序会拖慢大型应用,因为存储在磁盘中,需要创建不必要的额文件IO.
浪费时间.我们应该把数据回话保存在内存中,比如使用Memcached或者Redis.
这么做还有一个好处是以后便于伸缩,任何一台分部署PHP-FPM服务器都能访问回话数据

若想在PHP中访问Memcached存储的书,需要安装连接Memcached的PECL扩展. 然后再把下面两行添加到php.ini文件中,把PHP默认的回话存储访问改为MEmcached.

session.save_handler = 'memcached'
session_save_path = '127.0.0.1:11211'

缓冲数据

如果在较少的块中发送更多的数据,而不是在较多的块中发送较少的数据. 那么网络的效率会更高.也就是说, 在较少的片段中把内容传递给访问者的浏览器, 能减少HTTP请求总数.

因此,我们需要让PHP缓冲输出.默认情况下,PHP已经弃用和输出缓冲功能(不过没在命令行中弃用). PHP缓冲4096字节的输出后才会把其中的内容发给web服务器. 下面是我推荐在php.ini文件中使用的设置

output_buffering = 4096
imlicit_flush = false

建议 如果想修改输出缓冲区的大小, 确保使用的值是4(32位系统)或8(64系统)的倍数.

真实路径缓存

PHP会缓存应用使用的文件路劲,这样每次包含或导入文件时就无需不断的搜索包含路径了.
这个缓存叫真实路径缓存(realpath cache).
如果运行的时大型PHP文件,使用了大量文件,增加PHP真实路径缓存的大小能得到更好的性能.

真实路径缓存的默认大小为16K. 这个缓存所需要的准确大小不容易确确定,不过可以使用一个小技巧. 首先,增加真实路径的大小,设置为特别大的值.例如256k. 然后在一个PHP脚本的末尾加上print_r(realpath_cache_size()); 输出真实路径缓存的真正大小.最后吧这个路径缓存的大小GA为这个真正的值. 我们可以在php.ini文件中设置真实路径缓存大小:

realpath_cache_size = 64k

转载于:https://my.oschina.net/chinaliuhan/blog/3064894

PHP配置优化《MordenPHP》相关推荐

  1. MySQL 5.6 my.cnf配置优化

    MySQL 5.6 my.cnf配置优化 4核 16G Centos6.5 x64 优化后测试结果如下 #mysqlslap #--concurrency=2 #--iterations=1 #--n ...

  2. SSH配置优化和慢的解决方法

    SSH配置优化和慢的解决方法 参考文章: (1)SSH配置优化和慢的解决方法 (2)https://www.cnblogs.com/kaishirenshi/p/9495997.html 备忘一下.

  3. Redis在Linux系统的配置优化

    通常来看,Redis开发和运维人员更加关注的是Redis本身的一些配置优化,例如AOF和RDB的配置优化.数据结构的配置优化等,但是对于操作系统是否需要针对Redis做一些配置优化不甚了解或者不太关心 ...

  4. HBase性能优化方法总结(1):配置优化

    配置优化 zookeeper.session.timeout 默认值:3分钟(180000ms) 说明:RegionServer与Zookeeper间的连接超时时间.当超时时间到后,ReigonSer ...

  5. mysql 提高电脑配置_Mysql配置优化浅谈

    Mysql配置优化浅谈安装MySQL后,配置文件my.cnf在MySQL 安装目录/share/mysql目录中,该目录中还包含多个配置文件可供参考,有my-large.cnf ,my-huge.cn ...

  6. Mybatis学习之配置优化

    前言 接上章学习,我们配置build了之后,成功解决了资源导出失败的问题,这章我们学习的是配置优化 一.原来的配置 1.数据库配置(属性优化) 原先写死的数据库核心配置 <!--核心配置文件-- ...

  7. IntelliJ IDEA的配置优化

    IntelliJ IDEA的配置优化 我们安装完IntelliJ IDEA之后,在弹出的欢迎页面下方点击Configure,选择Setting,打开以下界面,我们在这个界面中进行配置. Appeara ...

  8. mybatis的mapper.xml文件中含有中文注释时运行出错,mybatis配置优化和别名优化 mybatis配置之映射器说明

    记录一个发现的小问题,刚刚在UserMapper.xml文件中有一段中文注释掉的内容: <!-- <resultMap id="Usermap" type=" ...

  9. apache配置优化

    最近参加了很多面试,多多少少有点小感悟,可以说观念转变了不少,特别是对于作为一个开发人员的定位,原来只是认为开发人员就只需要写好代码就行了,所以只需要有数据结构,算法,设计模式,重构方面的知识就行了. ...

  10. Tomcat配置优化

    TOMCAT配置优化 一. Tomcat下使用Log4j 接管 catalina.out 日志文件生成方式, 按天存放,解决catalina.out日志文件过大问题 1.准备jar包: log4j-1 ...

最新文章

  1. cpp map 获取所有 key_Flutter 中最熟悉的陌生人之 Key 全面解析
  2. mybaits三:全局配置文件(全面)
  3. 11 为了进一步_小米11正式官宣!12月28号整装待发,这几点或成关键
  4. unittest 多个测试文件只开一次浏览器_接口测试平台代码实现75: 多接口用例15
  5. GDOI2018 总结
  6. 收下这 16 篇最新论文,周会基本不用愁
  7. vs2013 无法打开 源 文件 SDKDDKVer.h
  8. ios realm 文件_关于ios:具有后台进程的Realm实例会丢失数据
  9. linux设备驱动模块引用和依赖
  10. python-操作数据库的练习
  11. Flash AS3.0实例教程:构建简单的声音可视化程序(波型图)
  12. 记一次spirngMVC整合HttpPrinter的过程
  13. cad快看_对于CAD看图软件,你到底了解多少?
  14. 16年的长度 记录中国独立游戏
  15. 线性代数学习笔记——第六讲——矩阵的转置
  16. 24年前他被余承东招入华为,现在掌舵第四大事业群,对垒阿里张建锋、百度王海峰,腾讯汤道生...
  17. SAP中多生产版本系统应用选择规则
  18. 18春计算机应用基础在线答案,南开18春《计算机应用基础》在线作业答案.doc
  19. eclipse创建项目没有web
  20. android 键盘开发demo,Android自定义键盘之中文键盘demo

热门文章

  1. java中的if语句_java中的条件判断语句
  2. 使用pm2部署vue项目
  3. 应用商店优化(ASO)之关键词及描述优化
  4. 查询银行卡归属地区API接口
  5. ICP算法原理及优缺点(简洁明了)
  6. 记一次磁盘PV丢失事件
  7. oracle的PRIPID字段,oracle常用库表和常用导数逻辑.doc
  8. 「新功能」对接金蝶云星空K3 Cloud插件支持版本升级
  9. 金蝶星空支持mysql吗_金蝶云星空K3 CLOUD SQL 数据库优化
  10. 重启网卡提示Bringing up interface eth0: Device eth0 does not seem to be present,delaying initialization.