由网络副手--寻路人于2017.05.11 11:02:00发布在PHP代码 升级360问答PHP版本过程以及带来的性能提升 阅读2658 评论0 喜欢0 一、PHP7性能演示 1.1 性能展现 单个脚本:生成一个有50w元素的数组,逐个查找key是否存在 执行 PHP test7.php real 0.415s user 0.217s sys 0.144s 执行/usr/local/php7.0.10/bin/php testphp7.php real 0.149s user 0.076s sys 0.086s 在单个执行脚本紧依靠php7语言引擎解释性能提升3倍有余 1.2 新版本优化的点 大量的细节优化,检查PHP中的内置函数,思考有无提升的空间 Zval(PHP中储存变量的结构体) zval从24位缩减至16位 内部类型zend_string( PHP中储存字符串的结构体)进行了优化 PHP数组的变化(HashTable和Zend Array)HashTable从72位减少至56位 函数调用机制的改变(Function Calling Convention) 通过宏定义和内联函数(inline),让编译器提前完成部分工作 对相应扩展的升级 更详细的新特性,请参考:http://www.php7.site/book/php7/about-30.html 二、PHP版本升级函数的变更 2. 在升级中遇到函数变更带来的问题:记录如下 1.3.1 子类重写父类中的方法,需保证参数个数相同 PHP5.3以后有此要求,否则会报一个 E_STRICT 警告 方法名不区分大小写(一直如此),父类与子类中只有大小写不同的方法名也是重写,需要保证参数个数相同 1.3.2.调用时弃用引用传参 php5.4时被移除。 现要求:定义时使用引用参数,引用时直接使用参数传递 1.3.3 .json_encode和json_decode ① json_encode()使用:encode前需转为UTF-8格式 ② json_decode使用: 仅能对UTF-8格式的数据进行解码 如果被解码的数据中包含非小写的字面量,例如:'{"a":true,"b":"true","c":TRUE,"d":"TRUE"}', 无法被解析、解析时会产生警告(PHP5.6+) 原先decode出错时,会把源字符串直接返回,现在会返回null 1.3.4 .call_user_func()和call_user_func_array()方法 要求:传入call_user_func()的参数不能为引用传递 如: function increment(&$a) { $a ++; } $a = 1; call_user_func('increment', $a); //错误用法 返回$a值不变call_user_func('increment', &$a); //错误用法 会报fatal error PHP5.3之前,是否引用传参都可按引用传参方式使用,且不会报notice call_user_func_array('increment', array(&$a)); //之前可以统一这样使用 PHP5.3+ 中,必须在需要引用传参的时候,传递引用参数 call_user_func_array('increment', array(&$a)); //需要引用传参时 call_user_func_array('increment', array($a)); //不需要引用传参时,必须正常传参 1.3.5 mysql 扩展及系列函数被废弃 mysql扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。 mysql系列函数,例如: mysql_connect mysql_db_name mysql_db_query ...... mysql_close 都已废弃 替换方案:使用pdo_mysql扩展、mysqli扩展 1.3.6 .preg_replace() 函数中用到的 /e 修饰符现在被弃用。 方法作用:执行一个正则表达式搜索并且使用一个回调进行替换 现在使用 preg_replace_callback() 函数来替代 1.3.7 Mcrypt函数需要有效长度的密钥和初始向量 mcrypt_encrypt(),mcrypt_decrypt(), mcrypt_cbc(),mcrypt_cfb(),mcrypt_ecb(),mcrypt_generic() 以及 mcrypt_ofb() 函数不再接受无效长度的密钥和初始向量, 对于需要初始向量的分组加密模式,如果不提供初始向量,函数调用将会失败。 之前版本中,对于长度不足的密钥和初始向量会在其后补齐 '\0' 使其达到有效长度。 现在不接受$key和$iv参数为无效或者缺省的状态 三、升级步骤以及遇到的坑 3.1 梳理问答项目中依赖的PHP扩展和SDK,确定支持的稳定版本,搭建环境 PHP扩展: memcached和libmemcached类库的问题 mongodb扩展的API不友好的问题 redis当时最新版本(3.1.1)hgetall的使用存在bug的问题 zookeeper 当时没有官方稳定版,只有0.3.1 alpha版 SDK: idgenclient 仍使用memcache API quclient 仍使用类名作为构造函数的函数名 根据PHP手册上的changelog,找出变更的函数和使用,grep代码,批量修改 从PHP 5.6.x 移植到 PHP 7.0.x 从PHP 5.5.x 移植到 PHP 5.6.x 从 PHP 5.4.x 迁移到 PHP 5.5.x 从 PHP 5.3.X 迁移到 PHP 5.4.X 从 PHP 5.2.x 移植到 PHP 5.3.x 3.2 使用开源的PHP代码兼容检测工具 php7cc A command line tool designed to make migration from PHP 5.3-5.6 to PHP 7 easier. 使用composer 安装 https://github.com/sstalle/php7cc 使用方法: php7cc –extensions=php,inc,tpl dirname/filename 从代码层面找出不兼容的函数和使用(提示分级别,比较详细,给出所有可能出问题的提示) 3.3 diff线上和升级环境的请求结果 从线上的访问日志批量提取请求,同时访问两个环境的代码,diff结果 使用郭牛提供的webdiff工具 页面中存在着非功能性的差异(server_time、不同环境的图片地址不同、异步接口随机展现数据不同) 使用sed、awk提取请求和对比结果 3.4 逐步上线步骤和方法 小流量发布线上机器 遇到memcache与memcached扩展的不兼容问题。解决方法:加前缀来区分 各种由于memcache扩展变更导致的主从不同步问题。。。 批量发布线上机器 上线步骤:下线部分机器、部署PHP7环境、删旧代码、发新代码 机器升级步骤:每次升级两台 → 升级一半 → 升级剩余机器(保留对照机) 升级worker机、导入机、用户行为机 逐个过一遍每个consumer任务、crontab任务 手工执行脚本文件排错 线下流程大范围报错,debug过程继续修改代码 3.5 升级过程对项目扩展带来的要求 PHP5 PHP7 apc ZendOpCache gearman √ memcahce memcached mongo mongodb mysql × PDO √ pdo_mysql √ redis √ zookeeper √尚未发布稳定版本 xhprof × 3.6 使用memcached扩展时的问题 memcached客户端功能更丰富、更强大,且找不到支持PHP7的memcache扩展 升级时的过渡状态,两个客户端需要共存。为解决共存问题,通过加前缀区分 Memcache扩展 Memcached扩展 第三方依赖 不需要 需要libmemcached库 哈希分布策略和 代码忽略.. 哈希函数配置 设置是否压缩 使用长连接 3.7 使用redis扩展的问题 支持PHP7的redis版本为3.0.0+ 选择了redis3.1.1, 使用 hgetall()方法,总是报“内存越界”错误 修改配置、gbd调试,都不行。版本降为3.0.0, 解决问题 四、升级结果以及带来的性能体验 问答全站 18个模块 涉及机器: 前端机 35台 后端机 19台 worker机 6台 数据导入机 7台 用户行为机 2台 Beta机 6台 性能提升 (涉及到了I/O操作,访问文件,网络或数据库连接) 页面 QPS 持续时间 响应时间(PHP5) PHP7 提升比较 CPUIDLE(PHP5) PHP7 比较 详情页: 50 3600 197 177 10%升 83% 88% 6% 100 3600 239 212 11% 45% 69% 53% 100 14400 142 列表页: 20 3600 119 88 26%升 86% 91% 6% 40 3600 109 89 18% 86% 91% 6% 50 14400 90 96% 主 页: 20 3600 81 70 14%升 86% 97% 13% 40 3600 86 76 12% 88% 95% 8% 50 14400 95% 踩到的坑总结: 模块过多,同一功能的基类在各个模块都有出现,修改代码量增加n倍 机器类别多,对应每种机器的环境不一致(qbus扩展问题没法统一安装),不同机器的升级步骤不同(删掉的代码目录不同,发布的代码模块不同) 废弃的代码多,很多代码没从代码库中去掉或者做标识,废弃代码中存在问题多,加大了升级工作量 赞 0 分享 赏 您可以选择一种方式赞助本站 支付宝扫码赞助 BraveDu 署名: 网络副手~寻路人