Modern PHP 笔记(三):部署测试和调优

有时候,我们会听说关于一些公司采用 Facebook 的开源项目的事情。Box
团队近期给我们发送了他们是如何使用 HHVM
的故事,是一个很好的文章。所以我们把他贴在这里,
我们感谢他们以这种方式发给我们.。我们也会寻求反馈意见.。你们可以在Facebook
Engineering 主页
或者在 GitHub联系到我们。

By Joe Marrama, class=”wp_keywordlink”>软件工程师,Box团队

从Facebook的GitHub账户中可以看到,Facebook已经开源的开源项目有近300个,领域涉及移动、前端、Web、后端、大数据、数据库、工具和硬件等。Facebook开源项目负责人James
Pearce曾在OSCON解释过Facebook究竟为何要使用、支持和发布开源项目。具体如下:

系列笔记:Modern PHP 笔记:语言特性Modern PHP 笔记:良好实践Modern PHP
笔记:部署测试和调优

减少延迟和增加我们的基础设施的能力一直是 Box
最优先考虑的问题。我们努力以最有效的方式提供最好的用户体验,并且以前我们的
PHP
还选择不与这些目标一致。我很高兴地说,对于这两个目标我们最近取得了非常显著的进步,成功的部署了
HHVM(HipHop虚拟机)作为我们 PHP
代码的独家引擎服务;在这篇文章的其余部分,我将详细介绍如何使用PHP,如何使用HHVM,我们所面临的挑战是HHVM迁移,和提供卓越的性能。

共享Facebook的代码促进了这个世界的创新。这些代码帮助他人更快地开发软件。因为Facebook不是一家软件公司,所以它在开源过程中没有面临竞争对手的威胁,相反,开源带来的价值在逐渐显现。用户使用Facebook的开源代码可以更快地构建应用,而他们也乐于回馈代码,使Facebook从中受益。拥抱开源,意味着Facebook必须一开始就写出更优秀的软件。如果他们知道某个软件从诞生起就要公开,那就必须要好好做,提高可用性和可靠性,因为将来外面的人都会用它。这种压力也会给公司内部带来更多的价值。开源带来了共享挑战的机会。开源项目面临的难题会吸引一些外部的优秀人员,而结果是,他们也带动了公司内部人员的能力提升。每天Facebook都承载了超过一亿人的沟通互联,何以能做到?唯有开源的力量。

可选:

Box中的PHP

在 Box 里,PHP
是开发栈的核心部分。尽管我们在大量的后台服务中使用了许多语言,然而每个后台服务都要求我们首先和
PHP web 应用进行交互。从 Box 诞生那一天开始,我们产品的核心功能都是使用
PHP 来实现的。

减缓由超过150个活跃贡献者编写的和超过75万行代码组成的还在不断增长的
PHP代
码所带来的延迟是最大的挑战。我们不能对我们提供服务的大部分页面进行缓冲处理,因为用户通常希望
Box
上的各种各样的动作都是原子性的。随着我们产品的不断成长、演变,这本身就会增大延迟。我们曾经一直投入巨大的努力来减少延迟,然而似乎一直没有找到好的办法。我们重构了旧的、效率低下的代码;把一些自身可独立做为组件的提取出来做为
PHP
扩展;这样就会大量地缓冲请求时可共享的保持不变的状态,然而,所做的一切都只是微微地减少了延迟,所取的效果很容易由新的功能来替代性的实现。然而自去年我们花时间对
HHVM 进行全面评估开始,这一切就有所改变。

下面是我整理的Facebook现有的比较活跃的开源项目列表,欢迎交流讨论。

  • 共享服务器
  • 虚拟私有服务器VPS
  • 专用服务器
  • PaaS

HipHop 虚拟机(HHVM)

HHVM 是由 Facebook 牵头开发的开源 PHP 解释器。它诞生初期是做为 PHP 到
C++ 的编译器,是对 Facebook 的 PHP
代码库进行大量的裁剪基础上产生的,不过,最近几年它已经成长为一个即时(JIT)编译器。简言之,即时编译器就是以统一的方式对经常需要执行的
PHP 代码块进行编译并装载。演进为即时编译器也使得 HHVM 获得了与通常 PHP
解释器几乎相同的功能,同时 HHVM 现在还支持更多 PHP
语言的动态机制。例如,旧的 PHP 到 C++ 的编译器就无法运行 PHP
的”eval”语句(”eval”是把字符串当做 PHP 代码来执行,而 C++
不支持这样的功能),而新版本的 HHVM 就可以。由于 HHVM
已经成长为即时编译器,因此它已经逐渐大量替换了标准的 PHP 解释器。

一年多以前,我们就留意到 HHVM 团队把大量的精力都集中在获得与普通的 PHP
解释器同样的功能上。过去,我们曾经对 HHVM 进行评估,不过证明要让 HHVM
正确地运行我们开发的 web
应用非常困难。然而,这次我们重新迎接这一挑战,对 HHVM
进行全面评估,确定它在延迟方面的效果。把 HHVM 合并到我们的开发栈里和让
HHVM
运行我们部分代码是一项非常重要的任务,不过潜在回报很快证明我们的努力是值得的。我们最初的试验显示:HHVM
运行一个核心端点要比默认的 PHP 解释器快四倍多。

这标志着为期一年的把我们的产品安全地移植并运行在 HHVM
上的奋斗开始了。在移植过程中,我们在开发栈的许多地方都遇到各种各样的挑战。我们遇到大部分重大困难其他人在运行时也会遇到。在接下来的一部分,我将详细说明运行
HHVM 时通常遇到四个难点:解决存在在 HHVM
和默认的解释器之间的意想不到的不兼容性;回避二者之间可预料的不兼容性;对
PHP 的部署进行修补;确保在这一混合环境下一切可以非常良好的运行。

