威尼斯手机平台登陆-官方网站登录

威尼斯手机平台登陆为您带来世界三大博彩公司最新相关资讯,威尼斯官方网站登录充分考虑到不同地域网民的不同需求,威尼斯手机平台登陆良好的用户界面,人性化的操作,实用的功能设计使其广泛受到欢迎,推动实体出版、影视、动漫、游戏等相关文化产业的发展。

您的位置:威尼斯手机平台登陆 > 威尼斯在线注册平台 > 什么使用HHVM,首先会先将PHP代码编写翻译成二进制指令opcode

什么使用HHVM,首先会先将PHP代码编写翻译成二进制指令opcode

发布时间:2020-03-04 19:11编辑:威尼斯在线注册平台浏览(200)

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

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

    HHVM

    HHVM是什么?

    HHVM(HipHop VM)是Fackbook推出用于在执行PHP代码的虚拟机,是一个PHP的JIT编译器,具有产生快速代码和及时编译的优点。

    HHVM能干什么?

    HHVM脚本主要应用服务器端脚本和命令行脚本两大领域,专注于服务器端脚本,如收集表单数据、生成动态页面、发送接受COOKIE等。

    HHVM为什么比ZendEngine快?

    HHVM是Facebook开发的高性能PHP虚拟机,宣称比官方Zend快9倍。

    PHP使用的Zend虚拟机(VM),首先会先将PHP代码编译成二进制指令opcode,然后逐条执行,每条opcode指令都对应一个C函数。对于PHP的用户函数、运行时局部变量、常量会存在一个Hashtable中。

    执行一次C函数的开销

    • 参数的入栈出栈
    • CPU寄存器状态保存

    例如:在PHP中执行1000w次累加

    <?php
    $sum = 0;
    // 发生1000w次C函数调用
    for($i=0; $i<10000000; $i++){
      $sum += $i;
    }
    

    若编译为机器码情况是什么样的呢?

    主频2.0GHZ的CPU每秒执行20亿次指令,函数调用则1秒只能运行1000W次。

    因此,编译为机器码执行语言如C、C++、Golang...,或拥有JIT的语言如Java、NodeJS、LuaJIT、HHVM...,单从指令执行角度上看至少比PHP快几十倍。

    对于字符串处理、JSON编码解码、iconv编码解码、数组操作等, PHP比C++、Java慢吗?

    在PHP中此类操作都是C扩展函数完成的,性能与编译型语言一致。

    PHP到底比编译型语言慢的原因在哪里呢?

    PHP代码中用户函数、类、对象操作等。

    运算密集型 vs IO密集型

    运算密集型程序指的是需大量执行内存复制操作、循环、运行指令等,瓶颈在CPU上,提升性能的解决方案就是提升CPU硬件配置、改进算法、提升语言/工具的执行性能。对于此类程序,PHP性能问题很明显,执行相同的逻辑,比C/C++慢几十倍甚至百倍,这是不可接受的。

    IO密集型程序瓶颈在IO等待,例如HTTP请求执行100ms后返回,其中90ms查询数据库,8ms读写文件, 那么无论C/C++还是PHP,请求响应时间总是100ms左右,语言性能优化只有2ms的空间。

    如何优化PHP呢

    • PHP语言层面优化
    • 优化PHP官方实现ZendEngine
    • 将PHP编译为其他语言字节码(bytecode),借助于其他语言虚拟机来运行。
    • 将PHP转成C/C++,编译成本地代码。
    • 开发更快的PHP虚拟机

    Zend的执行过程可分为两个环节

    • 将PHP编译为opcode
    • 威尼斯在线注册平台,执行opcode

    优化opcode可编码重复解析PHP与静态编译优化,由于PHP的动态性,这种优化方式是有局限,乐观估计可提升20%的性能。

    优化opcode架构本身,工作量大投入产生比不高。

    优化opcode执行,Zend解释器interpreter在读到opcode后会根据不同opcode调用不同函数(switch),在函数中执行语言相关的操作。优化空间不大。

    优化Zend执行性能,对于函数调用的开销,通过inline threading来优化,其原理如C中的inline关键字。

    更快的虚拟机

    HHVM 为什么更快,原因是JIT。

    JIT操作本身是耗时的,对于简单程序或许比interpreter慢。HHVM的发展就是不断优化、优化、在优化。

    威尼斯在线注册平台 1

    HHVM是如何超过HPHPc

    什么是JIT,如何实现一个JIT?

    动态语言中基本都会有一个eval(),作用是传入一段字符串来执行。JIT做着类似的事,不过它要拼接的不是字符串,而是不同平台下的机器码,然后执行。在JIT中更重要的优化是根据类型来生成特定的指令,从而减少指令数量和条件判断。

    类型推导

    JIT的关键是猜测类型,变量的类型要是老是变就很难优化。HHVM工程师考虑在PHP语法上做手脚,加上类型的支持,推出Hack。

    <?hh
    class Point
    {
      // 使用静态类型可让HHVM更好的优化性能,不过这也意味着和PHP语法不兼容。
      public float $x,$y;
      public function __construct(float $x, float $y)
      {
        $this->x = $x;
        $this->y = $y;
      }
    }
    

    HHVM提升PHP执行性能

    HHVM生成和执行PHP的在中间字节码,执行时通过JIT(Just In Time即时编译,软件优化技术,指在运行时才会去编译字节码为机器码)转换为机器码执行。JIT将大量重复执行的字节码在运行时编译为机器码,达到提高执行效率的目的。通常触发JIT的条件是代码或函数被多次重复调用。

    什么是字节码?

    威尼斯在线注册平台 2

    字节码

    ZendEngine做法是先编译为opcode,逐条执行,每条指令对应的是C语言级别的函数。

    HHVM服务器最开始的少数请求会比其余的慢,因为它必须在执行PHP和Hack代码之前将它们编译成机器码,这个效果是非常明显的,所以你不应当立即把一个新设置的HHVM服务器应用到生产环境中。你应该先发送一些人工模拟的请求到这个HHVM服务器上,对它进行热身。
    事实上,服务器启动的时候,并不会编译任何代码。初始的请求就是在HHVM的字节码解释器下运行的。原理就是:对于一个web服务器来说,最初的几个请求是不寻常的。在这个期间,开始了初始化,还对缓存进行填充等等。对这些代码路径的编译对整体性能的表现是非常糟糕的,因为一旦对服务器进行了预热,这些过程是不会被经常调用的。HHVM还利用这些请求,来收集一些代码所用到的数据类型分析的工作。所以它可以稍后更加有效地进行编译。你可以使用选项 hhvm.jit_profile_interp_requests 来调整这个门槛。
    对于发送预热请求,颗通过命令行或其它类似的地方,简单地使用 curl 这个命令功能。为了得到最好的结果:
    使用你希望在产品中看到的,能够代表最常见的请求的混合集合。例如,如果你期待所有对这个产品的请求中的40%都是到达 index.php 的,那么你的 40% 的预热请求都 应该是到 index.php 的请求。
    避免并行发送多个预热请求,若你真的并行发送了多个请求,那么并不会出现什么问题。单对于JIT编译器来说,若没有同时工作在多个请求上的话,它往往能够生成更好的代码。
    最终,你最好有个进程脚本用于服务器热身,这样的话,颗在命令行里仅仅执行一个命令就可以做到热身了。但是在最初期的时候,你还需要一些人工的参与,要实际计算出用于热身的请求数量是非常微妙的, 这主要取决于你的程序本身。

    PHP服务缓存加速优化实战

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

    Box中的PHP

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

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

    (1) 操作码介绍及缓存原理:

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

    当客户端请求一个PHP程序的时候,服务器的 PHP 引擎会解析该 PHP 程序,并将其编译为特定的操作码(Operate Code)文件。

    获得同等的功能

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

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

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

    该文件是执行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 的内存消耗始终保持稳定。

    默认情况下,这个编译好的操作码文件由 PHP 引擎执行后进行丢弃。

    修正部署

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

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

    威尼斯在线注册平台 3

    常见的HHVM服务器

    威尼斯在线注册平台 4

    部署代码后的HHVM服务器

    操作码文件缓存机制就是将编译还的文件保存下来,并放到共享内存中,以便于下一次调用该PHP页面的时候重用它,避免了相同的代码重复度,节省了 PHP 引擎重复编译的时间。

    现存的混合状态

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

    降低了服务器负载,同时减少了服务器的 CPU 和内存的开销。

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

    威尼斯在线注册平台 5

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

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

    威尼斯在线注册平台 6

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

    LAMP 环境 PHP 缓存加速器的原理:

    在 LNMP 中,Apache 服务是使用 libphp5.so 响应处理 PHP 程序请求的。

    1. Apache 服务接受客户的 PHP 程序请求,并根据规则进行过滤。

    2. Apache 将 PHP 程序请求传递给 PHP 处理模块 libphp5.so。

    3. PHP引擎定位磁盘上的 PHP 文件,并将其加载到内存中解析。

    4. PHP 处理模块 libphp5.so 将 PHP 源码编译成 opcode。

    5. Apache 接收客户端新的 PHP 请求,PHP 编译解析并将结果返回。

    LNMP 环境 PHP 缓存加速器的原理:

    在 LNMP 中不再使用 libphp5.so 模块了,而是启动独立的 FCGI 进程,就是 php-fpm,由它来监听来自 Nginx 的 PHP 程序请求,交给 PHP 引擎进行处理。

    1. Nginx 接收客户端的 PHP 程序访问请求。

    2. Nginx 根据扩展名等过滤规则进行将 PHP 程序传递给解析 PHP 程序的 FCGI 进程。

    3. PHP FPM 进程调用 PHP 解析器读取磁盘上的 PHP 文件,并加载到内存中。

    4. PHP 解析器将 PHP 程序编译成为 opcode 文件,然后把 opcode 缓存起来。

    5. PHP FPM 引擎执行 opcode 树后,返回数据给 Nginx,进而返回客户端。

    6. Nginx 接收新的客户端请求,PHP FPM 引擎就会直接读取缓存起来的 opcode 并执行。

    7. 将结果返回。

    PHP 加速软件的选择:

    PHP 缓存加速器软件常见的有 XCache、eAccelerator、APC(Alternative PHP Cache)、ZendOpcache 等。

    首选 Xcache,其次是 eAccelerator。

    原因:

    1. 经过测试,XCache 效率更高,速度更快。

    2. XCache 软件开发社区更加活跃。

    3. 支持更高的 PHP 版本

    4. eAccelerator 安装及配置相对简单,加速效果明显。

    5. eAccelerator 文档资料比较多,但是官方对软件的更新速度比较慢,社区不活跃。

    6. eAccelerator 仅仅适合 PHP 5.4 以下的版本。

    7. ZendOpcache 是 PHP 官方研发的新一代缓存加速软件,以后可能会有更好的发展前景。

    8. 从 PHP5.5 开始 ZendOpcache 开始整合到 PHP 软件中,以前都是以插件的方式进行安装的。

    9. 在 PHP5.5 以后的版本中使用--enable-opcache。

    10. ZendOpcache 可能是未来缓存的首先选择。

    在使用缓存的时候需要准备 LNMP 环境。

    (1) 安装 XCache 缓存加速模块:

    cd ./xcache-3.2.0
    /app/php/bin/phpize
    ./configure --enable-xcache --with-php-config=/app/php/bin/php-config
    make
    make test
    make install
    ll /app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    total 680
    -rwxr-xr-x. 1 root root 695580 Sep 17 14:06 xcache.so
    

    (2) 安装 eAccellerator 缓存加速模块:

    tar -zxvf ./eaccelerator-eaccelerator-42067ac.tar.gz
    cd ./eaccelerator-eaccelerator-42067ac
    /app/php/bin/phpize
    ./configure --enable-eaccelerator=shared --with-php-config=/app/php/bin/php-config
    make && make install
    ll /app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    total 1108
    -rwxr-xr-x. 1 root root 438090 Sep 17 14:14 eaccelerator.so
    

    (3) 安装 ZendOpcache 缓存加速模块:

    tar -zxvf ./zendopcache-7.0.5.tgz 
    cd ./zendopcache-7.0.5
    /app/php/bin/phpize
    ./configure --enable-opcache --with-php-config=/app/php/bin/php-config
    make && make install
    ll /app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    total 1636
    -rwxr-xr-x. 1 root root 539488 Sep 17 14:18 opcache.so
    

    (4) 安装 PHP Memcached 扩展插件:

    Memcached是一个开源的支持高性能、高并发及分布式的内存缓存服务软件。

    分为客户端和服务器端:

    客户端:Memcache

    服务器端:Memcached

    在传统场景下,多数 Web 应用都将数据保存到 RDBMS 中,www 服务器从中读取数据并在浏览器中显示。

    但是随着数据量的变大,访问的集中,就会出现 RDBMS 的负担加重,数据库响应速度变慢,网站延迟等问题。

    Memcached 是高性能的分布式内存缓存服务。

    使用 Memcached 的主要目的就是通过自身内存中缓存数据库的查询结果,减少数据库访问次数,以提高动态 Web 应用速度,提高网站架构的并发能力和扩展性。

    Memcached 服务通过在事先规划好的系统空间中面临缓存数据库中各类数据,以达到减少前端业务对数据库的直接高并发访问,从而提升大规模网站集群中动态服务的并发访问能力。

    生产场景中,Memcached 服务一般被用来保存网站中经常被读取的对象或数据。

    Memcached的工作流程:

    1. 程序首先检查客户端请求的数据在 Memcached 服务的缓存中是否存在,如果存在,会直接将请求的数据返回,不再请求后端的数据库。

    2. 如果请求的数据在 Memcached 的缓存中不存在,程序会去 Memcached 后端的数据库服务。

    3. 把数据从数据库中返回到客户端中。

    4. 同时把新的数据保存在 Memcached 服务缓存中,下次直接请求 Memcached 中的数据。

    为 PHP 安装 Memcache 客户端:

    tar -zxvf ./memcache-2.2.5.tgz
    cd ./memcache-2.2.5
    /app/php/bin/phpize
    ./configure --enable-memcache --with-php-config=/app/php/bin/php-config
    ll /app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    -rwxr-xr-x. 1 root root 259088 Sep 17 16:00 memcache.so
    

    安装报错解决:

    make:***[memcache.lo]Error 1
    

    解决:

    cp memcache.loT memcache.lo
    

    (5) 安装 PDO_MYSQL 扩展模块:

    PDO 扩展为 PHP 访问数据库定义了一个轻量级的一致性接口,它提供一个数据访问抽象层。

    这样五龙轮使用什么数据库都可以使用统一的函数进行数据查询并获取数据。

    PDO_MYSQL 可以使用插件安装或编译PHP的时候加入参数,使用--with-pdo-mysql=mysqlnd 直接加入 PDO_MYSQL 的 PHP 支持。

    使用--with-mysql-mysqlnd 即可在没有 MySQL 的环境下使 PHP 支持 MySQL 数据库。

    tar -zxvf ./PDO_MYSQL-1.0.2.tgz
    cd ./PDO_MYSQL-1.0.2
    /app/php/bin/phpize 
    ./configure --with-php-config=/app/php/bin/php-config --with-pdo-mysql=/app/mysql
    make && make install
    

    安装报错解决:

    make: *** [pdo_mysql.lo] Error 1
    

    解决:

    cp pdo_mysql.loT pdo_mysql.lo
    
    
    
    make: *** [mysql_driver.lo] Error 1
    

    解决:

    cp mysql_driver.loT mysql_driver.lo
    

    make: *** [mysql_statement.lo] Error 1

    解决:

    cp mysql_statement.loT mysql_statement.lo
    
    
    
    ll /app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    -rwxr-xr-x. 1 root root   5429 Sep 17 16:35 pdo_mysql.so
    

    (6) 安装 imagick 模块:

    ImageMagick 是一套功能强大,稳定而且免费的工具集和开发包,可以用来读写和处理超过 8 9 种。

    利用根据 Web 应用程序的需要动态生成图片,还可以对一个或一组图片进行改变大小等操作。

    同时 ImageMagick 提供一个高质量的 2D 工具包。

    部分支持 SVG。

    它甚至包括各种曲线的渲染功能。

    tar -zxvf ./ImageMagick-i686-pc-mingw32.tar.gz
    cd ./ImageMagick-6.8.5/
    ./configure && make && make install
    

    (7) 安装 imagick PHP 扩展模块:

    要先安装 ImageMagick 模块才可以安装 imagick PHP模 块。

    imagick 插件是提供 PHP 调用 ImageMagick 功能的扩展模块。

    安装 ImageMagick 图像程序后,再安装 PHP 的扩展 imagick 插件,才可以用 ImageMagick 提供的API进行图片创建、压缩与修改。

    ln -s /usr/local/include/ImageMagick-7/ /usr/local/include/ImageMagick
    tar -zxvf ./imagick-2.3.0.tgz
    cd ./imagick-2.3.0
    /app/php/bin/phpize
    ./configure --with-php-config=/app/php/bin/php-config
    

    配置 PHP Memcache/PDO_MYSQL/imagick 模块:

    编辑 php.ini 文件:

    extension=/app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    

    检查配置文件:

    grep "extension_dir=" /app/php/lib/php.ini
    extension=/app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/
    extention = pdo_mysql.so
    extettion = memcache.so
    extention = imagick.so
    

    (8) 配置 eAccelerator 插件生效并优化参数:

    mkdir /tmp/eaccelerator
    chown nginx.nginx /tmp/eaccelerator/
    ll -d /tmp/eaccelerator/
    drwxr-xr-x. 2 nginx nginx 4.0K Sep 17 20:26 /tmp/eaccelerator/
    

    这个目录可以使用 tmpfs 或 SSD 来存储。

    配置PHP参数:php.ini

    [eaccelerator]
    extension = eaccelerator.so
    eaccelerator.shm_size="64"
    eaccelerator.cache_dir="/tmp/eaccelerator"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_tt1="3360"
    eaccelerator.shm_prune_period="3360"
    eaccelerator.hsm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"
    

    检查 PHP 配置文件:

    [root@comp0 ~]# tail -15 /app/php/lib/php.ini 
    [eaccelerator]     #加载模块文件配置
    extension = eaccelerator.so      #加载模块
    eaccelerator.shm_size="64"      #存储缓存数据的共享内存大小,如果是0,则最大值看内核/proc/sys/kernel/shmmax
    eaccelerator.cache_dir="/tmp/eaccelerator"    #磁盘缓存存储路径,缓存内容precompiled code、session data、contect、user entires。默认路径是/tmp/eaccelerator
    eaccelerator.enable="1"   #eAccelerator缓存生效开关,默认为1,表示开启。
    eaccelerator.optimizer="1"    #加速PHP代码执行速度,默认为1,表示激活。用于缓存前的代码加速。
    eaccelerator.check_mtime="1"  #检查缓存修改时间,决定代码是否需要重新编译,默认值为1,表示激活。
    eaccelerator.debug="0"    #缓存加速调试,打开后可以看到缓存中的信息。
    eaccelerator.filter=""    #设定对象是否缓存规则,空表示不设定。
    eaccelerator.shm_max="0"    #可以被放置的缓存最大值,不限制为0.
    eaccelerator.shm_tt1="3360"   #缓存文件的生存期
    eaccelerator.shm_prune_period="3360"  #当共享内存时间不够的时候,从共享内存中移除旧的数据的时间周期。
    eaccelerator.hsm_only="0"    #是否允许缓存数据到磁盘,允许为0,但是对于session data and contect caching无影响。
    eaccelerator.compress="1"  #是否开启压缩,开启为1。
    eaccelerator.compress_level="9"    #压缩级别,最高为9。
    #可选值
    eaccelerator.keys="shm_and_disk"    #控制keys的缓存位置
    eaccelerator.sessions="shm_and_disk"   #控制sessions的缓存位置
    eaccelerator.content="shm_and_disk"   #控制内容缓存位置
    

    查看 eAccelerator 的加速情况:

    /app/php/sbin/php-fpm -v
    PHP 5.4.24 (fpm-fcgi) (built: Sep 17 2017 12:21:41)
    Copyright (c) 1997-2013 The PHP Group
    Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
        with eAccelerator v1.0-dev, Copyright (c) 2004-2012 eAccelerator, by eAccelerator
    

    测试/tmp/eaccelerator/目录下存在缓存数据。

    配置XCache插件加速:

    编辑php.ini:

    ;[xcache]
    [xcache-common]
    extension = xcache.so
    [xcache.admin]
    xcache.admin.enable_auth = On
    xcache.admin.user = "mOo"
    xcache.admin.pass = "md5 encrypted password"
    [xcache]
    xcache.shm_scheme = "mmap"
    xcache.size = 256M
    xcache.count = 2
    xcache.slots = 8K
    xcache.ttl = 86400
    xcache.gc_interval = 3600
    xcache.var_size = 64M
    xcache.var_count = 1
    xcache.var_slots = 8K
    xcache.var_ttl = 0
    xcache.var_gc_interval = 300
    xcache.var_namespace_mode = 0
    xcache.var_namespace = ""
    xcache.readonly_protection = Off
    xcache.mmap_path = "/dev/zero"
    xcache.coredump_directory = ""
    xcache.coredump_type = 0
    xcache.disable_on_crash = Off
    xcache.experimental = Off
    xcache.cacher = On
    xcache.stat = On
    xcache.optimizer = Off
    [xcache.converager]
    xcache.coverager = Off
    xcache.coverager_autostart = On
    xcache.coveragedump_directory = ""
    

    检查 PHP 的 XCache 加速缓存情况:

    /app/php/bin/php -v
    PHP 5.4.24 (cli) (built: Sep 17 2017 12:21:30) 
    Copyright (c) 1997-2013 The PHP Group
    Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
        with XCache v3.2.0, Copyright (c) 2005-2014, by mOo
        with XCache Cacher v3.2.0, Copyright (c) 2005-2014, by mOo
    

    配置文件详解:

    ;[xcache]   XCache配置文件解析开始
    [xcache-common]
    extension = xcache.so    包含加速模块,路径相对于extension_dir的配置,自3.0开始不再支持使用zend_extension加载xcache的方式。
    [xcache.admin]     管理员配置开始
    xcache.admin.enable_auth = On     激活管理员认证
    xcache.admin.user = "mOo"    指定xcache的管理员用户名
    xcache.admin.pass = "md5 encrypted password"  指定xcache的管理员密码
    [xcache]   XCache配置开始
    xcache.shm_scheme = "mmap"   设置XCache如何从系统分配共享内存
    xcache.size = 256M    禁止缓存为0,启用缓存为非零数字,需要注意系统所允许的mmap最大值
    xcache.count = 2    指定将XCache切分多少块,官方推荐设置为服务器CPU的数量
    xcache.slots = 8K  hash槽个数的参考值,缓冲超过此数值时,也没有任何问题。
    xcache.ttl = 86400    设定cache对象的生存周期TTL,永不过期是0
    xcache.gc_interval = 3600   回收器扫描过期回收内存空间的间隔,不扫描为0,其他数值的单位是秒,默认是0
    xcache.var_size = 64M  用于变量缓存,而不是opcache缓存
    xcache.var_count = 1  用于变量缓存,而不是opcache缓存
    xcache.var_slots = 8K  用于变量缓存,而不是opcache缓存
    xcache.var_ttl = 0   用于变量缓存,而不是opcache缓存
    xcache.var_gc_interval = 300  用于变量缓存,而不是opcache缓存
    xcache.var_namespace_mode = 0  如果启用了还参数,将会稍微降低性能,但是会提高一定的系统安全性。对xcache.mmap_path = "/dev/zero"无效
    xcache.var_namespace = ""
    xcache.readonly_protection = Off
    xcache.mmap_path = "/dev/zero"  对于*nix,xcache.mmap_path 是一个文件路径而非目录。如果要启用该参数,请使用/tmp/xcache这样的参数。
    如果开启了xcache.readonly_protection参数,不同进程组的PHP将不会共享一个/tmp/xcache路径。
    xcache.coredump_directory = ""  当XCache崩溃后,是否把数据保存到指定路径
    xcache.coredump_type = 0   
    xcache.disable_on_crash = Off   当XCache发生崩溃后,自动关闭XCache的路径
    xcache.experimental = Off
    xcache.cacher = On
    xcache.stat = On
    xcache.optimizer = Off
    [xcache.converager]
    xcache.coverager = Off
    xcache.coverager_autostart = On
    xcache.coveragedump_directory = ""
    

    查看CPU参数:

    more /proc/cpuinfo 
    processor: 0
    vendor_id: GenuineIntel
    cpu family: 6
    model: 69
    model name: Intel(R) Core(TM) i3-4030U CPU @ 1.90GHz
    stepping: 1
    microcode: 29
    cpu MHz: 1900.000
    cache size: 3072 KB
    physical id: 0
    siblings: 1
    core id: 0
    cpu cores: 1
    apicid: 0
    initial apicid: 0
    fpu: yes
    fpu_exception: yes
    cpuid level: 13
    wp: yes
    flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc up
     arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadli
    ne_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm arat epb xsaveopt pln pts dtherm tpr_shadow vnmi ept vpid fsgsbase bmi1 avx2 smep bmi2 invpcid
    bogomips: 3800.00
    clflush size: 64
    cache_alignment: 64
    address sizes: 42 bits physical, 48 bits virtual
    power management:
    

    配置web管理界面:

    mkdir /app/nginx/html/blog/xcache
    cp -a /tools/xcache-3.2.0/htdocs/ /app/nginx/html/xcache/
    chown -R nginx.nginx /app/nginx/html/xcache/
    

    创建XCache web配置文件

    vim /app/nginx/conf/extras/xcache.conf
    server {
            listen       8088;
            server_name  inner.myxcache.com;
    
            #location / { 
            #    root   html;
            #    index  index.html index.htm;
            #}  
    
            location / { 
                root html/xcache;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include ../conf/fastcgi.conf;
            }   
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }   
    }
    

    通过md5sum生成管理员密码:

    echo "123456" | md5sum 
    e10adc3949ba59abbe56e057f20f883e  -
    

    修改php.ini文件:

    xcache.admin.user = "xcacheadmin"
    xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e"
    

    重启 php-fpm。

    重启 Nginx。

    访问   可以进入管理页面。

    配置Z endOpcache 插件加速:

    vim /app/php/lib/php.ini
    [opcache]
    zend_extension=/app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/opcache.so
    opcache.memory_consumption=32
    opcache.interned_strings_buffer=8
    opcache.max_accelerated_files=1000
    opcache.revalidate_freq=60
    opcache.fast_shutdown=1
    opcache.enable_cli=1
    

    重启php-fpm进程:

    访问:

    view_phpinfo.php文件代码:

    <?php
    phpinfo();
    ?>
    

    参数讲解:

    [opcache]   ZendOpcache配置开始

    zend_extension=/app/php-5.4.24/lib/php/extensions/no-debug-non-zts-20100525/opcache.so  加载模块文件

    opcache.memory_consumption=32  ZendOpcache共享内存的大小,用于存放precompiled PHP code,默认是64,单位是Mbytes

    opcache.interned_strings_buffer=8  默认是4,interned_strings内存的数量,单位值MB

    opcache.max_accelerated_files=1000  默认是2000,ZendOpcache散列表的key的最大数量

    opcache.revalidate_freq=60  默认是2,检查文件时间戳的频率,用于共享内存分配的变化

    opcache.fast_shutdown=1   默认是0,如果激活,一个快速的关闭队列将被用来加速代码

    opcache.enable_cli=1   默认是0,激活PHP CLI的ZendOpcache,用于测试和调试

    在PHP5.5以上的版本中只需要编译PHP的时候指定--enable-opcache即可使用ZendOpcache。

    生产环境PHP插件安装建议:

    eAccelerator-0.9.5.2.tar.gz适合PHP5.3及以前的版本,缓存加速使用 可选的PHP扩展插件。

    eAccelerator-0.9.6.tar.bz2适合PHP5.3版本,PHP缓存加速,可选的PHP扩展插件。

    ImageMagick.tar.gz常用图像处理程序,属于功能应用,非PHP扩展插件。

    imagick-2.3.0.tgz需要先安装图像处理程序,属于应用功能,可选的PHP扩展插件。

    memcache-2.2.7.tgz是memcache客户端数据库缓存优化应用,可选的PHP扩展插件。

    PDO_MYSQL-1.0.2.tar.gz是PHP数据库库访问插件,属于PHP功能插件,可选的PHP扩展插件。

    xcache-3.2.0.tar.bz2支持PHP5.1~PHP5.6缓存加速,可选PHP扩展插件。

    zendopcache-7.0.5.tar.gz支持PHP5.3~PHP5.4缓存加速,可选的PHP扩展插件。

    生产环境插件安装建议:

    对于功能性插件:

    如果业务不需要使用,可以不考虑安装。

    如果不清楚是否需要安装,最好安装上。

    对于性能优化插件:

    eAccelerator、XCache、ZendOpcache、APC可以安装其中任何一种。

    具体情况看业务需求。最好进行压力测试。

    PHP加速插件性能测试对比:

    eAccelerator在请求时间和内存占用综合方面是最好的。

    存在加速器比不存在加速器在请求时间方面快3倍。

    什么是phpize?

    安装PHP扩展的时候需要phpize,phpize是用来扩展PHP扩展模块的。

    通过phpize可以建立PHP的外挂模块。

    编译PHP后,在bin目录下会有phpize这个脚本文件,再要添加模块的目录下执行这个脚本后出现一个configuer文件。

    ./configuer后面可以很--with-php-config的文件路径。

    在PHP指定编译时指定了--with-mysql=mysqlnd和--with-pdo-mysql=mysqlnd的参数,在生产环境中可能会有socket连接问题。

    解决方法时在php.ini中加入:

    pdo_mysql.default_socket=/app/php/tmp/mysql.sock

    本文由威尼斯手机平台登陆发布于威尼斯在线注册平台,转载请注明出处:什么使用HHVM,首先会先将PHP代码编写翻译成二进制指令opcode

    关键词: