Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • PHP

    • PHP-FPM使用指南
    • PHP7新特性总结
    • PHP安全编程
    • PHP安全配置总结
    • PHP变量的值类型和引用类型
    • PHP标准规范PSR
    • PHP操作Zookeeper实践
    • PHP错误和异常处理机制详解
    • PHP的Session运行机制
    • PHP底层运行机制和原理
    • PHP反射模拟实现注解路由
    • PHP高级用法总结
    • PHP开发常用文档总结
    • PHP开发入门:Memcached扩展安装
    • PHP开发入门:PHP7安装部署
    • PHP开发入门:Redis扩展安装
    • PHP开发SPL总结
    • PHP框架常见URL模式
    • PHP扩展开发入门
    • PHP垃圾回收机制
    • PHP类的自动加载
    • PHP输入输出流
    • PHP微服务开发指南
    • PHP协程
    • PHP写时拷贝技术
    • PHP性能优化之Opcache
      • Zend引擎
      • Zend Opcache
      • A/B测试
    • PHP依赖注入和控制反转
    • PHP运行模式(SAPI)
    • PHP中file_get_contents与curl区别
    • RPC的简单实现
    • Protobuf:高效数据结构化工具
    • P3P协议详解
    • Laravel之集合(Collection)总结
    • Laravel实践总结
    • Laravel之ORM总结
    • 中高级PHP实践总结
    • PHP Socket编程实战
  • Golang

  • Python

  • Javascript

  • 其他语言

  • 编程语言
  • PHP
Ravior
2017-08-27
目录

PHP性能优化之Opcache

Opcache全程Operation Code, 意为操作码。由于PHP是解释型语言,当解析器执行PHP脚本时会解析脚本代码,将它们生成可以直接运行的中间代码,称为Zend OpCode, 类似于Java的ByteCode。

# Zend引擎

opcache

Zend引擎是PHP的编译引擎和执行引擎,当它执行一段PHP脚本时,会依次按照如下步骤执行:

  • Scan:扫描,将PHP代码转换成语言片段。
  • Parse:解析,将语言片段组合成有意义的表达式。
  • Complie:编译,将表达式编译程OpCode。
  • Excute:执行,顺次执行OpCode。

Nginx或其他Web服务器把HTTP请求转发给PHP-FPM, PHP-FPM再把请求交给某个PHP子进程处理,PHP进程找到PHP脚本后执行,把脚本编译为OpCode后生成响应。我们从图中看到PHP脚本被编译为Zend Opcode后生成内容,然后被发送到浏览器客户端。

如果每次请求一个PHP脚本都要编译一次Zend OpCode,然后执行字节码,就会消耗很多资源。如果每次HTTP请求PHP都必须不断解析、编译和执行PHP脚本,消耗的资源更多。如果有一个工具能缓存预告编译好的字节码,减少应用的响应时间,降低系统资源压力,这当然就是我们想要的方式—字节码缓存。

字节码缓存的共通特性就是能够存储预先编译的Zend OpCode,使用OpCode缓存后,当请求一个PHP脚本时,不用再读取、解析和编译PHP代码。PHP解释器会从内存中读取预先编译好的字节码,立即执行。这样就能节省很多时间,极大提升应用的性能。

opcache

# Zend Opcache

在PHP5.5以后,Zend OpCache虽然被内置,但默认没有启用,需要显式指定启用Zend OpCache。

如果是自己编译的PHP运行环境,需要在configure命令时包含如下:

--enable -opcache

编译好,须在php.ini文件中配置Zend OpCache。

zend_extension=opcache.so
[opcache]
;开启opcache
opcache.enable=1  

;CLI环境下,PHP启用OPcache
opcache.enable_cli=1

;OPcache共享内存存储大小,单位MB
opcache.memory_consumption=128  