移动开发框架:React Native

目标:安装Web服务器,以便接收HTTP请求;设置并管理一组PHP进程,处理PHP请求,进程可以与web服务器通信。

获得同等的功能

PHP
是一个非常庞大的语言。仅它的核心运行环境就包含大量的函数,配置设置和大量的类,这些都是十多年的社团贡献累积而来的。这甚至还不包括大量的
PHP 扩展,所有这些扩展也必须移植到 HHVM 上。让 HHVM 具有与默认的
PHP解释器几乎完全相同的功能本身就是惊人的重大壮举。我们试图说明这两个运行时环境行为上的差异。

我们发现大量的运行时差异是在 PHP
中几乎不经常使用的地方。其中一些差异是极易发现的错误,通过单元测试就可发现错误。而一些差异则是隐藏很深的漏洞,这些漏洞可引起非常严重的后果。HHVM
每天都会接近 PHP
解释器所提供的功能,然而移植这么庞大的代码库必然会使更多的行为上的差异浮出水面。自动测试是一种最安全的保障措施,它可以排除那些影响到用户功能的运行时差异。要让
HHVM 通过我们的 PHPUnit
测试套件是要花大力气的,即要进行许多修补才能获得同等功能。手工测试则是另一种必不可少的保障措施,尤其可以找到外部服务和
HHVM 之间交互时出现的错误。在 HHVM
使用在生产环境前,我们通过自动测试和手工测试混合的方法发现了大量功能存在差异的地方。

对 HHVM 运行时环境差异的修补过程非常有趣。HHVM
社团非常活跃,在很短的时间内就可以在
GitHub
或者 HHVM 的 IRC
聊天室获得帮助。HHVM
的代码库充分利用到了现代C++的各种构件,同时理解和给代码库做出贡献也相对容易多了。在发布
HHVM 之前,我们贡献了大约 20 个用于解决功能不等同问题和增强功能的补丁。

React
Native是Facebook在2015年开源的基于React.js的移动开发框架,它的设计理念是让移动应用既拥有Native的用户体验,同时又可以保留React的开发效率,提高代码的复用率。React
Native的宗旨是,学习一次,高效编写跨平台原生应用。开发者可以使用JavaScript编写应用,并利用相同的核心代码就可以创建Web、iOS
和Android平台的原生应用,目前已经实现了对iOS和Android两大平台的支持。

一般选择nginx。因为apache为每个PHP请求派生一个子进程,比较耗资源。

设计方面的差异

在进行移植期间,我们发现两个运行时环境几个行为方面不一致的地方,这些不一致使得基本的设计有所不同。这可能是需要解决的最棘手的差异化问题。例如,HHVM
的多路处理模型(MPM)与以前我们曾经使用过的 Apache prefork
多路处理模型完全不同。HHVM 给每个请求提供服务的是一个工作者线程,而
Apache prefork
则给每个请求提供服务的是一个工作者进程。这对我们来说就有一点挑战。一旦发现问题所在,我们首先要做的就是进行相对简单的漏洞修复-我们曾经使用过
PHP 的进程 ID 来区分日志文件和其他临时文件。由于 HHVM
使用的是单一进程,因此当前的进程 ID
是不能用来区分并发的多个请求了。发现到这个漏洞后,我们对代码库中可能收到新多路处理模块影响的所有功能进行了一次全面的核查,例如,设置创建文件的模式的掩码和切换目录。

一个特别令人意想不到的行为上的差异是通过运行 PHP
的”memory_get_usage“函数使自身显露出来的,这个函数是用来汇报分配给当前请求的内存数量的。对于某种请求流,我们将根据这个函数汇报的数值定期地刷新内存中的缓冲数据。这个差异影响到
HHVM 的内存预分配库
jemalloc。jemalloc
是一个基于 Slab
的分配器,这种分配器分配的是各种大型的内存块,较小的内存分配则由这些内存块来分配。HHVM的“memory_get_usage”返回的是分配给某个请求的所有
slab
的总的大小,而不是实际上这个请求正在使用的slab内存的数量。当我们继续以同样的方式运行HHVM的“memory_get_usage”时,特定的请求流就会出现行为错乱,就会在本地缓冲数据区乱冲乱撞,这必然使得后台系统负载大大地增加。很幸运,可以完全修补这个问题:通过更改
HHVM
汇报的内存机制使得其汇报的是该请求实际上使用的本地内存数量(即通过设置参数
“$real_usage” 参数为 true 实现)。

由 HHVM
的多路处理模块(MPM)的差异还引起了另一个更加严重的问题:内存泄漏!在
Apache prefork
的多路处理模块(MPM)里,缓慢的内存泄漏不会太引起人们的关心,因为工作者进程在服务完一定量的请求后会被回收。而在
HHVM 里,这种待遇不再有了。我们在多天非标准负载的 HHVM
上碰到了非常难以处理的内存泄漏。经过大量对 jemalloc
的仔细设置,我们追踪到问题是由第三方库引起的,并马上对其打上补丁。打上这个补丁之后,在许多天服务数百万个请求的情况下,HHVM
的内存消耗始终保持稳定。

GitHub主页:-nativeStar数量:33108

然后作者展示了一个登陆VPS的例子:需要ssh登陆、创建非根用户管理web服务器,不要使用root

修正部署

