msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

04 Dec 15 让PHP7达到最高性能的几个Tips

PHP7已经发布了, 作为PHP10年来最大的版本升级, 最大的性能升级, PHP7在多放的测试中都表现出很明显的性能提升, 然而, 为了让它能发挥出最大的性能, 我还是有几件事想提醒下.

PHP7 VS PHP5.6

1. Opcache

记得启用Zend Opcache, 因为PHP7即使不启用Opcache速度也比PHP-5.6启用了Opcache快, 所以之前测试时期就发生了有人一直没有启用Opcache的事情. 启用Opcache非常简单, 在php.ini配置文件中加入:

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1"

2. 使用新的编译器

使用新一点的编译器, 推荐GCC 4.8以上, 因为只有GCC 4.8以上PHP才会开启Global Register for opline and execute_data支持, 这个会带来5%左右的性能提升(Wordpres的QPS角度衡量)

其实GCC 4.8以前的版本也支持, 但是我们发现它支持的有Bug, 所以必须是4.8以上的版本才会开启这个特性.

3. HugePage

我之前的文章也介绍过: 让你的PHP7更快之Hugepage , 首先在系统中开启HugePages, 然后开启Opcache的huge_code_pages.

以我的CentOS 6.5为例, 通过:

$sudo sysctl vm.nr_hugepages=512

分配512个预留的大页内存:

$ cat /proc/meminfo  | grep Huge
AnonHugePages:    106496 kB
HugePages_Total:     512
HugePages_Free:      504
HugePages_Rsvd:       27
HugePages_Surp:        0
Hugepagesize:       2048 kB

然后在php.ini中加入:

 opcache.huge_code_pages=1

这样一来, PHP会把自身的text段, 以及内存分配中的huge都采用大内存页来保存, 减少TLB miss, 从而提高性能.

4. Opcache file cache

开启Opcache File Cache(实验性), 通过开启这个, 我们可以让Opcache把opcode缓存缓存到外部文件中, 对于一些脚本, 会有很明显的性能提升.
在php.ini中加入:

opcache.file_cache=/tmp

这样PHP就会在/tmp目录下Cache一些Opcode的二进制导出文件, 可以跨PHP生命周期存在.

5. PGO

我之前的文章: 让你的PHP7更快(GCC PGO) 也介绍过, 如果你的PHP是专门为一个项目服务, 比如只是为你的Wordpress, 或者drupal, 或者其他什么, 那么你就可以尝试通过PGO, 来提升PHP, 专门为你的这个项目提高性能.

具体的, 以wordpress 4.1为优化场景.. 首先在编译PHP的时候首先:

$ make prof-gen

然后用你的项目训练PHP, 比如对于Wordpress:

$ sapi/cgi/php-cgi -T 100 /home/huixinchen/local/www/htdocs/wordpress/index.php >/dev/null

也就是让php-cgi跑100遍wordpress的首页, 从而生成一些在这个过程中的profile信息.

最后:

$ make prof-clean
$ make prof-use && make install

这个时候你编译得到的PHP7就是为你的项目量身打造的最高性能的编译版本.

暂时就这么多吧, 以后想起来再加, 欢迎大家尝试, thanks


分享到:



Related Posts:

Tags: , , , ,

