Box 迁移到 HHVM 实践

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

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

PHP入门及服务环境配置(Nginx+PHP)

Apache和Tomcat都是web网络服务器,两者既有联系又有区别,在进行HTML、PHP、JSP、Perl等开发过程中,需要准确掌握其各自特点,选择最佳的服务器配置。

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

PHP入门

图片 1

PHP维基百科:

PHP(全称:PHP:Hypertext
Preprocessor,即“PHP:超文本预处理器”)是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入HTML中使用。PHP的语法借鉴吸收C语言、Java和Perl等流行计算机语言的特点,易于一般程序员学习。PHP的主要目标是允许网络开发人员快速编写动态页面,但PHP也被用于其他很多领域。

最新版本:2015年12月3日 7.0.0发布

  • Apache是web服务器(静态解析,如HTML),tomcat是java应用服务器(动态解析,如JSP、PHP)
  • Tomcat只是一个servlet(jsp也翻译成servlet)容器,可以认为是apache的扩展,但是可以独立于apache运行

Box中的PHP

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

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

应用

PHP是一个应用范围很广的语言,特别是在网络程序开发方面。

  1. 产生网页提供浏览器读取
  2. 开发命令行脚本程序
  3. 用户端的GUI应用程序(PHP-GTK)

使用PHP不需要任何费用,官方组织PHP
Group提供了完整的程序源代码,允许用户修改、编译、扩充来使用。

两者从以下几点可以比较的:

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 的部署进行修补;确保在这一混合环境下一切可以非常良好的运行。

语法

参考了Perl、C语言,而且可以集成在HTML之中。

简单的Hello World代码:

<?php
  echo 'Hello World!';
?>

PHP剖析引擎只剖析<?php?>之间的代码,而不包含在<?php?>之间的内容则会直接提交。

在判断语句中的HTML代码并不会被直接提交:

 <?php
 if (false) {
 ?>
 HTML Code
 <?php
 }
 ?>

注释

C与C++所使用的

  • /*...*/
  • //
    和Perl的
  • #

数据类型

  • 四种标量类型
  • 整数型(integer)
  • 浮点数型(float)
  • 布尔型(boolean)
  • 字符串(string)
  • 两种复合类型
  • 数组(array)
  • 对象(object)
  • 两种特殊类型
  • NULL
  • 资源 (resource)

变量

  • 以“$”后接变量名称来表示。
  • 变量名称区分大小写。

PHP框架

  1. Laravel:
    图片 2

  2. Symfony2:
    图片 3

  3. Thinkphp:
    图片 4

  • 内置的函数
  • 很多扩展库(extension)

源代码

  • 源代码是可以直接读取的,即使放到服务器上运行也是一样。
  • 通过PHP编码器,可以保护PHP的源代码不被读取(对商业软件来说特别有需求),也可以提升运行的性能。
  • 通过动态的缓存机制来提升速度。加速工具有商业版的,也有开放源代码的。

PHP编译器

PHP一直被当作解释器使用。

PHP编译器则将PHP从解释器中分离,为加快运行和改善与以其他编程语言编写部分的互通性。

  • PHP 语法教程
  • PHP: PHP 手册 – Manual

PHP 版本

论坛评论摘要:

  • 5.2到5.3上有挺大的差异吧.
    在面向对象方面和资源回收方面都挺多的改进的.
    再往上没听说有什么非常特别的变化,
    要是新版本没有放映出啥bug就升级下呗
  • 5.2:实际开发中没有命名空间,不兼容所有现代 PHP
    框架。更重要的是这是一个停止维护很久的版本, 2011 年 1
    月后就没有安全补丁了,也就是 2011 ~ 2015
    四年间的所有公开漏洞全都在。
  • 为什么 centos 源里的 php 一直是 5.3.3 版本?centos
    就是以软件老而闻名的。
    据说号称是为了稳定性。

结论:使用 >=5.3 ,同时不宜太新。

  1. 两者都是apache组织开发的

获得同等的功能

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

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

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

Unix系统下服务环境配置(Nginx+PHP)

网站和 web 应用程序在通常情况下,需要三样东西:

  • PHP 自身
  • 一个 web 服务器(Nginx、Apache、IIS)
  • 一个 web 浏览器

如果需要自己配置服务器和 PHP,有两个方法将 PHP 连接到服务器上。

  • 很多服务器,PHP 均有一个直接的模块接口(也叫做
    SAPI)来源
  • 如果 PHP 不能作为模块支持 web 服务器,总是可以将其作为 CGI 或
    FastCGI 处理器来使用。

下面将采用 FastCGI + Nginx 的方式。