HHVM运行在最佳性能时有两点与众不同的,这两个不同点迫使我们重新思考了一下我们PHP应用的部署方式。第一个不同点是HHVM需要对新编写代码“热身”以后才能达到最佳性能。由于HHVM是一个即时编译器(JIT),因此需要对新编写的代码运行几次后,才能收集到足够的信息,进而对这些代码进行转换,最终达到有效装配。实际上,在对当前请求服务之前,这样的转换是发生在curl请求的几个重大节点上的。第二个不同点是规律性地重新启动HHVM以达到最佳性能。这使得升级HHVM就容易多了,同时也是一个保障HHVM和其连接库出现内存泄漏的好方法。要满足上面两点需要对Apache通常的PHP部署稍作调整。

以前我们是通过Apache
web服务器单个实例为整个站点提供服务的,同时我们通过转换指向当前代码库的符号链接来实现多个代码库之间循环访问的。现在,我们使用三个HHVM实例为各种请求提供不间断的服务。通常情况下,其中一个HHVM实例为当前应用的所有请求提供服务,另外两个实例做为备用,为以前的应用和以前的以前的应用提供服务(见下图)。每个HHVM
web服务器都指向一个绝对路径,因此当我们需要部署新版本的时候,我们只要停止指向旧版本的web服务器,启动指向新版本的服务器,并使用多个curl请求对代码库进行热身,再重定向请求就可以了。这种部署方式满足了上段提到的两个不同点,这样可以很容易地实现回滚和前期测试。要回滚到以前版本,我们可以把请求重定向到提供以前版本代码服务的HHVM实例上(注意这个HHVM实例已经在运行)。要对新部署的应用进行前期测试,我们只要把一部分请求路由到新的HHVM实例上,测试一直持续到我们确信新的部署稳定时为止。这种部署已证明非常强大:在生产环境下可以处理大容量的请求。

图片 1

常见的HHVM服务器

图片 2

部署代码后的HHVM服务器

数据查询语言:GraphQL

因为使用密码登陆有漏洞,尽量使用SSH密钥对认证。SSH密钥对登录流程如下:

现存的混合状态

毫不奇怪,迁移到 HHVM
过程中最危险的部分是将其推出应用。没有足够的测试以确保 HHVM
在生产环境中可以完美处理所有请求并与后续系统完美配合。HHVM
在预生产环境中的重度测试中表现良好,但是我们任然对此表示怀疑。此外,我们不能提供一个独立的只读生产环境供
HHVM 测试,而且我们不能容许有任何的停机时间。对我们来说,应用 HHVM
唯一可行的方式是具有长期,充分观察的实验过程的可控方式。这需要使 HHVM
运行在与 Apache 和默认 PHP
解释器相同的环境中。只有在这种情况下最终存在,才可以使我们成功放出
HHVM,而不会使 HHVM 对用户有负面影响。

我们的 PHP
代码库与大量的不同后端系统交互。幸运的是,绝大多数交互的发生是通过 curl
对内部 REST
APIs 的请求,curl
是经过非常充分测试和稳定的 HHVM curl 扩展。我们使用 PDO
扩展来与我们的
MySQL 数据库服务器交互,同样表现出了与默认 PHP
解释器相同的功能行为。可能有潜在麻烦的后端系统是
Memcached,为了确保两个运行时中完整的互操作性,两个运行时都必须具有功能相等的
Memcached
扩展而且都必须是相同的序列化对象。如果任何一个运行时的序列化对象有不同行为,在另一个运行时中从
Memcached
中回复对象序列化在不同格式时就会轻易造成严重破坏。我们在混合环境中进行了众多的实验以确保两个运行时都不会毒化
Memcached
或任何其他后端存储。所有事情都表现的很好,除了一个小问题:ArrayObjects。在标准的
PHP 解释器中,实现 ArrayObject 的扩展定义了一个自定义的序列格式,然而
HHVM 中只使用标准的对象序列。我们需要在我们的应用中禁用 ArrayObjects
缓存以确保 Memcached
的互操作性。幸运的是,我们在推出之前或过程中不会再遇到任何其他的互操作性问题。

在上线过程中,一个非常有用的处理工具就是我们简单到爆的主机转换法。尽管使转换到
HHVM
的过程尽可能简单是一件再明显不过的事,但它任然值得我们在所有场合拿出来炫耀一下。我们决定通过
puppet 将 HHVM 部署在一个 host-by-host 基础上,转换过程是通过 puppet
中可以由主机名调整的一个标志控制的。主机转换到 HHVM
和回滚的操作仅仅需要调整标志的条件,不需要从负载平衡器上移除主机,也不需要做其它任何事。完整的回滚操作可以五分钟内完成,多主机一次性快速迁移和回滚是必须的。

上线过程中我们所有网络应用的登录和监控系统是至关重要的,但是有一种形式的监控被证明特别有用;监控
HHVM 错误日志以得到新的错误。我们维护了一个内部数据库,它包含有我们从
Apache 错误日志中观测到的所有独特的 PHP 错误。当上线 HHVM
时,这个系统告诉我们所有发生在 HHVM
上的新错误,通过对错误进行分类,并使用 PHP
错误数据库判断其是否是一个之前存在的错误。这使我们更多地了解到 HHVM
是否导致了任何新的倒退。

GraphQL是Facebook开源的数据查询语言。Facebook在构建移动应用程序时,需要用API获取足够强大的数据来描述所有的脸谱,同时简单易学易用,于是开发了GraphQL,并支持每天千亿级的调用。GraphQL不是像MySQL或Redis这样直接面向数据的接口,而是面向已经存在的应用代码的接口。你可以把GraphQL看作是为了调用应用服务器上的方法的一些内嵌的RPC。