38 Responses to “让PHP7达到最高性能的几个Tips”

  1. Name |

    PHP7快了不少。

  2. PHP程序员雷雪松 |

    好高端啊!!支持一下鸟哥!!

  3. yao |

    magento提升仍然有限,感觉magento踩了大坑

  4. MYZHANG QJZI |

    鸟哥。。这个大坑,zend_extension才能开启opcache,使用extension无法开启。。。

  5. Emilio Hancox |

    Menos mal que he dado con esta información. No sabe el tiempo que llevaba buscándola. Gracias. Abrazos!!!

    Masajes Relajantes – Masajes Eróticos – Masajes Tantricos

  6. ppto |

    php 内核代码在线查看工具, http://www.phpsourcechm.com 不用只为了看内核代码在本地装ide了。

  7. Anonymous |

    请评价一下laravel框架。谢谢。

  8. Jerray |

    Hello,鸟哥,遇到了奇怪的问题

    sysctl vm.nr_hugepages=512 这样开了HugePage以后,只要登录phpMyAdmin,FPM就会一直报 WARNING: [pool www] child 785 exited on signal 7 (SIGBUS……

    用gdb查看core dump结果如下

    Core was generated by `php-fpm: master process (/data/server/php/etc/php-fpm.conf) ‘.
    Program terminated with signal SIGBUS, Bus error.
    #0 zend_mm_alloc_small (size=, bin_num=8, heap=0x2aaaaac00040) at /data/software/php-7.0.4/Zend/zend_alloc.c:1284
    1284 heap->size = size;
    (gdb) bt
    #0 zend_mm_alloc_small (size=, bin_num=8, heap=0x2aaaaac00040) at /data/software/php-7.0.4/Zend/zend_alloc.c:1284
    #1 zend_mm_alloc_heap (size=, heap=0x2aaaaac00040) at /data/software/php-7.0.4/Zend/zend_alloc.c:1358
    #2 zend_mm_realloc_heap (heap=0x2aaaaac00040, ptr=0×0, size=, copy_size=79) at /data/software/php-7.0.4/Zend/zend_alloc.c:1454
    #3 0x00000000007abf5d in xbuf_format_converter (xbuf=xbuf@entry=0x7fff8800d7b0, is_char=is_char@entry=1 ’01′, fmt=0xddce8e “pool %s”,
    ap=ap@entry=0x7fff8800d7f8) at /data/software/php-7.0.4/main/spprintf.c:246
    #4 0x00000000007acbca in vspprintf (pbuf=0x7fff8800d8d8, max_len=0, format=, ap=ap@entry=0x7fff8800d7f8)
    at /data/software/php-7.0.4/main/spprintf.c:847
    #5 0x00000000007accb2 in spprintf (pbuf=pbuf@entry=0x7fff8800d8d8, max_len=max_len@entry=0, format=format@entry=0xddce8e “pool %s”)
    at /data/software/php-7.0.4/main/spprintf.c:871
    #6 0x00000000008906c5 in fpm_env_init_child (wp=wp@entry=0x1d38000) at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_env.c:142
    #7 0x000000000088c412 in fpm_child_init (wp=0x1d38000) at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_children.c:155
    #8 fpm_children_make (wp=wp@entry=0x1d38000, in_event_loop=in_event_loop@entry=1, nb_to_spawn=nb_to_spawn@entry=1, is_debug=is_debug@entry=0)
    at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_children.c:407
    #9 0x000000000088c875 in fpm_children_bury () at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_children.c:288
    #10 0x0000000000890de6 in fpm_got_signal (ev=, which=, arg=)
    at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_events.c:77
    #11 0x000000000089aed6 in fpm_event_epoll_wait (queue=, timeout=)
    at /data/software/php-7.0.4/sapi/fpm/fpm/events/epoll.c:147
    #12 0x00000000008916b1 in fpm_event_loop (err=err@entry=0) at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_events.c:411
    #13 0x000000000088c157 in fpm_run (max_requests=max_requests@entry=0x7fff8800dc78) at /data/software/php-7.0.4/sapi/fpm/fpm/fpm.c:115
    #14 0x000000000043fbfc in main (argc=6, argv=0x7fff8800dfa8) at /data/software/php-7.0.4/sapi/fpm/fpm/fpm_main.c:1882

    把 vm.nr_hugepages改回0,不会再出现这个问题。

  9. terry |

    正在试水中,7的性能和新特性让人期待。

  10. 正山小种属于什么茶 |

    看到最后,博主说“编译得到的PHP7是为项目量身打造的最高性能的编译版本”,一定要试一下啊…..看评论里大神们已经开始尝试了啊……

  11. chahualao |

    辛苦了。

  12. dearbaba |

    看了您的博文总结的非常好,您的博客非常不错。我也推荐一个程序员必备的搜索博客问答的网站 http://www.itdaan.com

  13. 烈火青春 |

    请问鸟哥平常用的什么开发工具?

  14. yumanutong |

    恩恩,还不错。路过的

  15. 石樱灯笼 |

    关于“专门为一个项目服务”,这里有什么特别的含义吗?
    如果我的php既跑php,又跑其他自己写的php程序,会有问题吗?

    HugePages那里例子是512M,我的vps如果不足512该怎么做呢?要填小一些吗?

  16. lagolas |

    每次编译到这里就这样,centos7 php7.0.1
    ext/openssl/.libs/xp_ssl.o: In function `php_openssl_setup_crypto’:
    /usr/local/src/php-src-php-7.0.1/ext/openssl/xp_ssl.c:1599: undefined reference to `SSL_CTX_set_alpn_protos’
    /usr/local/src/php-src-php-7.0.1/ext/openssl/xp_ssl.c:1604: undefined reference to `SSL_CTX_set_alpn_select_cb’
    ext/openssl/.libs/xp_ssl.o: In function `php_openssl_sockop_set_option’:
    /usr/local/src/php-src-php-7.0.1/ext/openssl/xp_ssl.c:2305: undefined reference to `SSL_get0_alpn_selected’
    collect2: error: ld returned 1 exit status
    make: *** [sapi/cli/php] Error 1

  17. lagolas |

    鸟哥 你好,你能发布一个php7安装配置以及依赖包的帖子吗?网上搜了好多安装,也都是各种问题,依赖包问题,以及配置问题。谢谢~

  18. lilj |

    @lx 刚才尝试关闭了opcache, 可以扑捉到core。 你可以试一试。

    @Laruence 给你的 l***e@php.net 发了一封邮件, 不知道能否收到。 谢谢

  19. lilj |

    @lx 没有解决

    @kn007 你可以去下载memcached的php7分支单独编译

  20. kn007 |

    鸟哥,PGO学习的话,代码含有PHP扩展怎么办?
    我代码调用了Memcached扩展,但是编译的时候不带这个mc扩展,sapi/cgi/php-cgi直接报fatal error。
    谢谢

  21. bruce |

    win server2012安装PHP7+fastcgi 想配置zend opcache但是php.ini里没有zend_extension=的选项,还需不需要加入zend_extension=”c:\php\ext\opcache.dll”这一行在php.ini里?

  22. lx |

    @lilj 你的502问题解决了吗? 我也遇见了一个很怪的问题,一个地方不报错,也没有报错和core dump, 但是切换回5.6,也没问题。

  23. sgub |

    已经把php7以及内置的extension都用gcc 4.9.2编译了。外部ext有必要用高版本gcc重新编译吗?比如 php-pecl-memcached?不需要的话我就直接拿remi的成品啦。

  24. lilj |

    鸟哥, 刚看到回复
    我的意思是能否给你发邮件沟通, 不是说给你发邮件了。

    目前已经切换回了5.6, 不敢拿用户试验太久
    据初步判断,是spl_autoload 会出现core dump
    我把用到autoload的几处地方改成include了, 情况有所好转
    但是另外一个地方也老是产生502错误, 也没有报错和core dump, 只能先切换回5.6
    等以后有时间再优化一下代码看看。

    谢谢

  25. cloud |

    鸟哥, osx 10.11 是不是只能用gcc编译,不能用clang?

  26. eechen |

    PHP7用opcache.file_cache导出opcode实现代码保护
    http://my.oschina.net/eechen/blog/539995

  27. laruence |

    @lilj 没收到你邮件啊, 你发送我gmail的?

  28. lilj |

    抱歉,我又来刷屏了


    (gdb) source /usr/local/src/php/php-7.0.0/.gdbinit
    (gdb) zbacktrace
    [0x7fe842c13520] spl_autoload_call(“Gifts_Model”) [internal function]
    [0x7fe842c134b0] class_exists(“Gifts_Model”) [internal function]
    [0x7fe842c13410] Controller->load(“Gifts_Model”) /mnt/data/env/php-7.0/lib/php/Yafext/Traits/Common.php:31
    [0x7fe842c13330] Controller->__get(“gifts_model”) /mnt/data/env/php-7.0/lib/php/Yafext/Traits/Common.php:18
    [0x7ffc105bc0b0] ???
    [0x7fe842c13140] Pvp_Fight_Controller->indexAction() /mnt/data/stable/sguo/server/app/controllers/Pvp/Fight.php:147
    [0x7fe842c130e0] Yaf_Application->run() [internal function]
    [0x7fe842c13030] (main) /mnt/data/stable/sguo/server/public/index.php:30


    $ cat /etc/php.ini |grep yaf
    extension=yaf.so
    [yaf]
    yaf.environ = product
    yaf.use_spl_autoload = 1

    问题似乎在yaf的use_spl_autoload 上
    我用了一句 Yaf_Loader::getInstance->autoload(‘Gfits_Model’);
    话说鸟哥能给回复邮件么? 这里交流实在太不方便了

    谢谢

  29. lilj |

    @laruence 你好
    经提醒开了core dump, 截取了以下数据

    ….
    Reading symbols from /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/yac.so…done.
    Loaded symbols for /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/yac.so
    Reading symbols from /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/redis.so…done.
    Loaded symbols for /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/redis.so
    Reading symbols from /lib64/libnss_files.so.2…(no debugging symbols found)…done.
    Loaded symbols for /lib64/libnss_files.so.2
    Core was generated by `php-fpm: pool alpha ‘.
    Program terminated with signal 11, Segmentation fault.
    #0 _emalloc () at /usr/local/src/php/php-7.0.0/Zend/zend_alloc.c:1291
    1291 heap->free_slot[bin_num] = p->next_free_slot;
    ….

    (gdb) where
    #0 _emalloc () at /usr/local/src/php/php-7.0.0/Zend/zend_alloc.c:1291
    #1 0x000000000062adf6 in zif_spl_autoload_call ()
    #2 0x000000000074807f in zend_call_function ()
    #3 0×0000000000748722 in zend_lookup_class_ex ()
    #4 0x000000000076bf24 in zif_class_exists ()
    #5 0x000000000079e9bd in ZEND_DO_ICALL_SPEC_HANDLER () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:586
    #6 0x0000000000790efb in execute_ex () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:414
    #7 0×0000000000748004 in zend_call_function ()
    #8 0×0000000000771244 in zend_call_method ()
    #9 0x00000000007891ec in zend_std_call_getter () at /usr/local/src/php/php-7.0.0/Zend/zend_object_handlers.c:202
    #10 0x000000000078a5ff in zend_std_read_property () at /usr/local/src/php/php-7.0.0/Zend/zend_object_handlers.c:564
    #11 0x0000000000791ab3 in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER ()
    at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:23382
    #12 0x0000000000790efb in execute_ex () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:414
    #13 0×0000000000748004 in zend_call_function ()
    #14 0×0000000000771244 in zend_call_method ()
    #15 0x00007fe8427a1b41 in yaf_dispatcher_handle () from /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/yaf.so
    #16 0x00007fe8427a2bf8 in yaf_dispatcher_dispatch ()
    from /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/yaf.so
    #17 0x00007fe84279e943 in zim_yaf_application_run ()
    from /mnt/data/env/php/lib/php/extensions/no-debug-non-zts-20151012/yaf.so
    #18 0x00000000007cdffb in ZEND_DO_FCALL_SPEC_HANDLER () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:842
    #19 0x0000000000790efb in execute_ex () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:414
    #20 0x00000000007d9ae7 in zend_execute () at /usr/local/src/php/php-7.0.0/Zend/zend_vm_execute.h:458
    #21 0x0000000000755c74 in zend_execute_scripts () at /usr/local/src/php/php-7.0.0/Zend/zend.c:1428
    #22 0x00000000006faee0 in php_execute_script () at /usr/local/src/php/php-7.0.0/main/main.c:2471
    #23 0x00000000007e505c in main () at /usr/local/src/php/php-7.0.0/sapi/fpm/fpm/fpm_main.c:1944

    技能太差不会用gdb
    希望能有用, 目前已经切换回5.6版本

    谢谢

  30. simon_qqmmmqq |

    鸟哥 NB

    [root@localhost php]# sysctl vm.nr_hugepages=512
    vm.nr_hugepages = 512
    [root@localhost php]# cat /proc/meminfo | grep Huge
    AnonHugePages: 288768 kB
    HugePages_Total: 0
    HugePages_Free: 0
    HugePages_Rsvd: 0
    HugePages_Surp: 0
    Hugepagesize: 2048 kB

    看看这个怎么回事?
    HugePages_Total: 0
    这个是代表huge pages 没设成功吗?

  31. Laruence |

    @lilj 看看是不是php-fpm coredump了

  32. lilj |

    昨天升级了生产环境中的一台

    升级后同样的配置, 相比其他5台

    php7这台的负载下去了, 但是(104: Connection reset by peer) 成8倍增长

    正在查原因

  33. Young |

    第四个厉害了 。 对于一些类库文件 简直就是预编译似的存在

  34. Lancer |

    不得不说PHP7真的性能提高了不少。过一段时间准备拿项目做升级试试水。

  35. barbery |

    还可以机器学习,生成个性的编译版本,PGO太屌了。。。

  36. Laruence |

    @xLight 懒死你算了

  37. xLight |

    pgo 之后的wordpress性能也应该show出来啊

  38. seatle |

    有点吊的,支持鸟哥

Leave a Reply

*