设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP中关于php.ini参数优化详解

发布时间:2022-06-14 12:40 所属栏目:121 来源:互联网
导读:这篇文章主要介绍了PHP8新特性之JIT案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下。 PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样?
  这篇文章主要介绍了PHP8新特性之JIT案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下。
 
  PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样?
 
  首先,我们来看一张图:
 
  deabbe4c2476e16f4314c7d54b552f48.png
 
  左图是 PHP 8之前的Opcache流程示意图, 右图是 PHP 8中的Opcache示意图, 可以看出几个关键点:
 
  PHP8的JIT是在Opcache之中提供的
 
  目前PHP8只支持x86架构的CPU
 
  JIT是在原来Opcache优化的优化基础之上进行优化的,不是替代
 
  事实上JIT共用了很多原来Opcache做优化的基础数据结构,比如data flow graph, call graph, SSA等,关于这部分,后续如果有时间,可以单独在写一个文章来介绍,今天就只是着重在使用层面。
 
  下载安装好以后,除掉原有的opcache配置以外,对于JIT我们需要添加如下配置到php.ini:
 
  opcache.jit=1205
 
  opcache.jit_buffer_size=64M
 
  opcache.jit这个配置看起来稍微有点复杂,我来解释下, 这个配置由4个独立的数字组成,从左到右分别是( 请注意,这个是基于目前alpha1的版本设置,一些配置可能会随着后续版本做微调 ):
 
  是否在生成机器码点时候使用AVX指令, 需要CPU支持: 0: 不使用
 
  1: 使用
 
  寄存器分配策略: 0: 不使用寄存器分配
 
  1: 局部(block)域分配
 
  2: 全局(function)域分配
 
  JIT触发策略: 0: PHP脚本载入的时候就JIT
 
  1: 当函数第一次被执行时JIT
 
  2: 在一次运行后,JIT调用次数最多的百分之(opcache.prof_threshold * 100)的函数
 
  3: 当函数/方法执行超过N(N和opcache.jit_hot_func相关)次以后JIT
 
  4: 当函数方法的注释中含有@jit的时候对它进行JIT
 
  5: 当一个Trace执行超过N次(和opcache.jit_hot_loop, jit_hot_return等有关)以后JIT
 
  JIT优化策略,数值越大优化力度越大: 0: 不JIT
 
  1: 做opline之间的跳转部分的JIT
 
  2: 内敛opcode handler调用
 
  3: 基于类型推断做函数级别的JIT
 
  4: 基于类型推断,过程调用图做函数级别JIT
 
  5: 基于类型推断,过程调用图做脚本级别的JIT
 
  基于此,我们可以大概得到如下几个结论:
 
  尽量使用12x5型的配置,此时应该是效果最优的
 
  对于x, 如果是脚本级别的,推荐使用0, 如果是Web服务型的,可以根据测试结果选择3或5
 
  @jit的形式,在有了attributes以后,可能变为<>
 
  现在,我们来测试下启用和不启用JIT的时候,Zend/bench.php的差异,首先是不启用(php -d opcache.jit_buffer_size=0 Zend/bench.php):
 
  simple 0.008
  
  simplecall 0.004
  
  simpleucall 0.004
  
  simpleudcall 0.004
  
  mandel 0.035
  
  mandel2 0.055
  
  ackermann(7) 0.020
  
  ary(50000) 0.004
  
  ary2(50000) 0.003
  
  ary3(2000) 0.048
  
  fibo(30) 0.084
  
  hash1(50000) 0.013
  
  hash2(500) 0.010
  
  heapsort(20000) 0.027
  
  matrix(20) 0.026
  
  nestedloop(12) 0.023
  
  sieve(30) 0.013
  
  strcat(200000) 0.006
  ------------------------
  
  Total 0.387
  根据上面的介绍,我们选择opcache.jit=1205, 因为bench.php是脚本(php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php):
 
  simple 0.002
  
  simplecall 0.001
  
  simpleucall 0.001
  
  simpleudcall 0.001
  
  mandel 0.010
  
  mandel2 0.011
  
  ackermann(7) 0.010
  
  ary(50000) 0.003
  
  ary2(50000) 0.002
  
  ary3(2000) 0.018
  
  fibo(30) 0.031
  
  hash1(50000) 0.011
  
  hash2(500) 0.008
  
  heapsort(20000) 0.014
  
  matrix(20) 0.015
  
  nestedloop(12) 0.011
  
  sieve(30) 0.005
  
  strcat(200000) 0.004
  ------------------------
  
  Total 0.157
  可见, 对于Zend/bench.php, 相比不开启JIT,开启了以后,耗时降低将近60%,性能提升将近2倍 。
 
  对于大家研究学习来说,可以通过opcache.jit_debug来观测JIT后生成的汇编结果,比如对于:
 
  function simple() {
  $a = 0;
  
  for ($i = 0; $i < 1000000; $i++)
  
  $a++;
  
  }
  我们通过php -d opcache.jit=1205 -dopcache.jit_debug=0x01 可以看到:
 
  JIT$simple: ; (/tmp/1.php)
 
  sub $0x10, %rsp
  
  xor %rdx, %rdx
  
  jmp .L2
  
  .L1:
  
  add $0x1, %rdx
  
  .L2:
  
  cmp $0x0, EG(vm_interrupt)
  
  jnz .L4
  
  cmp $0xf4240, %rdx
  
  jl .L1
  
  mov 0x10(%r14), %rcx
  
  test %rcx, %rcx
  
  jz .L3
  
  mov $0x1, 0x8(%rcx)
  
  .L3:
  
  mov 0x30(%r14), %rax
  
  mov %rax, EG(current_execute_data)
  
  mov 0x28(%r14), %edi
  
  test $0x9e0000, %edi
  
  jnz JIT$$leave_function
  
  mov %r14, EG(vm_stack_top)
  
  mov 0x30(%r14), %r14
  
  cmp $0x0, EG(exception)
  
  mov (%r14), %r15
  
  jnz JIT$$leave_throw
  
  add $0x20, %r15
  
  add $0x10, %rsp
  
  jmp (%r15)
  
  .L4:
  
  mov $0x45543818, %r15
  
  jmp JIT$$interrupt_handler
  而如果我们采用opcache.jit=1201, 我们可以得到如下结果:
 
  JIT$simple: ; (/tmp/1.php)
 
  sub $0x10, %rsp
  
  call ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER
  
  add $0x40, %r15
  
  jmp .L2
  
  .L1:
  
  call ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER
  
  cmp $0x0, EG(exception)
  
  jnz JIT$$exception_handler
  
  .L2:
  
  cmp $0x0, EG(vm_interrupt)
  
  jnz JIT$$interrupt_handler
  
  call ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER
  
  cmp $0x0, EG(exception)
  
  jnz JIT$$exception_handler
  
  cmp $0x452a0858, %r15d
  
  jnz .L1
  
  add $0x10, %rsp
  
  jmp ZEND_RETURN_SPEC_CONST_LABEL
  你也可以尝试各种debug的配置,比如opcache.jit_debug=0xff,将会有更多的信息输出。
 
  好了,JIT的使用就简单介绍到这里,关于JIT本身的实现等细节,以后有时间,我再来写吧。
 
  大家现在就可以去php.net下载PHP8来测试了 :)PHP引擎php.ini参数优化
 
  无论是apache还是nginx,php.ini都是适合的,而php-fpm.conf适合nginx+fcgi的配置
 
  首先选择产品环境的php.ini(php.ini-production)
 
  /home/oldboy/tools/php-5.3.27/php.ini-development
 
  /home/oldboy/tools/php-5.3.27/php.ini-production
 
  1.打开php的安全模式
 
  php的安全模式是个非常重要的php内嵌的安全机制,能够控制一些php中的函数执行,比如system(),同时把很多文件操作的函数进行了权限控制。
 
  该参数配置如下:
 
  safe_mode = off
 
  ;是否启用安全模式
 
  ;打开时,php将检查当前脚本的拥有者是否和被操作的文件的拥有者相同。
 
  默认的php.ini是没有打开安全模式的,我们把它打开如下:
 
  safe_mode = On
 
  2.用户组安全
 
  当safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且相同组的用户也能够对文件进行访问。建议设置为:
 
  safe_mode_gid = off
 
  如果不进行设置,可能我们无法对我们服务器网站目录下的文件进行操作了,比如我们需要对文件进行操作的时候。php5.3.27默认为safe_mode_gid = off
 
  3.关闭危险函数
 
  如果打开了安全模式,那么函数禁止是可以不需要的,但是我们为了安全还是考虑进去。比如,我们觉得不希望执行包括system()等在那的能够执行命令的php函数,或者能够查看php信息的phpinfo()等函数,那么我们就可以禁止它们,方法如下:
 
  disable_functions = system,passthru,exec,shell_exec,popen,phpinfo
 
  disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown
 
  4.关闭php版本信息在http头中的泄漏
 
  为了防止黑客获取服务器中php版本的信息,可以关闭该信息斜路在http头中。
 
  该参数默认配置如下:
 
  expose_php = On
 
  ;是否暴露php被安装在服务器上的事实(在http头重加上其签名)
 
  ;它不会有安全上的直接威胁,但它使得客户端知道服务器上安装了php.
 
  建议设置为
 
  expose_php = Off
 
  5.关闭注册全局变量
 
  在php中提交的变量,包括使用post或get提交的变量,都将自动注册为全局变量,能够直接访问,这是对服务器非常不安全的,所以我们不能让它注册为全局变量,就把注册全局变量选项关闭:
 
  默认配置:
 
  register_globals = Off
 
  ;是否将E,G,P,C,S变量注册为全局变量
 
  ;打开该指令可能会导致严重的安全问题,除非你的脚本经过非常仔细的检查。
 
  ;推荐使用预定义的超全局变量:$_ENV,$_GET,$_POST,$_COOKIE,$_SERVER
 
  ;该指令受variables_order指令的影响。
 
  ;php6中已经删除此指令。
 
  建议设置为:
 
  register_globals = Off
 
  6.打开magic_quotes_gpc来防止SQl注入
 
  magic_quotes_pgc = Off
 
  这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,比如把'转义为\'等,这对防止sql注入有重大作用,所以我们推荐设置为:
 
  magic_quotes_pgc = On
 
  7.错误信息控制
 
  一般php在没有连接到数据库或者其他情况下会有提示错误,一般错误信息中会包含php脚本当前的路径信息或者查询的SQL语句等信息,这类信息提供给黑客后,是不安全的,所以一般服务器建议禁止错误提示。
 
  该参数默认配置如下:
 
  display_errors = Off
 
  ;是否将错误信息作为输出的一部分显示给终端用户。应用调试时,可以打开,方便查看错误。
 
  ;在最终发布的web站点上,强烈建议你关掉这个特性,并使用错误日志代替(参看下面)。
 
  ;在最终发布的web站点打开这个特性可能暴露一些安全信息,
 
  ;例如你的web服务器上文件路径、数据库规划或别的信息。
 
  设置为:
 
  display_errors = Off
 
  (php5.3.27默认即为display_errors = Off)
 
  如果你确实是要显示错误信息,一定要设置显示错误的级别,比如只显示警告以上的信息:
 
  error_reporting = E_WARING & ERROR
 
  当然,最好是关闭错误提示。
 
  8.错误日志
 
  建议在关闭dispaly_errors后能够把错误信息记录下来,便于查找服务器运行的原因:
 
  log_errors = On
 
  php5.3.27默认即为log_errors = On
 
  同时也要设置错误日志存放的目录,建议根apache的日志存在一起:
 
  error_log = /app/logs/php_error.log
 
  注意:给文件必须允许apache用户的和组具有写的权限
 
  9.部分资源限制参数优化
 
  (1)设置每个脚本运行的最长时间
 
  当无法上传交大的文件或者后台设备数据经常超时,此事需要调整如下设置:
 
  max_execution_time = 30
 
  ;每个脚本最大允许执行时间(秒),0表示没有限制。
 
  ;这个参数有助于阻止劣质脚本无休止的占用服务器资源。
 
  ;该指令仅影响脚本本身的运行时间,任何其他花费在脚本运行之外的时间
 
  ;如用system()/sleep()函数的使用、数据库查询、文件上传等,都不包括在内。
 
  ;在安全模式下,你不能用ini_set()在运行时改变这个设置。
 
  (2)每个脚本使用的最大内存
 
  memory_limit = 128M
 
  ;一个脚本所能够申请到的最大内存字节数(可以使用K和M作为单位)
 
  ;这有助于防止劣质脚本消耗完服务器上的所有内存。
 
  ;要能够使用该指令必须在编译时使用"--enable-memory-limit"配置选项。
 
  ;如果要取消内存限制,则必须将其设为-1
 
  ;设置了该指令后,memory_get_usage()函数将变为可用。
 
  (3)每个脚本等待输入数据最长时间
 
  max_input_time = -1
 
  ;每个脚本解析输入数据(POST,GET,upload)的最大允许时间(秒)
 
  ;-1表示不限制
 
  设置为
 
  max_input_time = 60;
 
  (4)上传文件的最大许可大小
 
  当上传较大文件时,需要调整如下参数:
 
  upload_max_filesize = 2M;
 
  ;上传文件的最大许可大小,一些图片论坛需要这个更大的值。
 
  10.部分安全参数优化
 
  (1)禁止打开远程地址,记得最近出的php include的那个漏洞吗?就是在一个php程序中include了变量,那么入侵者就可以利用这个控制服务器在本地执行远程的一个php程序,例如phpshell,所以我们关闭这个。
 
  allow_url_fopen = Off
 
  (2)设定:cgi.fix_pathinfo=0防止Nginx文件类型错误解析漏洞
 
  cgi.fix_pathinfo=0
 
  11.调整php sesson信息存放类型和位置
 
  session.save_handler = files
 
  ;存储和检索与会话关联的数据的处理器名字。默认为文件("files")
 
  ;如果想要使用自定义的处理器(如基于数据库的处理器),可用"user"
 
  ;设为"memcache"则可以使用memcache作为会话处理器(需要指定"--enable-memcache-session"编译选项)
 
  ;session.save_path = "/tmp"
 
  ;传递给存储处理器的参数。对于files处理器,此值是创建会话数据文件的路径
 
  参考资料:
 
  LAMP系统性能调优,第1部分:理解LAMP架构
 
  http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-1/
 
  LAMP系统性能调优,第2部分:优化Apache和PHP
 
  http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-2.html
 
  LAMP系统性能调优,第3部分:MySQL服务器调优
 
  http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-3.html
 
  安装memcache客户端
 
  修改配置文件,在php.ini中全局设置:
 
  web集群session共享存储设置:
 
  默认php.ini中session的类型和配置路径:
 
  #session.save_handler = files
 
  #session.save_path = "/tmp"
 
  修改成如下设置:
 
  session.save_handler = memcache
 
  session.save_path = "tcp://10.0.0.18:11211"
 
  提示:
 
  1)10.0.0.18:11211为memcached数据库缓存的IP及端口
 
  2)上述适合LNMP,LAMP环境
 
  3)memcached服务器也可以是多台通过hash调度
 
  使用tmps作为缓存加速缓存的文件目录
 
  mount -t tmpfs tmpfs /dev/shm -o size=256m
 
  mount -t tmpfs /dev/shm/ /tmp/eaccelerator
 
  1.上传图片缩略图临时处理的目录/tmp
 
  2.其他加速器临时目录 /tmp/eaccelerator。

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读