使用SSH密钥对认证方式登录远程设备时,远程设备随机创建一个消息,使用公钥加密,然后把密文发给本地设备,本地设备收到密文后使用私钥解密,然后把解密后的消息发给远程服务器。远程服务器验证解密后的消息之后,再赋予你访问服务器的权限。

大棒末端的胡萝卜:HHVM 的好处

图片 3

大部分基础设施迁移到 HHVM 期间的服务器端延迟。迁移大约是在 10:50am 到
1:00pm 之间进行的。

与我们前期的测评一致,HHVM
大幅度地缩减了服务器端延迟。上面的图片显示了我们将大部分生产基础设施迁移到
HHVM 那天的迁移期间服务器端延迟。从图中可以直观地看出,HHVM
明显地减小了服务器端延迟。HHVM 平均可以将服务器端的延迟降低为原来的
2/5,这里的服务器端延迟是请求进入我们的基础设施到响应离开之间经过的时间。更令人印象深刻的是,这个数字包括等待后端服务响应的时间,本质上,所有的请求都对许多不同的服务进行了调用。没有
HHVM,很明显我们不可能有其他方式可以如此大幅度地消减延迟。更重要的是,HHVM
对延迟的影响可以从用户的反应中轻松得到。

图片 4

大部分基础设施迁移到 HHVM 期间一个数据中心的 CPU 使用率。

HHVM 也可以大幅度提高效率。上面的图片是我们大部分服务器迁移到 HHVM
期间的平均前端 CPU 使用率。可以看出,CPU 的使用率约为原来的
1/2。这免费地将我们的前端容量扩大了一倍,因为 CPU
使用率是我们前端机器的主要限制因素。在我们的领域内,这将显著节约服务器的开支、电力消耗和对数据中心容量的需求。

HHVM 在速度和高效性之外还提供许多令人惊奇的功能,包括:

  • 运行 Hack 代码的能力。Hack
    提供很多我们想要的功能,包括一个有表现力的类型系统,一个类型检查器和对异步执行的支持。我们认真地评估了在我们的
    PHP 代码库中大规模使用 Hack 的可行性。
  • 精致的性能分析工具。HHVM 实现了许多性能分析机制,包括那些可以在
    XDebug 扩展中找到的,和一个被称为 Xenon 基于时间的取样分析器。HHVM
    还与 jemalloc 的内存分析工具完美整合以提供详细进程规模的度量和分析。
  • 更大地提升速度,效率和代码质量的可能性。HHVM
    在这一领域提供的主要便利就是“仓库授权”模式,在这里,你可以将 PHP
    预编译成中间代码并使其替代运行,仓库授权模式禁止使用较多的 PHP
    动态特性,例如将字符串作为 PHP
    代码执行。我们的经验是,使用它可以提高 15% 的速度和效率。
  • 一个非常活跃的社区。HHVM 在争取与默认 PHP
    解释器相同地位的道路上快速发展,并进行性能提升和扩展移植。HHVM
    正处于一个快速的版本迭代过程中,社区对问题和和并请求的响应非常迅速。

总而言之,将 PHP 运行时迁移到 HHVM
并不是一个简单的过程,但是是件非常值得的事。必我们须要小心进行,提前做大量的测试并且要时刻保持警惕,完全有可能安全且零停机地完成这个过程。需要特别关注的是部署架构,转换方法,对所有运行时的不兼容进行修复和监控。HHVM
在加速受 CPU 限制的 PH
P应用时具有非常巨大的潜力,而且它还具有许多其他优点。我们对于 HHVM
现在驱动 Box 感到非常兴奋,而且将为进一步挖掘 HHVM 的潜力,使 Box
尽可能地快速可靠地工作。

GitHub主页:数量:2902

适合在一台电脑中登录远程,多台不适合。

大数据查询引擎:Presto

 // 生成私钥、公钥文件 ~/.ssh/id_rsa 和 ~/.ssh/id_rsa.pub ssh-keygen // 复制公钥到服务器 scp ~/.ssh/id_rsa.pub deploy@100.10.3.1: // 末尾要加':',会复制到家目录 // deploy用户登录服务器 // 确认有~/.ssh目录,没有则创建目录和文件,文件存储允许登录的公钥 touch ~/.ssh/authorized_keys cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys // 修改几个目录和文件的权限,只让deploy用户访问 chown -R deploy:deploy ~/.ssh chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys

Presto是Facebook开发的一款分布式SQL引擎,主要用于针对各种大小的数据源来运行交互式分析查询。Facebook创建Presto的主要目的在于帮助他们更快地分析数据,因为Facebook的数据量一直在持续增长,产品周期的节奏也变得越来越快。自从2013年11月开源后,Presto的用户量呈现了爆发式增长。诸如Airbnb、京东、Dropbox以及Netflix等公司都将Presto作为自己的交互式查询引擎。

禁用密码,禁止根用户登录

这样最安全

 // /etc/ssh/sshd_config PassWordAuthentication 设置为no PermitRootLogin 设置为no

PHP FastCGI Process Manager(PHP
FastCGI进程管理器)。它会创建一个主进程,控制何时以及如何把HTTP请求转发给一个或多个子进程处理。PHP-FPM还需控制何时创建、销毁PHP子进程。

GitHub主页:数量:4792

全局配置

CentOS主配置文件:/etc/php-fpm.conf建议修改默认配置:

 emergency_restart_threshold = 10 // 指定时间内,失效的PHP-FPM子进程超过这个值,让PHP-FPM主进程优雅重启 emergency_resttart_interval = 1m // 指定时间跨度

PHP执行引擎:HHVM

配置进程池

让各个PHP-FPM进程池都以指定的操作系统用户和用户组的身份运行,每个PHP用户一个非根用户,这样查看和管理都很方便。