;PHP使用了一种叫做字符串驻留(string interning)的技术来改善性能。例如,如果你在代码中使用了1000次字符串“foobar”,在PHP内部只会在第一使用这个字符串的时候分配一个不可变的内存区域来存储这个字符串,其他的999次使用都会直接指向这个内存区域。这个选项则会把这个特性提升一个层次——默认情况下这个不可变的内存区域只会存在于单个php-fpm的进程中,如果设置了这个选项,那么它将会在所有的php-fpm进程中共享。在比较大的应用中,这可以非常有效地节约内存,提高应用的性能。
这个选项的值是以兆字节(megabytes)作为单位,如果把它设置为16,则表示16MB,默认是4MB
opcache.interned_strings_buffer=8

;这个选项用于控制内存中最多可以缓存多少个PHP文件。这个选项必须得设置得足够大,大于你的项目中的所有PHP文件的总和。
设置值取值范围最小值是 200,最大值在 PHP 5.5.6 之前是 100000,PHP 5.5.6 及之后是 1000000。也就是说在200到1000000之间。
opcache.max_accelerated_files=4000

;设置缓存的过期时间(单位是秒),为0的话每次都要检查
opcache.revalidate_freq=60

;从字面上理解就是“允许更快速关闭”。它的作用是在单个请求结束时提供一种更快速的机制来调用代码中的析构器,从而加快PHP的响应速度和PHP进程资源的回收速度,这样应用程序可以更快速地响应下一个请求。把它设置为1就可以使用这个机制了。
opcache.fast_shutdown=1

;如果启用(设置为1),OPcache会在opcache.revalidate_freq设置的秒数去检测文件的时间戳(timestamp)检查脚本是否更新。
如果这个选项被禁用(设置为0),opcache.revalidate_freq会被忽略,PHP文件永远不会被检查。这意味着如果你修改了你的代码,然后你把它更新到服务器上,再在浏览器上请求更新的代码对应的功能,你会看不到更新的效果
强烈建议你在生产环境中设置为0,更新代码后,再平滑重启PHP和web服务器。
opcache.validate_timestamps=0 

;开启Opcache File Cache(实验性), 通过开启这个, 我们可以让Opcache把opcode缓存缓存到外部文件中, 对于一些脚本, 会有很明显的性能提升.
这样PHP就会在/tmp目录下Cache一些Opcode的二进制导出文件, 可以跨PHP生命周期存在.
opcache.file_cache=/tmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

重启PHP FPM,使用phpinfo函数查看,确认Zend OpCache是否正常工作,如图所示:

opcache2

# A/B测试

现在我们对开启Opcache效果进行A/B测试,以请求phpinfo.php为例。

未开启:

Document Path:          /phpinfo.php
Document Length:        94760 bytes

Concurrency Level:      100
Time taken for tests:   39.205 seconds
Complete requests:      10000
Failed requests:        880
   (Connect: 0, Receive: 0, Length: 880, Exceptions: 0)
Total transferred:      949419025 bytes
HTML transferred:       947599025 bytes
Requests per second:    255.07 [#/sec] (mean)
Time per request:       392.054 [ms] (mean)
Time per request:       3.921 [ms] (mean, across all concurrent requests)
Transfer rate:          23648.95 [Kbytes/sec] received
1
2
3
4
5
6
7
8
9
10
11
12
13
14

未开启状态下,TPS:255/s。

开启后:

Document Path:          /phpinfo.php
Document Length:        99540 bytes

Concurrency Level:      100
Time taken for tests:   35.199 seconds
Complete requests:      10000
Failed requests:        9041
   (Connect: 0, Receive: 0, Length: 9041, Exceptions: 0)
Total transferred:      997228816 bytes
HTML transferred:       995408816 bytes
Requests per second:    284.10 [#/sec] (mean)
Time per request:       351.995 [ms] (mean)
Time per request:       3.520 [ms] (mean, across all concurrent requests)
Transfer rate:          27666.80 [Kbytes/sec] received
1
2
3
4
5
6
7
8
9
10
11
12
13
14

开启后,TPS: 284/s, 性能提升11.4%, 开启后效果还是非常棒的。

#PHP
上次更新: 2022/12/01, 11:09:34
PHP写时拷贝技术
PHP依赖注入和控制反转

← PHP写时拷贝技术 PHP依赖注入和控制反转→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式