在 Unix 平台下安装 PHP 有几种方法:

  • 使用配置和编译
  • 使用各种预编译的包
  • 两者都有HTTP服务的功能
  • 两者都是开源免费的

设计方面的差异

在进行移植期间,我们发现两个运行时环境几个行为方面不一致的地方,这些不一致使得基本的设计有所不同。这可能是需要解决的最棘手的差异化问题。例如,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
的内存消耗始终保持稳定。

CGI 或 FastCGI

FastCGI:

快速通用网关接口(Fast Common Gateway
Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。

FastCGI致力于减少网页服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的网页请求。

与为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI服务器管理,而不是web服务器。
当进来一个请求时,web服务器把环境变量和这个页面请求通过一个socket比如FastCGI进程与web服务器(都位于本地)或者一个TCP connection(FastCGI进程在远端的server
farm)传递给FastCGI进程。

CGI:

通用网关接口(Common Gateway
Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了客户端和服务器程序之间传输数据的一种标准。

联系

  1. Apache是普通服务器,本身只支持html即普通网页,可以通过插件支持php,还可以与Tomcat连通(Apache单向连接Tomcat,就是说通过Apache可以访问Tomcat资源,反之不然)。
  • Apache只支持静态网页,但像asp、jsp、php、cgi等动态网页就需要Tomcat来处理。
  • Apache和Tomcat整合使用:
    • 如果客户端请求的是静态页面,则只需要Apache服务器响应请求;
    • 如果客户端请求动态页面,则是Tomcat服务器响应请求,将解析的JSP等网页代码解析后回传给Apache服务器,再经Apache返回给浏览器端。
    • 这是因为jsp是服务器端解释代码的,Tomcat只做动态代码解析,Apache回传解析好的静态代码,Apache+Tomcat这样整合就可以减少Tomcat的服务开销。
  • Apache和Tomcat是独立的,在同一台服务器上可以集成。

修正部署

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

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

图片 5

常见的HHVM服务器

图片 6

部署代码后的HHVM服务器

Nginx

图片 7

Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP,
POP3,
IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。

发明人是俄国人。此软件BSD-like协议下发行,可以在UNIX、GNU/Linux、BSD、Mac
OS X、Solaris,以及Microsoft Windows等操作系统中运行。

整体采用模块化设计是nginx的一个重大特点,甚至http服务器核心功能也是一个模块。要注意的是:nginx的模块是静态的,添加和删除模块都要对nginx进行重新编译,这一点与Apache的动态模块完全不同。

了解Tengine:Tengine –
维基百科,自由的百科全书(一个由淘宝从nginx复刻出来的HTTP服务器)

区别

Apache是有C语言实现的,支持各种特性和模块从而来扩展核心功能;Tomcat是Java编写的,更好的支持Servlet和JSP。

  1. Apache是Web服务器,Web服务器传送(serves)页面使浏览器可以浏览,Web服务器专门处理HTTP请求(request),但是应用程序服务器是通过很多协议来为应用程序提供
    (serves)商业逻辑(business
    logic)。Tomcat是运行在Apache上的应用服务器,应用程序服务器提供的是客户端应用程序可以调用(call)的方法
    (methods)。它只是一个servlet(jsp也翻译成servlet)容器,可以认为是Apache的扩展,但是可以独立于apache运行。
  • Apache是普通服务器,本身只支持html静态普通网页。不过可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源,反之不然),Tomcat是jsp/servlet容器,同时也支持HTML、JSP、ASP、PHP、CGI等,其中CGI需要一些手动调试,不过很容易的。
  • Apache侧重于http
    server,Tomcat侧重于servlet引擎,如果以standalone方式运行,功能上Tomcat与apache等效支持JSP,但对静态网页不太理想。
  • Apache可以运行一年不重启,稳定性非常好,而Tomcat则不见得。
  • 首选web服务器是Apache,但Apache解析不了的jsp、servlet才用tomcat。
  • Apache是很最开始的页面解析服务,tomcat是后研发出来的,从本质上来说tomcat的功能完全可以替代Apache,但Apache毕竟是tomcat的前辈级人物,并且市场上也有不少人还在用Apache,所以Apache还会继续存在,不会被取代,apache不能解析java的东西,但解析html速度快。

现存的混合状态

毫不奇怪,迁移到 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
是否导致了任何新的倒退。

与PHP的集成

自PHP-5.3.3起,PHP-FPM加入到了PHP核心,编译时加上--enable-fpm即可提供支持。
PHP-FPM以守护进程在后台运行,Nginx响应请求后,自行处理静态请求,PHP请求则经过fastcgi_pass交由PHP-FPM处理,处理完毕后返回。
Nginx和PHP-FPM的组合,是一种稳定、高效的PHP运行方式

两者例子

Apache是一辆车,上面可以装一些东西如html等,但是不能装水,要装水必须要有容器(桶),而这个桶也可以不放在卡车上,那这个桶就是Tomcat。

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

图片 8

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

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

图片 9

大部分基础设施迁移到 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
尽可能地快速可靠地工作。

直接安装(从安装源)

命令及提示摘要:

sudo apt-get install nginx
下列【新】软件包将被安装:
  nginx nginx-common nginx-full

21:31 root@debian:/home/weaming $ whereis nginx
nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx /usr/share/man/man1/nginx.1.gz

21:31 root@debian:/home/weaming $ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

23:24 root@debian:/ $ nginx -V
nginx version: nginx/1.6.2
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --add-module=/tmp/buildd/nginx-1.6.2/debian/modules/nginx-auth-pam --add-module=/tmp/buildd/nginx-1.6.2/debian/modules/nginx-dav-ext-module --add-module=/tmp/buildd/nginx-1.6.2/debian/modules/nginx-echo --add-module=/tmp/buildd/nginx-1.6.2/debian/modules/nginx-upstream-fair --add-module=/tmp/buildd/nginx-1.6.2/debian/modules/ngx_http_substitutions_filter_module

小结:

  • 默认安装了 nginx nginx-common nginx-full 三个包
  • whereis nginx 查看nginx可执行程序位置
  • 默认配置文件位置:/etc/nginx/nginx.conf。nginx默认配置
  • nginx -t检查配置是否有错误
  • nginx -V查看安装了哪些模块
  • /etc/nginx/文件夹下还有(tree /etc/nginx/ -L 2):

/etc/nginx/
├── conf.d
├── fastcgi.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── nginx.conf
├── proxy_params
├── scgi_params
├── sites-available
│   └── default
├── sites-enabled
│   └── default -> /etc/nginx/sites-available/default
├── snippets
│   ├── fastcgi-php.conf
│   └── snakeoil.conf
├── uwsgi_params
└── win-utf

4 directories, 14 files

两者整合

Apache是一个web服务器环境程序,启用他可以作为web服务器使用。不过只支持静态网页,不支持动态网页,如asp、jsp、php、cgi。如果要在Apache环境下运行jsp,就需要一个解释器来执行jsp网页,而这个jsp解释器就是Tomcat。那为什么还要JDK呢?因为jsp需要连接数据库的话,就要jdk来提供连接数据库的驱动程序,所以要运行jsp的web服务器平台,就需要Apache+Tomcat+JDK。

从源代码编译安装

整合的好处

  1. 如果客户端请求的是静态页面,则只需要Apache服务器响应请求
  • 如果客户端请求动态页面,则是Tomcat服务器响应请求
  • 因为jsp是服务器端解释代码的,这样整合就可以减少Tomcat的服务开销

PHP、php-fpm

直接(从安装源)安装

  • php为什么有那么多依赖程序? –
    SegmentFault
  • PHP: Debian GNU/Linux
    安装说明

php自身分为三个东西,php-cgiphp-cliphp-fpm,cli则是在shell执行php的工具。

经典的功能模块有php-mysql,php-curl等等。mysql,mysqli,pdo,curl,gd,pear,xmlrpc,imagemagick字样的都是经典的包,前缀根据环境不同,可能是php-,可能是php5-

pdo用于取代mysql和mysqli连接数据库,curl用于post,gd用于生成验证码,pear和pecl用于安装扩展,xmlrpc用于通信,imagemagic用于图片处理。具体的功能,apt-cache search php
或者yum search php就能出现一句话的功能简介。

$ sudo apt-get install php5 php5-fpm php-apc php5-curl php5-cli php-pear php5-gd -y

Creating config file /etc/php5/mods-available/pdo.ini with new version
php5_invoke: Enable module pdo for cli SAPI
php5_invoke: Enable module pdo for fpm SAPI

Creating config file /etc/php5/mods-available/opcache.ini with new version
php5_invoke: Enable module opcache for cli SAPI
php5_invoke: Enable module opcache for fpm SAPI
正在设置 php5-json (1.3.6-1) ...
php5_invoke: Enable module json for cli SAPI
php5_invoke: Enable module json for fpm SAPI
正在设置 php5-cli (5.6.17+dfsg-0+deb8u1) ...
update-alternatives: 使用 /usr/bin/php5 来在自动模式中提供 /usr/bin/php (php)
update-alternatives: 使用 /usr/bin/phar5 来在自动模式中提供 /usr/bin/phar (phar)

Creating config file /etc/php5/cli/php.ini with new version
正在设置 php-pear (5.6.17+dfsg-0+deb8u1) ...
正在设置 libapparmor1:amd64 (2.9.0-3) ...
正在设置 php5-fpm (5.6.17+dfsg-0+deb8u1) ...

Creating config file /etc/php5/fpm/php.ini with new version
正在设置 php5 (5.6.17+dfsg-0+deb8u1) ...
正在设置 php5-apcu (4.0.7-1) ...
php5_invoke: Enable module apcu for cli SAPI
php5_invoke: Enable module apcu for fpm SAPI
正在设置 php5-curl (5.6.17+dfsg-0+deb8u1) ...

Creating config file /etc/php5/mods-available/curl.ini with new version
php5_invoke: Enable module curl for cli SAPI
php5_invoke: Enable module curl for fpm SAPI
正在设置 php5-gd (5.6.17+dfsg-0+deb8u1) ...

Creating config file /etc/php5/mods-available/gd.ini with new version
php5_invoke: Enable module gd for cli SAPI
php5_invoke: Enable module gd for fpm SAPI
正在设置 php5-readline (5.6.17+dfsg-0+deb8u1) ...

Creating config file /etc/php5/mods-available/readline.ini with new version
php5_invoke: Enable module readline for cli SAPI
php5_invoke: Enable module readline for fpm SAPI
正在设置 php-apc (4.0.7-1) ...
正在处理用于 libc-bin (2.19-18+deb8u1) 的触发器 ...
正在处理用于 systemd (215-17+deb8u2) 的触发器 ...
正在处理用于 php5-fpm (5.6.17+dfsg-0+deb8u1) 的触发器 ...

数据库

#sudo apt-get php-mysql php5-pgsql php5-sqlite -y

APT 会自动把适当的行添加到不同的 php.ini 相关文件中去,例如:

/etc/php5
├── cli
│   ├── conf.d
│   └── php.ini
├── fpm
│   ├── conf.d
│   ├── php-fpm.conf
│   ├── php.ini
│   └── pool.d
└── mods-available
    ├── apcu.ini
    ├── curl.ini
    ├── gd.ini
    ├── json.ini
    ├── opcache.ini
    ├── pdo.ini
    └── readline.ini
  • 默认php.ini
  • 默认php-fpm.conf
  • PHP: Unix
    系统下的安装PHP

重启php-fpm:

  • php 5.4中php-fpm
    的重启、终止操作命令

php5-fpm reload
php5-fpm restart

均报错。像下面这样做即可:

23:06 root@debian:/etc/php5 $ cat fpm/php-fpm.conf | grep pid
pid = /run/php5-fpm.pid
23:07 root@debian:/etc/php5 $ kill -USR2 `cat /run/php5-fpm.pid`

php-cgi

php-cgi是 PHP 的解释器 ,它只是个 CGI
程序,只能解析请求,返回结果,不会进程管理。所以就出现了一些能够调度
php-cgi 进程的程序。

PHP-FPM

FPM(FastCGI 进程管理器)用于替换 PHP FastCGI
的大部分附加功能,对于高负载网站是非常有用的。

修改了php.ini配置文件后,没办法平滑重启。php-fpm对此的处理机制是新的worker用新的配置,已经存在的worker处理完手上的活就可以歇着了,通过这种机制来平滑过度。

“PHP解析器(php-cgi)会解析php.ini文件,初始化执行环境”,就是这里了。标准的CGI对每个请求都会执行这些步骤(不闲累啊!启动进程很累的说!),所以处理每个时间的时间会比较长。这明显不合理嘛!那么Fastcgi是怎么做的呢?首先,Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是fastcgi的对进程的管理。
来源:搞不清FastCgi与PHP-fpm之间是个什么样的关系 –
SegmentFault

搞笑版:

你(PHP)去和爱斯基摩人(web服务器,如 Apache、Nginx)谈生意

你说中文(PHP代码),他说爱斯基摩语(C代码),互相听不懂,怎么办?那就都把各自说的话转换成英语(FastCGI
协议)吧。

怎么转换呢?你就要使用一个翻译机(PHP-FPM)(当然对方也有一个翻译机,那个是他自带的)

我们这个翻译机是最新型的,老式的那个(PHP-CGI)被淘汰了。不过它(PHP-FPM)只有年轻人(Linux系统)会用,老头子们(Windows系统)不会摆弄它,只好继续用老式的那个。

参考文档:

  • Setting up PHP-FastCGI and nginx? Don’t trust the tutorials: check
    your configuration!

发表评论

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