HHVM是Facebook于2013年开源的PHP执行引擎。它采用一种JIT的编译机制实现了高性能,同时又保持对
PHP
语法的充分支持。HHVM常常用作独立的服务器,用于替代Apache与mod_php,旨在执行使用Hack与PHP所编写的程序。它使用了即时编译方法来实现超高的性能,同时又保持了PHP开发者所习惯的灵活性。

配置虚拟主机

CentOS: /etc/nginx/conf.d/example.conf

 server { listen 80; server_name example.com; index index.php; client_max_body_size 50M; error_log /home/deploy/apps/logs/example.error.log; access_log /home/deploy/apps/logs/example.access.log; root /home/deploy/apps/example.com; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ .php { try_files $uri =404; fastcgi_split_path_info ^$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; } }

location / {}使用try_files指令查找匹配所请求的URI文件,先查询所请求的URI文件,找不到则查询目录,也找不到会改写URL为index.php开头的,交给location ~ .php {}处理。把请求交给9000端口处理,前面已经设置PHP-FPM监听9000端口。

  • Puppet
  • Chef
  • Ansible
  • SaltStack

一般在/etc/php5/fpm/,
命令行php运行的是另一个php.ini文件,一般在/etc/php5/cli/

我也在安装目录下lib找到了这个文件。

memory_limit = 128M

这个值可以考虑总共分配内存,和每个PHP进程占用内存,大概算出。也可以用apache
bench或seige做压测

主要是ini文件里一堆opcache开头的配置,用的时候查文档吧

 file_uploads = 1 upload_max_filesize = 10M max_file_uploads = 3

默认同时上传20个,每个2M,不很合适。

 max_execution_time = 5

PHP进程最长用时,默认30秒太长了。如果有长时间运行的任务,要在单独的职程中运行。

PHP中的exec()函数调用bash的at命令。用于派生单独的非阻塞进程,不耽误当前PHP进程。exec()要使用escapeshellarg()函数转义shell参数。比如要生成一个pdf文件,需要等待10分钟,应该单独编写一个php文件create_report.php,让这个文件运行10分钟。

 <?php exec('echo "create_report.php" | at now'); echo 'Report pending...';

create_report.php脚本在单独的后台执行,运营完毕后可以更新数据库或者通过电子邮件把报告发给收件人。

如果要派生很多后台进程,最好用专门的队列。PHPResque等。

php默认的会话处理会拖慢大型程序,因为需要把会话数据存储在硬盘。我们应该保存在内存中,使用memcached或者redis。也便于伸缩,硬盘上数据不适合增加额外服务器。

使用memcashed需要安装PECL扩展,然后更改ini

使用较少的块发送更所数据,下面是等凑够4096字节再发

 out_buffering = 4096 implict_flush = false

php会缓存应用使用的文件路径,这样每次包含或导入文件时就无需不断搜索包含路径了。这个缓存叫真实路径缓存。realpath_cache_size
= 64k

  • 让部署变得简单
  • 部署结果可预知
  • 部署可逆

capistrano运行在本地设备,通过ssh与远程服务器通信。

GitHub主页:数量:13652

capistrano的工作方式

capistrano会在远程服务器中保存之前部署的应用,而且每次部署的版本放在各自的目录中。capistrano还会创建一个current/目录,通过符号连接指向当前部署的应用所在的目录。当部署应用时,capistrano会首先从git仓库获取最新代码,然后把代码放到realeases/的一个新子目录,然后把current/符号连接指向新目录。

  • Deployer
  • Magallanes
  • Rocketeer

从长远来看,测试省钱,省精力

  • 开发前:把测试工具当做项目开发的重要依赖
  • 开发中,每个功能都要编写并运行测试
  • 开发后,编写新测试,确保修补缺陷的方式是正确的

单元测试和功能测试

  • 单元测试:使用PHPUnit或者PHPSpec
  • 测试驱动开发: 编写之前写测试,再开发,然后再写测试,再开发
  • 行为驱动开发: 编写故事,描述应用的表现。
    • SpecBDD:也是单元测试,使用人类能读懂的语言。比如PHPUnit风格测试命名为testRenderTemplate(),
      等价SpecBDD命名为itRendersTheTemplate(),
      而且会使用诸如$this->shouldReturn()、$this->shouldbe()之类易于理解的辅助方法。
    • StoryBDD:类似,但是更多关注整体行为。StoryBDD用于测试产品经理的需求(要生成报告,并且电子邮件发送给用户),SpecBDD测试开发的需求(这个类方法只能接收一个数组)

术语:PHPUnit测试在一起组成测试用例(test
case),测试用例在一起组成测试组件(test
suite),PHPUnit会使用测试运行程序(test runner)运行测试组件。

一个测试用例是一个PHP类(且以Test结尾,文件名以Test.php结尾),扩展自PHPUnit_Framework_TestCase类。测试用例中有一些以test开头的公开方法,一个方法是一个测试,在方法中我们断言会发生什么事。断言可能通过也可能失败,目标是使断言都通过。

测试运行程序默认使用命令行运行程序,调用phpunit命令。

JavaScript库:React

安装

PHPUnit用于测试,用composer安装;XDebug用于生成覆盖度信息,是PHP扩展,用包管理器安装。

紧接着,书中有一个具体的测试用例,用的时候找更详细的blog看看吧

原生提供钩子,可以集成github仓库,每次提交后,都能自动测试,并在多个版本中测试。

指的是分析应用的性能。

什么时候使用?

当遇到性能瓶颈时再使用。

  • 在开发环境:XDebug。它的结果人类读不懂,需要KCacheGrind或者WinCacheGrind形象化展示。
  • 在生产环境:XHprof,使用XHGUI展示结果。

