37

opcache,提升PHP性能的利器

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwOTU4NzM5Ng%3D%3D&%3Bmid=2455771508&%3Bidx=1&%3Bsn=7cf7530265bec7f29c232ea3194ad00f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

昨天《如何衡量单机PHP支撑能力》提到了OPcache,今天在自己的ECS上做了些测试,结果令人激动。

什么是Opcache

即使不使用OPcache,PHP7的性能也是非常高的。PHP脚本每次运行的时候,都要动态解析PHP代码,然后再执行。

如果将解析的结果保存下来,这样执行的时候就省去了解析,执行的性能就会提升。

将代码解析结果保存到共享内存中,这就是OPcache,PHP-FPM worker进程都能使用该内存区域。

如何启用OPcache

PHP5.6以上的版本默认编译了OPcache,不过要真正启用,必须在php.ini中配置 zend_extension=opcache.so,动态加载 Zend extension。

如果php -v 出现with Zend OPcache v7.2.8, Copyright (c) 1999-2018, by Zend Technologies,说明启用了OPcache。

如何配置OPcache

具体见 www.php.net/manual/zh/opcache.configuration.php,说几个有用的。

opcache.enable 表示启用OPcache。

opcache.enable_cli 表示PHP命令行也启用OPcache。

opcache.memory_consumption 表示共享内存的大小。

opcache.interned_strings_buffer PHP相同字符串可以保存到共享内存中。

opcache.validate_timestamps 如果是1表示每次都会检查PHP文件的更新时间,以便确定是否使用OPcache,在生产环境中建议关闭,这样性能更高,那如果源文件修改了怎么办?后面会说。

opcache.max_accelerated_files 表示可缓存文件的最大个数。

opcache.enable_file_override 如果开启,则在调用函数 file_exists(),is_file() 以及 is_readable() 的时候,都会检查OPcache。

opcache.file_cache 可以将OPcache导出到外部文件,这样即使重启PHP,外部文件的OPcache也能使用,但自己没有开启。

如何运用在生产环境

OPcache确实很好,但如果opcache.validate_timestamps关闭,那么源文件如果变更,如何能够更新OPcache呢?

有两种方法,第一个就是重启PHP-FPM,第二个就是调用 opcache_reset() 函数。

重启PHP-FPM不太适合,比如在QA环境,不能修改一行代码就启动PHP-FPM,所以目前的方法就是QA代码(if/else)使用opcache_reset()强制不使用OPcache。

那么生产环境如何更新OPcache呢?目前的方法就是在ssh git分发代码的时候,增加curl一个接口,该接口就是执行opcache_reset()。

OPcache统计

内置opcache_get_status()函数可以了解统计数据,比如:

[memory_usage] => Array
(
    [used_memory] => 21200864
    [free_memory] => 113016864
    [wasted_memory] => 0
    [current_wasted_percentage] => 0
)

[interned_strings_usage] => Array
(
    [buffer_size] => 8388608
    [used_memory] => 710928
    [free_memory] => 7677680
    [number_of_strings] => 16899
)

[opcache_statistics] => Array
(
    [num_cached_scripts] => 36
    [num_cached_keys] => 44
    [max_cached_keys] => 16229
    [hits] => 36
    [start_time] => 1591457444
    [last_restart_time] => 1591457446
    [oom_restarts] => 0
    [hash_restarts] => 0
    [manual_restarts] => 1
    [misses] => 36
    [blacklist_misses] => 0
    [blacklist_miss_ratio] => 0
    [opcache_hit_rate] => 50
)

[scripts] => Array

free_memory 表示共享内存还有多少没有用;current_wasted_percentage表示浪费的内存,达到一定比例,会自动清除OPcache;opcache_hit_rate表示OPcache命中率;scripts 表示查看那些脚本被缓存了。

具体效果

使用ab进行并发测试。

yum -y install httpd-tools
ab -n 10000 -c 500 url #并发500

在开启OPcache的时候:

Concurrency Level:      500
Time taken for tests:   38.155 seconds
Complete requests:      10000
Failed requests:        340
   (Connect: 0, Receive: 0, Length: 340, Exceptions: 0)
Write errors:           0
Non-2xx responses:      340
Total transferred:      1938420 bytes
HTML transferred:       564000 bytes
Requests per second:    262.09 [#/sec] (mean)
Time per request:       1907.740 [ms] (mean)
Time per request:       3.815 [ms] (mean, across all concurrent requests)
Transfer rate:          49.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       14  510 1156.1     25   15056
Processing:    19  398 1557.7     32   29043
Waiting:       19  398 1557.7     32   29043
Total:         33  908 2014.5    269   32053

没有开启的情况下:

Concurrency Level:      500
Time taken for tests:   28.447 seconds
Complete requests:      10000
Failed requests:        7663
   (Connect: 0, Receive: 0, Length: 7663, Exceptions: 0)
Write errors:           0
Non-2xx responses:      10000
Total transferred:      2784615 bytes
HTML transferred:       1270593 bytes
Requests per second:    351.53 [#/sec] (mean)
Time per request:       1422.361 [ms] (mean)
Time per request:       2.845 [ms] (mean, across all concurrent requests)
Transfer rate:          95.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       14  326 1302.2     23   15060
Processing:    14 1035 1884.1     27    9045
Waiting:       14 1035 1884.1     27    9045
Total:         29 1361 2246.7     58   21169

有的同学很奇怪,怎么开启OPcache的情况下,执行时间反而更长?原因在于并发数太高,而单请求响应时间长,PHP-FPM worker子进程达到了500;而开启OPcache的时候,执行效率高,worker进程没有超过20,所以其总体时间更长。

另外如果没有开启OPcache,则CPU负载瞬间飙到10以上;而开启OPcache的话,CPU负载没有超过1。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK