大头龙仔Blog

A strong man can save himself. A great man can save another.

['PHP 5' => 'PHP 7']

| Comments

一、背景介绍

  • 目前所维护的项目服务框架组成: Windows + C#, Linux + PHP + Python, MongoDB
  • 由于历史原因而存在两个操作系统平台,C#部分的代码逻辑耦合很强,拆分非常困难
  • 我们后端的人员储备基本上都是PHP的应用开发
  • 考虑未来迭代维护,我们需要去C#化
  • PHP 7带来了不错的性能提升,提前升级为C#改写为PHP做准备

二、PHP 7的一些变化

  • PHP 7 Release Note

  • ZVAL的变化

  • 结构体内存占用对比

我们可以看到,数据结构的变化还是非常大的,所以release note里的的关于大幅降低内存占用的那个item应该也不是吹的。

三、PHP 7为系统带来的提升

  • 一些经典的开源项目升级前后对比

  • ulabox.com升级PHP 7

  • 升级PHP 7后CPU与内存占用都大幅降低,为某公司年节省100w刀

四、升级PHP 7

(上面都在吹别人的,现在到我们自己折腾了)

1)PHP EXT之变

  • 在PHP7开始, 我们移除了MAKE_STD_ZVAL / ALLOC_ZVAL宏, 不再支持存堆内存上申请zval. 函数内部使用的zval要么来自外面输入, 要么使用在栈上分配的临时zval
  • 所以PHP 5的扩展模块是不能直接兼容PHP 7

2)MongoDB Driver For PHP 7

  • 当前使用的MongoDB扩展并不支持PHP 7

  • 发了邮件问作者 – –!!!

  • github上提的issue

  • PHPC-286

  • 看了源码,的确工作量巨大(mongo.so),而官方推荐使用的是这个 mongodb.so

  • 不幸的是,mongodb.so与mongo.so的接口调用方式还是有挺多不一样的,并且官方推荐使用mongo-php-library,所以有下面关系: PHP 5: mongo.so PHP 7: mongo-php-library(PHP) –> mongodb.so

  • 到这里,我只想说

3)升级后部分接口性能对比

  • PHP 7 VS PHP 5 (OPcache Enable, ms, less is better)

  • 我们发现get_raw_data_list接口性能大幅下降

4)XDebug + WinCacheGrind

  • 对get_raw_data_list进行调试

  • php中间层mongo-php-library加入,提升数据访问接口灵活性,但也导致了性能的降低,我们可以从上图中发现大量的bson对象的转换。

  • [‘typeMap’=>[‘root’=>‘array’,‘document’=>‘array’]],这个参数可以让该库不转换成bson对象,重新优化了代码后,耗时从922ms下降到398ms

5)升级后性能下降了?

  • 因为MongoDB的扩展驱动换了,所以这里不能做最直接的比较,但像get_raw_data_list这样的接口几乎是db的直接读取接口,所以驱动对其影响是最大的。

  • 我们也能注意到像get_summary, get_reputation_word_freq这样的接口性能提升了30%,这些接口主要是进行了数据的计算

  • C#的接口正在迁移中,所以暂时还没有实际的对比数据,但考虑到除7带来的提升外,相对老接口还会多引用多进程、多线程的处理,这里的优化数据还是非常值得期待

6)其它

  • 目前使用的是pcntl,后续会多加入pthreads以提高并行处理效率

  • 注意DEPRECATED in PHP 5.x, and REMOVED in PHP 7.0.0.的接口

  • 多了个php-cli.ini,cli下默认就用这个配置文件了

  • OPcache记得用上

五、结论

  • 新项目上PHP 7

  • 旧项目先评估PHP扩展模块的兼容性(包括公司内部的……)

  • PHP5与7可以共存一段时间,对比调试

  • 引入非官方扩展(自己写)时要慎重考虑,能用php语言自身解决的(socket, pack, unpack等),基决不用扩展。Less is more.

六、Reference

Comments