为节省资源,配置成触发执行,具体配置略

接下来讨论的是PHP的未来。

传统的PHP解释器是Zend Engine, HHVM(Hip Hop Virtual
Machiane)由Facebook开发,目的是提高性能,HHVM先把PHP代码转换成字节码,然后缓存字节码,然后使用JIT编译器(Just
in
Time)转换并优化成x86_64机器码。这样传统的解释型语言就有了一些编译型语言的速度。JIT提供了很多底层性能优化。

HHVM和Zend Engine是等价的。相当于PHP+PHP-FPM。

HHVM配置也是用php.ini文件

推荐使用Supervisord监控,HHVM挂掉后立即重启。

他们把自己看做PHP的方言,为PHP引入了新的数据类型和结构,以及静态类型。

React是Facebook开发的用于构建用户界面的JavaScript库,现已为很多公司所用,因为它采用了一种不同的方式来构建应用:借助于React,开发者可以将应用分解为彼此解耦的独立组件,这样就可以独立维护并迭代各种组件了。2015年,React有两个主要的发布,同时还发布了React
Native,并且发布了新的开发者工具。现在已经有越来越多的公司开始使用React构建自己的产品了。

从PHP转向Hack

<?php改成<?hh

GitHub主页:数量:43146

类型

静态语言,通常都要编译,编译器提供类型检查和错误报告,通常更稳定。缺点是要先编译,反馈回路长。

动态语言,通常解释执行,在运行时发现错误。迭代速度快,反馈及时。缺点是,没有类型检查,缺少内在的准确性。

键值存储系统:RocksDB

hack两者兼有

hack基本兼容PHP

查了下最新的情况,PHP7性能卓越,Hack优势不明显了,前景不明。

以上就是这本书的精华,不过瘾的话强烈推荐购买。欢迎交流

RocksDB是Facebook开源的嵌入式、可持久化键值存储系统,它基于Google的LevelDB,但提高了扩展性可以运行在多核处理器上,可以有效使用快速存储,支持IO绑定、内存和一次写负荷。过去一段时间,RocksDB在社区非常流行,Facebook分析其原因在于它能够对由于网络延迟等原因造成的慢查询响应时间起到消除的作用,RocksDB非常灵活,完全可以针对各种新兴的硬件发展趋势进行定制。LinkedIn与Yahoo都是RocksDB的重度使用者。

GitHub主页:数量:5418

人工智能硬件平台:Big Sur

近些年,人工智能和机器学习方向取得了长足的发展。据Kevin
Lee透露,Facebook的AI软件已经能够阅读故事、回答相关场景的问题、玩游戏以及通过一些例子来学习非指定的内容。作为计算密集型的应用,AI软件的性能与数据集规模/硬件性能密切相关。尤其是硬件方面,高性能微处理器、存储器以及图形处理器的发展为AI算法的快速运行提供了坚实基础。为了进一步更好地服务大规模AI计算,Facebook推出了基于GPU的、用于训练神经网络的“Big
Sur”硬件系统。

了解更多:-BigSur-OpenSource

网络模拟测试工具:ATC

Augmented Traffic Control能够利用Wi-Fi网络模拟2G、2.5G、3G以及LTE
4G移动网络环境,测试工程师们可以快速在各种不同的模拟网络环境中切换,从而实现对智能手机和App在不同国家地区和应用环境下的性能表现进行测试。ATC是Facebook内部团队在2013年的一次Hackathon活动上开发出来的工具,其原理实际是利用了Linux流量控制系统,通过纯Python的网络库pyroute2调用netlink的API控制,而开发其的目的是为了确保更多的用户获得最好的应用体验。

GitHub主页:-traffic-controlStar数量:2962

开源数据库:HydraBase

HydraBase是HBase数据库的升级版。Facebook是HBase的重度用户,Facebook的HBase数据库系统存储着Facebook的很多关键业务数据,包括内部监控系统、搜索索
引、流数据分析以及数据抓取等。HydraBase相比HBase稳定性和可用性更高,可以减少服务器宕机时间。HydraBase能够让一个数据域分布在多个域服务器中,域服务器之间能相互备份,因此能够大大减少数据恢复所用的时间。Facebook声称HydraBase能将Facebook全年的宕机时间缩减到不到5分钟。

Facebook已经将HydraBase捐赠给Apache,目前很多代码都已经被合并到HBase中。

关系型数据库:WebScaleSQL

WebScaleSQL是基于MySQL 5.6
社区版本改编的MySQL通用分支,基于GPL开源协议发布。WebScaleSQL目前已经做了很多性能改进工作,包括:客户端异步协调、逻辑预读、查询限流、服务端线程池优化、InnoDB大页支持等等。WebScaleSQL上的功能都是很“Web
Scale”和接地气的。比如线程池优化,WebScaleSQL基于Mariadb的线程池实现进行重写并优化,对读写队列进行分离,重新设计队列优先级策略,避免了饿死现象。要知道线程饿死在有些场景下是很严重的。尤其是在并发连接数往往很大的互联网应用里面。

GitHub主页:-5.6Star数量:2940

代码审查工具Phabricator

代码审查方面,Facebook开源了可视化工具Phabricator。工程师可以在页面上非常方便的针对每一段代码进行交互讨论;负责审查的工程师可以接受代码改变,可以提出疑问要求原作者继续修改,可以提出自己不适合以推出该代码审查,等等。只有代码被明确接受之后才能被工程师提交到服务器端的代码库,这一点集成到提交工具中强制执行。

GitHub主页:数量:7022

C语言事件框架:libPhenom

