加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Badoo 告诉你切换到 PHP7 节省了 100 万美元

发布时间:2016-10-01 09:17:52 所属栏目:PHP教程 来源:oschina
导读:副标题#e# 介绍 我们成功的把我们的应用迁移到了php7上面(数百台机器的集群),而且运行的很好,据说我们是第二个把如此规模的应用切换到php7的企业,在切 换的过程我们发现了一些php7字节码缓存的bug,庆幸的是这些bug现在已经被修复了,现在我们把这个激

我们能够注意到,所有这些修改都至少需要改变所有的扩展(即使不是完全重写)。虽然我们可以依赖内置扩展的作者进行必要的修改,我们也当然有责任自己修改他们,虽然工作量很大。由于内部API的修改,使得只修改一些代码段变得简单。

不幸的是,引入使代码执行速度提升的垃圾回收机制让引擎变得更加复杂并且变得更加难以定位问题。涉及到OpCache的问题。在缓存刷新期间,当可 用于别的进程的已缓存的文件字节码在此时损坏,就会导致崩溃。这就是它从外部看起来的样子(zend_string):使用方法名或者常量突然崩溃并且垃 圾就会出现。

鉴于我们使用了大量的内部扩展,其中许多处理都是专门针对字符串的,我们怀疑这个问题与如何使用字符串在内部扩展有关。我们写了大量的测试,并进行了大量的实验,但没有得到我们预期的结果。最后,我们从PHP引擎开发人员 Dmitri Stogov 那里寻求了帮助。
他的第一个问题是“你有没有清除缓存?”我们解释说,事实上,我们每一次都在清除缓存。在这一点上,我们意识到这个问题并不在我们这里,而是 opcache。我们很快就转载了这一案例,这有助于我们在几天内回复并解决这个问题。在7.0.4版本,这个修复没有出来,就不可能使php7进入稳定 产品。

更改测试基础设施

我们为我们在Badoo上做测试感到特别骄傲。我们部署服务器的PHP代码到产品环境,每天两次,每次部署包含20-50份任务量(我们使用功能分 支Git和自动化紧JIRA集成版本)。鉴于这种时间表和任务量,我们没有办法不选择自动测试。目前,我们大约有6万个单元测试,约50%的覆盖率,其运 行在云上,平均2-3分钟(参见我们的文章了解更多)。除了单元测试,我们使用更高级别的自动测试,集成和系统测试,并为网页做了Selenium测试,为手机客户端做了Calabash测试。作为一个整体,这使我们能够迅速达成与结论有关的代码,每个具体版本的质量,并应用相应的解决方案。

切换到新版本的解释器是一个充满潜在问题的重大变化,所以所有测试工作都是极其重要的。为了弄清我们到底做了什么,以及我们如何设法做到这一点,让我们来看看近几年测试开发在Badoo上是如何演变的。

通常,当我们开始考虑实施产品测试(或在某些情况下,已经开始实施的话)时,在测试过程中我们会发现他们的代码“并没有达到测试阶段”。出于这个原 因,在大多数情况下,开发者在写代码时要牢记,代码的可测试性是很重要的。架构师应允许用单元测试去取代调用和外部依赖对象,以便代码测试能与外部环境相 隔离。当然,毫无疑问这是一个备受憎恨的要求,很多程序员认为写“可测试性”的代码是完全不可接受的。他们认为,这些限制完全不顾“优秀代码”的标准而且 通常不会取得成功。你能想象到,大量不按规则编写的代码,导致测试为了等“一个更好的时机”被延迟,或者通过运行小型测试来满足并且在测试结果被推迟,或 实验者为了使自己运行的小测试能够通过,只做了能够通过的那部分(也就是指测试没有产生预期的结果)。
我并不是说我们公司是一个例外,从一开始,我们的项目也未执行测试。因为依然有几行代码在生产过程中正常运作,带来效益,所以正如文献中建议的,如果只是为了运行测试重写代码将是一件愚蠢的事情。那将占用太长的时间,花费太多。

幸运的是我们有一个很棒的工具来解决“未测试代码”的大问题——runkit。当脚本在运行时,这个 PHP 扩展允许你对方法、类及函数进行增、删、改的操作。此工具还有很多其它的功能但我们这里用不到它们。从 2005 年到 2008 年这个工具由 Sara Goleman(就职于 Facebook,有趣的是他在做 HHVM 方向的工作)开发和支持了多年。从 2008 年至今则由 Dmitri Zenovich (带领 Begun 和 Mail.ru 的测试部门)进行维护。我们也对这个项目做了些许贡献。

同时,runkit 是一个非常危险的扩展,它允许你在使用它的脚本在运行的时候对常量、函数及类进行修改。就像是一个允许你在飞行中重建飞机的工具。runkit 有直达 PHP “心脏”的权力,一个小错误或缺陷就能让一切毁掉,导致 PHP 失败或者你要用很多时间来查找内存泄漏或做一些底层的调试。尽管如此,这个工具对于我们的测试还是必要的:不需要做大的重构来完成项目测试只能在程序运行 的时候改变代码来实现。

但是在切换到PHP7的时候发现runkit带来了很大麻烦,因为它并不支持新的版本。我们当然也可以在新版本中添加支持,但是从长远考虑,这看起来并不是最可靠的解决途径。因此我们选择了其他方法。

最适合的方法之一就是从runkit迁移到uopz。后者也是PHP的扩展,有着(与runkit)类似的功能性,于2014年正式推出。我在 Wamba的同事建议使用uopz,它将有很好的速度体验。顺便说一下uopz的维护者就是Joe Watkins(First Beat Media公司,英国)。不幸的是我们迁移到uopz的测试程序无论怎样都无法成功运行。在某些地方总会发生致命的错误,出现在段错误中。我们提交了一些 报告,但很遗憾他们并没有动作(e.g. https://github.com/krakjoe/uopz/issues/18)。为了解决这种困境而重写测试程序的付出将会非常高昂,即使重写了也很容易再次暴露出问题。

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读