libPhenom是Facebook发布的一个C语言事件框架,用于构建高性能和高可扩展的系统。支持多线程、提供内存管理和常用数据结构、JSON处理。特性如下:

带有计数器的内存管理——记录应用程序正使用的内存类型的次数工作——分解你的应用程序并用调度管理来搞定它们带缓冲的I/O流常用的数据结构数据类型的变种来使能JSON的序列化和反序列化带有注册对象格式的printf的实现

GitHub主页:

Star数量:1334

C++HTTP框架:Proxygen

Proxygen是一款Facebook开源的支持SPDY
3.1的HTTP框架。其目的不是替换Apache,而是有能力创建一个专用的高性能Web服务器,使其可以嵌入到Facebook提供Web服务的现有应用中。Facebook从2011年开始构建一款代理服务器,在该项目演进并在生产环境中测试了数年之后,Facebook将其代码开源了。
Facebook内部做的基准测试表明,在一个Proxygen
echo服务器上,每秒可以支撑多达304 197次基于SPDY 3.1的内存GET请求。

GitHub主页:数量:3961

开源动画库:Pop

Pop是Facebook推出的一个可扩展的iOS 和OS
X动画库,其新闻聚合阅读应用Paper背后的核心技术就是由Pop支持。除了增加基本的静态动画外,还支持Spring和衰变动态动画,可非常方便的构建现实的、基于物理的交互。Pop动画库的动画效果非常流畅,因为它使用了CADisplayLink来刷新画面,一秒钟刷新帧数为60帧,接近于游戏开发引擎。Pop动画的自成体系,与系统的CoreAnimation有很大的区别,但使用上非常相似。

GitHub主页:数量:15468

Memcached协议路由器:Mcrouter

Mcrouter 是一个基于Memcached 协议的路由器,它是
Facebook缓存架构的核心组件,在峰值的时候,它能够处理每秒50亿次的请求。Memcached服务的客户端都会使用标准ASCII编码的Memcached协议,所以对于客户端来说,Mcrouter就像一个Memcached服务器;而对于服务器端来说,Memcached却又像一个普通的Memcached客户端。Mcrouter主要使用C++开发,且使用C开发了功能库部分,使用Ragel开发了协议解析部分,使用开源库Folly和Fbthrift处理异步网络。

GitHub主页:数量:1473

静态代码分析工具:Infer

Infer是Facebook的开发团队在代码提交内部评审时,用来执行增量分析的一款静态分析工具,在代码提交到代码库或者部署到用户的设备之前找出bug。由OCaml语言编写的Infer目前能检测出空指针访问、资源泄露以及内存泄露,可对C、Java或Objective-C代码进行检测。Facebook使用Infer自动验证iOS和安卓上的移动应用的代码,bug报告的正确率达80%。Infer通过捕获编译命令,把要被编译的文件转换为可用于分析潜在错误的中间语言格式。整个过程是增量进行的,意味着通常只有那些有修改过并提交编译的文件才会被Infer分析。Infer还集成了大量的构建或编译工具,包括Gradle、Maven、Buck、Xcodebuild、clang、make和javac。

GitHub主页:数量:5259

操作系统监控工具:osquery

osquery是一款面向OSX和Linux的操作系统检测框架。它将操作系统暴露为一个高性能的关系型数据库,允许用户编写SQL查询查看操作系统数据。在osquery中,SQL表代表像下面这样的抽象概念:

正在运行的进程已加载的内核模块打开的网络连接

虽然osquery利用了非常底层的操作系统API,但它允许用户在Ubuntu、CentOS和Mac
OS
X上构建并使用它。osquery性能极高,内存占用小,支持用户在整个基础设施上执行查询。

GitHub主页:数量:6209

JavaScript静态类型检查工具:Flow

Flow是Facebook出品的一个JavaScript代码的静态类型检查工具,该工具采用开放源码的OCaml语言开发,。Flow能够帮助开发人员查找出JavaScript代码中的类型错误,从而提高开发效率和代码质量。Flow已经能够捕获JavaScript代码中的常见问题,如静态类型转换不匹配、空指针引用等问题。同时,Flow还为JavaScript新增了类型语法,如类型别名。

GitHub主页:数量:7510

Haskell库:Haxl

Facebook开源了Haxl,一个为高效并发数据访问而开发的库。这个库一方面利用了Haskell的传统优势,比如表达力很强的类型系统、对正确性和安全性的保障,另一方面也受益于GHC的高性能运行时库,解决烦人的隐式并发数据访问的问题。Haxl简化了对远程数据的访问,比如数据库或网站服务。对同一数据源的多个访问请求,或同时从不同的数据源请求数据,它都能批量处理,并且缓存上一次的结果。

GitHub主页:数量:2257

Web应用架构:Flux

Facebook认为MVC无法满足他们的扩展需求,因此他们决定使用另一种模式:Flux。由于Facebook非常巨大的代码库和庞大的组织,所以MVC真的很快就变得非常复杂,于是他们得出结论,认为MVC不适合于大规模应用。

每次Facebook工程师努力增加一项新特性时,系统的复杂性成级数增长,代码变得“脆弱和不可预测”。对于刚接触某个代码库的开发人员来说,这正成为一个严重的问题。Flux是一个Facebook开发的、利用单向数据流实现的应用架构,用于
React。Flux应用有三个主要的部分组成:调度程序、存储和视图。

GitHub主页:数量:11616

JavaScript单元测试工具:Jest

Jest是一个开源的、基于Jasmine框架的JavaScript单元测试工具。Jest源于Facebook两年前的构想,用于快速、可靠地测试Web聊天应用。它吸引了公司内部的兴趣,Facebook的一名软件工程师Jeff
Morrison半年前又重拾这个项目,改善它的性能,并将其开源。

在最基础层面,Jest被设计用于快速、简单地编写地道的JavaScript测试。Jest自动模拟require()返回的CommonJS模块,并提供了包括内置的测试环境Dom
API支持、合理的默认值、预处理代码和默认执行并行测试在内的特性。通过在并行进程中同时运行测试,Jest让测试更快地结束。

GitHub主页:数量:4119

基于Atom的开发工具集:Nuclide

Nuclide是Facebook
推出的一套基于Atom的开发工具集,用于开发基于Hack的Web应用,提供自动完成和JavaScript类型检查,内建React开发支持,并支持Facebook最新的React
Native库,支持Facebook的Flow
JavaScript类型检查器。Nuclide的设计目是为了在整个公司为工程师提供一套标准的开发者经验——无论他们从事纯iOS应用,React和React
Native代码,或者在Hack运行我们的HHVM网络服务。

GitHub主页:数量:4412

Android调试工具:Stetho

Stetho是一个Android应用的调试工具。当Android应用集成Stetho时,开发者可以通过访问Chrome,在Chrome
Developer
Tools中查看应用布局、网络请求、sqlite、preference等等,可视化一切应用操作。开发者也可通过它的dumpapp工具提供的命令行接口来访问应用内部。

GitHub主页:数量:5079

Android编译工具:Buck

Buck受到了Google
Blaze的启发,创建它是为了处理与多个Android库有复杂关联的应用程序,从而减少构建时间。引入Buck之后,Facebook开发的四种本地Android应用程序中使用了单一的代码树和构建工具,这让开发更简单、更流畅,错误更少。最初的38个库在四种应用程序之间共享了500个模块。使用Buck替换了最初基于Ant的系统之后,第一次针对代码树运行时,构建时间就从3分40秒降到1分30秒。

相比传统的Android编译工具,Buck凭借多核及并行技术,极大加速了Android工程的编译速度。同时,多次编译过程中,它会对未变动的模块进行标记,以增量式编译的方式进一步提高速度。Buck自带编译脚本生成功能,并提供编译过程中单元测试的代码覆盖率等数据表单,还为无法用Ant工具编译的模块提供了便捷的编译方式。Buck跟IntelliJ结合紧密,可通过简单的编译脚本生成该IDE可用的工程,极大降低了本地IDE开发后向服务器迁移的成本。

GitHub主页:数量:2686

弹簧模型Java库:Rebound

Rebound是一个弹簧模型Java库,由Facebook于2013年10月在Mobile@Scale大会上发布,旨在应用中引入真实的物理世界,创建让人感觉很接近自然的动画。Rebound不是通用物理库,但是,弹簧模型能够驱动各种各样的动画。Rebound的简单特性使它很容易被集成,以及作为构建块创建如呼叫、滚动条和切换开关等复杂组件。

GitHub主页:数量:3455

移动应用交互设计工具:Origami

现在App的原型设计越来越复杂,以前使用PhotoShop制作静态图的方式不能满足各种交互效果的展示,Paper的首席设计师Mike
Matas在加入Facebook之初就推荐大家使用Quartz
Composer来快速构建应用原型,而Facebook的设计团队也很快接收并喜欢上了这个工具,在随后的应用,他们遇到了一个问题:对于产品设计师来说,Quartz
Composer 的学习曲线太高。

于是Mike就带头开发了Origami。2013年12月,Facebook 开源了基于 Quartz
Composer 的插件Origami,设计师可以通过 Origami
能够快速构建移动应用交互原型,随后交付给工程师实现,值得注意的是 Origami
无需编程背景,新发布的 Paper 从项目设计之初所有的原型设计都是采用
Origami 来实现。

GitHub主页:数量:3186

UI测试工具:huxley

Huxley
是一个基于Python用于Web应用UI测试的工具,Huxley可以录下UI操作过程,并回放自动测试。自动测试时和UI基准对比,UI不符合预期时,会保存变化的
UI 并警告你。

GitHub主页:数量:3891

Facebook iOS UI工具:ComponentKit

ComponentKit
使用功能性和声明性的方法来进行创建界面,和以往不同的是,ComponentKit
使用单向数据流的形式从不可变的模型映射到不可变的组件来确定视图的显示方式。ComponentKit
的 declarative 看上去和 declarative UI(QML) 差不多,其实差得远。QML
更偏向于 UI 设计的描述性,而 ComponentKit 则是做好基本 UI
和事件之间的联系,让事件设计和 UI 设计可以分开单独完成。

GitHub主页:数量:3095

iOS内存监测工具:FBMemoryProfiler

FBMemoryProfiler是Facebook开源的一款用于分析iOS内存使用和检测循环引用的工具库。

手机设备的内存是一个共享资源。应用程序可能会不当的耗尽内存、崩溃,或者遭遇大幅度的性能降低。当分配了一块内存,并设置了对象之后,如果在使用完了之后忘记释放,这就会发生内存泄露。这意味着系统是无法回收内存并交予他人使用,这也最终意味着我们的内存将会逐渐耗尽。

在Facebook,有很多工程师在代码库的不同部分上工作。这不可避免的会发生内存泄露。当发生内存泄露之后,工程师需要尽快找到并修复它们。一些工具已经可以找到内存泄露,但是它们需要大量的人工干预。自动化可以在不需要更多开发者的情况下,更快的找到内存泄露。为了解决这个问题,Facebook做了一套工具来自动化的处理和修复代码库中的一些问题,这个工具就是FBMemoryProfiler。

GitHub主页:数量:1657

发表评论

电子邮件地址不会被公开。 必填项已用*标注