What You See Is What You Get Element

使用 Zend Server 和 Oracle Database 构建企业级 PHP 体系

作者:Vikram Vaswani

建立 Oracle/PHP/Apache/Linux (OPAL) 开发和部署环境的快速方法

2014 年 3 月更新

下载:

Zend Server

内容

Zend Server 简介

熟悉 Zend Server 仪表盘

使用应用

结合使用 Oracle Database 与 Zend Server

使用 Oracle Database 中的连接池

使用页面和 Opcode 缓存提高性能

记录和分析瓶颈和错误

总结

简介

如果您正在构建将在企业级推广的应用,您很可能已经在使用 Oracle 作为后端数据库。对于应用的 Web 前端,PHP 无疑是最佳之选:毕竟它简单易学,是流行的 Web 应用构建工具,拥有活跃的社区和完备的文档,并且支持 Oracle 在内的多种数据库。

现在,您打算从何处入手?如果您不喜欢走捷径,可以下载 Apache 和 PHP,将 PHP 编译为 Apache 模块,编译适用于 PHP 的 Oracle OCI8 数据库扩展,然后进行配置,并将其组合起来创建一个自定义的 Oracle/PHP/Apache/Linux (OPAL) 体系。但组建自己的体系也意味着当您需要支持时,没法打电话找人帮忙。如果您没有时间去实验,或者更喜欢专心构建应用,而不是处理基础架构问题,Zend Server 可以提供帮助。

Zend Server 是一个随时可运行的 PHP 体系,在 Windows、Linux、Mac OS X 和 IBM i 上运行。它提供对 Oracle 数据库的内置支持,从而可以快速、轻松地开发 Oracle 支持的 Web 应用。此外,它还有一组附加工具可实现持续集成、版本自动化、应用监视和性能管理,为企业 OPAL 应用开发和部署提供高性能的基础。继续阅读,我将通过几个示例为您介绍如何使用 Zend Server。

Zend Server 简介

Zend Server 可帮助您轻松地开始使用 PHP 快速、敏捷地开发和部署应用。

  • 对于开发人员来说,它包括经过全面测试的、受支持的、更新的 PHP 5.5 和 Apache 2.4 版本,支持 Oracle(通过 OCI8 扩展)和 MySQL 等多种数据库产品,以及用于错误检测、打包、部署和版本控制的 Zend 特定插件。在 Linux 上,Zend Server 还允许您使用 nginx 代替 Apache。

  • 对于管理员来说,它提供了可安装的、企业级的、受支持的中间件体系,具有集中的应用监视和性能跟踪功能。管理员可以通过访问控制和供应实施一致的安全策略,还可以通过扩展和会话集群添加新服务器来支持更高的负载。

如果您在 PHP 方面有一定更多经验并且愿意手动维护服务器和管理更新,可以选择 Zend Server 的免费版本。这种版本不包括商业版本中包含的页面缓存、代码跟踪、脱机作业队列、会话集群和云扩展特性以及长期 PHP 支持。

如果这些特性对您很重要 — 如果您要部署业务关键型 PHP 应用,这些特性应该对您很重要 — 应考虑购买一种 Zend Server 商业版本,这样您就有权使用部分或全部(取决于购买的版本)上述特性,包括 Zend 针对 PHP 的安全修补程序和技术支持。

现在您已对 Zend Server 有了大致的了解,我们来试用一下。但在开始之前,我们照例要确定几件事:

  • 假定您具有 PHP 脚本编程的基本知识。如果没有,可通过此初学者系列快速入门。还假定您了解使用 Oracle 数据库和 SQL 的基本知识。

VirtualBox 软件设备包含 Zend Server 企业版的 7 天试用版,可以很轻松地再扩展 3 周,这样您就能在操作中了解所有特性,确定哪些特性对您最重要。该软件设备可以帮助您轻松、快速地开始了解 Zend Server、PHP 和 Oracle 组合;它用于本文中的所有示例。

如果您已经拥有一个工作的开发或生产环境,并且希望添加 Zend Server,您可以阅读 Linux(DEB 和 RPM 软件包)、Windows 和 Mac OS X 上详细的独立安装说明

熟悉 Zend Server 仪表盘

首先,您需要启动 VirtualBox,然后导入下载的 Zend Server VirtualBox 软件设备。阅读并同意 Zend 软件许可协议,然后针对新建的虚拟机调整内存、磁盘和 CPU 设置,启动虚拟机。如果遇到问题,请阅读有关 VirtualBox 软件设备入门的更多信息

启动虚拟机之后,将自动下载并安装 Zend Server(这可能需要几分钟时间)。完成之后,将显示 Linux 登录提示符,您可以在此使用密码“guest1234”以“guest”身份登录。进入虚拟桌面之后,启动浏览器,指向 URL http://localhost:10081/ZendServer,即可访问 Zend Server。

第一次尝试访问 Zend Server 时,将提示您接受许可,选择一个工作环境(在本文中,选择“Development”即可),然后输入管理员密码,如下所示:

image11-png

密码输入

输入所需信息,一路单击完成接下来的几个屏幕,然后您将到达 Zend Server 欢迎页面,如下所示:

image10-jpg

欢迎页面

Zend Server 欢迎页面概要介绍了您可以执行的各种操作:部署示例应用、阅读入门说明、观看介绍视频或下载 Zend 的持续交付蓝图。单击 Overview -> Dashboard 将转到 Zend Server Dashboard,这里是 Zend Server 的操作中心。以下简要介绍 Dashboard 各部分的功能:

您可以通过 Overview 部分统揽全局:它包含 Zend Server 的所有监视功能,允许您查看事件、最近错误以及资源使用情况和性能的统计信息。当前 PHP 版本及所安装组件的详细信息可从 Overview -> Server Info 页面获取,Overview -> Logs 处有运行中的重要日志文件更新。

image06-png

服务器信息

下一个是 Applications 部分。我们将在后面深入讨论应用,因此现在只需了解此部分是在服务器上部署和管理新 PHP 应用的主控制点。在此还可以控制虚拟主机、设置每个应用的监视和缓存规则以及安排作业。

image19-png

应用

Configuration 部分是关于 PHP 和服务器配置的。您可以启用或禁用 PHP 扩展,激活或停用 Zend 的性能和诊断工具,并且能够在 Zend PHP IDE 中对 Web 应用进行本地和远程的 PHP 调试和分析。如果您管理着 PHP 应用服务器集群,也可以在此配置分布式会话管理。

image00-png

PHP 配置

在 Administration 部分,您可以管理集群服务器、用户和密码;查看审计跟踪;更新许可;或者配置日志记录、邮件通知和错误报告的常规设置。有趣的是,Zend Server 有一个 Web API 用于从基于浏览器的管理界面外部执行其任何特性;您可以在 Administration -> WebAPI 处管理 API 密钥。

image01-png

用户审计跟踪

使用应用

谈到部署 PHP 应用时,似乎每个开发人员都有不同的方法:Composer、rsync、Phing、Ant、PEAR 或任意数量的自制解决方案。这导致不一致的工作流程,增加了运营团队的维护和故障排除开销。许多情况下甚至都未考虑自动化解决方案;部署完全是手动流程,这导致意外跳过一些步骤时,难以跟踪错误和不当配置。

Zend Server 尝试对此加以简化,它将应用看作分散的逻辑单元,可以使用一个集中的管理界面定义、部署和分析。可以用两种办法实现。您可以使用 ZPK 格式打包应用,然后使用 Zend Server 部署;Zend Server 自动将每个 ZPK 识别为一个单独的应用。如果您已经有现成的应用,或者使用不同的构建/打包系统,您可以使用应用的基本 URL 在 Zend Server 中手动定义应用条目。

使用这种以应用为中心的方法有不少好处。应用部署变得更简单、更一致,因为有提供应用代码的标准格式。应用开发人员可以预先定义所需的参数和环境变量;Zend Server 将在部署应用时自动提示输入这些参数,降低了配置不当的风险。最后,可以为每个应用定义事件和监视规则,这样可以在操作托管多个应用的集群时轻松识别需要注意的应用。

Zend Server 6.3 包含了许多 ZPK 格式的常见 PHP 应用,包括 Wordpress、Magento 和 Drupal。本文稍后将介绍其中一个部署示例。现在,我们先将一个现有服务器 URL 定义为应用。首先,打开一个终端窗口,以“root”身份登录(密码为“zend1234”)。然后在服务器的 Web 文档根目录(默认为 /var/www/html)中创建 opal 目录,并在其中添加下面的简单 PHP 脚本:

/var/www/html/opal/index.php:

<?php

echo 'Hello from Zend Server and PHP ' . phpversion();

?>

并没有令人印象深刻的地方,但不要担心,我们很快就会添加一些花俏的内容。现在,下一步是告诉 Zend Server 将这个新建的目录看作一个单独的应用。因此,依次单击 Applications -> Apps -> Define Application,并提供应用名称(“My OPAL App”)和基本 URL(“/opal”),定义一个新的应用。

image12-png

应用定义

新定义的应用现在应显示在 Applications -> Apps 页面中。

image15-png

应用部署

结合使用 Oracle Database 与 Zend Server

除了一个 Zend Server 工作实例,VirtualBox 软件设备还包括一个 Oracle Database 11g 快捷版(“Oracle XE”)安装,方便测试。由于 Zend Server 已经包含 PHP 的 OCI8 扩展,它可以直接连接到大多数 Oracle 数据库。这就可以使用 Zend Server 轻松、快速地开始构建 Oracle 支持的 PHP 应用。

我们来实践操作以下,先解除 Oracle XE 示例 HR 模式的锁定,然后更新先前的 PHP 脚本来查询此模式,并以 Web 页面形式显示结果。

首先,需要配置和启动 Oracle XE。提示输入 root 密码时,输入密码“zend1234”。

shell> su -

shell> /etc/init.d/oracle-xe configure

选择数据库端口和密码,如这些说明第 6 步中所示。

以“oracle”用户身份登录,设置 Oracle XE 环境变量。

shell> su - 

shell> su - oracle

shell> source /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh

有关以上步骤的详细信息,请参见这些附加说明。现在您应能够以系统管理员身份登录 Oracle Database 并解锁 HR 模式和用户帐户:

shell> sqlplus / as sysdba

SQL*Plus:Release 11.2.0.2.0 Production on Wed Feb 5 02:26:57 2014

Copyright (c) 1982, 2011, Oracle. All rights reserved.

Connected to:

Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> ALTER USER HR IDENTIFIED BY guessme ACCOUNT UNLOCK;

User altered.

Then, connect as the 'HR' user and run a quick query:

SQL> CONNECT hr

Enter password: ****

Connected.

SQL> SELECT FIRST_NAME, LAST_NAME, HIRE_DATE FROM EMPLOYEES;

FIRST_NAME           LAST_NAME                 HIRE_DATE

-------------------- ------------------------- ------------------

Steven               King                      17-JUN-03

Neena                Kochhar                   21-SEP-05

Lex                  De Haan                   13-JAN-01

Alexander            Hunold                    03-JAN-06

Bruce                Ernst                     21-MAY-07

...

现在,使用 PHP 执行相同操作,用以下代码更新先前的 PHP 脚本:

/var/www/html/opal/index.php:

<html>

  <head>

    <style type="text/css">

    table { border-collapse:collapse; }

    td { border:solid 1px black; padding:3px; }

    </style>

  </head>

  <body>

  <h2>Employees</h2>

  <?php

  // open database connection

  $db = oci_connect('hr', 'guessme', 'localhost/XE');

  if (!$db) {

    trigger_error('Unable to connect to database', E_USER_ERROR);

  }

  // formulate and parse query

  $sql = 'SELECT FIRST_NAME, LAST_NAME, HIRE_DATE FROM EMPLOYEES';

  $stmt = oci_parse($db, $sql);

  // execute query

  oci_execute($stmt);

  // iterate over result set

  $count = 0;

  echo '<table>';

  while (($row = oci_fetch_object($stmt)) != false) {

    echo '<tr>';

    echo '<td>' . htmlentities($row->FIRST_NAME) .'</td>';

    echo '<td>' . htmlentities($row->LAST_NAME) .'</td>';

    echo '<td>' . htmlentities($row->HIRE_DATE) .'</td>';

    echo '</tr>';

    $count++;

  }

  echo '</table><br/>';

  echo $count .' record(s) found.';

  // free statement handle and close connection

  oci_free_statement($stmt);

  oci_close($db);

  ?>

  </body>

</html>

该脚本首先通过用简单连接语法的 oci_connect() 函数打开一个到数据库服务器的连接。然后,它使用 oci_parse() 函数准备一个查询,会返回一个语句对象;然后将此语句对象传递给 oci_execute() 函数以执行查询。

将使用循环遍历结果集,将单个记录作为对象通过 oci_fetch_object() 返回。现在可以用对象属性访问每条记录的各个字段;接下来就是相当容易的了,我们用一个 HTML 表呈现这些字段值。处理完结果集中的所有记录后,使用 oci_close() 关闭连接。

通过 Web 浏览器访问该脚本(URL 为“http://localhost/opal/”)时,您应该看到类似下图的 Web 页面:

image08-png

数据库查询输出

访问 Zend Server Dashboard 时,现在您将能够看到您的新应用的使用统计信息、错误和性能。

image05-png

Zend Server 仪表盘,含 OPAL 应用统计信息

使用 Oracle Database 中的连接池

Oracle Database 包括数据库驻留连接池 (DRCP),专门针对需要高可扩展性的应用。有了 DRCP,就可以在不同的应用进程之间共享数据库连接,从而可以更高效地使用服务器资源和全面提高性能。Zend Server 附带的 PHP OCI8 扩展包括现成的 DRCP 支持,允许开发人员在其 PHP 应用中直接使用此特性。

要启用 DRCP,登录到数据库服务器并启动连接池:

shell> sqlplus / as sysdba

SQL*Plus:Release 11.2.0.2.0 Production on Wed Feb 5 03:01:23 2014

Copyright (c) 1982, 2011, Oracle. All rights reserved.

Connected to:

Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> execute dbms_connection_pool.start_pool();

PL/SQL procedure successfully completed.

通过查询特定的 DBA_CPOOL_INFO 视图确认该池已启动:

SQL> SELECT CONNECTION_POOL, STATUS, MAXSIZE

  2  FROM DBA_CPOOL_INFO;

CONNECTION_POOL             STATUS                  MAXSIZE

----------------------------------------------------------

SYS_DEFAULT_CONNECTION_POOL ACTIVE                  40

然后,在 Zend Server 管理控制台的 Configurations -> PHP 页面,找到 OCI8 部分并在 oci8.connection_class 变量中设置 PHP 应用所使用的 DRCP 连接类的名称。这个用户选择的名称允许从逻辑上区分不同应用的池化服务器:

image02-png

OCI8 DRCP 配置

最后,将关键字 POOLED 添加到 oci_connect() 连接字符串,让 PHP 应用使用 DRCP。尽管并非强制性的,但建议您用 oci_pconnect() 函数替换 oci_connect() 函数。以下是重写的代码版本:

<html>

  <head>

    <style type="text/css">

    table { border-collapse:collapse; }

    td { border:solid 1px black; padding:3px; }

    </style>

  </head>

  <body>

  <h2>Employees</h2>

  <?php

  // open database connection

  $db = oci_pconnect('hr', 'guessme', 'localhost/XE:POOLED');

  if (!$db) {

    trigger_error('Unable to connect to database', E_USER_ERROR);

  }

  // formulate and parse query

  $sql = 'SELECT FIRST_NAME, LAST_NAME, HIRE_DATE FROM EMPLOYEES';

  $stmt = oci_parse($db, $sql);

  // execute query

  oci_execute($stmt);

  // iterate over result set

  $count = 0;

  echo '<table>';

  while (($row = oci_fetch_object($stmt)) != false) {

    echo '<tr>';

    echo '<td>' . htmlentities($row->FIRST_NAME) .'</td>';

    echo '<td>' . htmlentities($row->LAST_NAME) .'</td>';

    echo '<td>' . htmlentities($row->HIRE_DATE) .'</td>';

    echo '</tr>';

    $count++;

  }

  echo '</table><br/>';

  echo $count .' record(s) found.';

  // free statement handle and close connection

  oci_free_statement($stmt);

  oci_close($db);

  ?>

  </body>

</html>

您还将注意到,脚本中唯一的改动是修改了连接调用;无需其他修改即可利用 DRCP。

 

使用页面和 Opcode 缓存提高性能

Zend Server 包括两个专为提高应用性能而设计的组件:Zend Page Cache(它提供基于 URL 的 HTML 输出缓存),以及 Zend OPcache(它在运行时预编译并缓存 PHP 代码)。这两个特性都是完全基于服务器的;无需更改应用代码即可启用。

为说明其工作原理,我尝试使用 Zend Server 对一个常见的开源应用进行基准测试:phpBB3,这是一个基于 PHP 的高级公告板,适用于 Oracle Database 等各种数据库系统。phpBB3 可以从其官方网站免费下载,附带自动安装程序。

我首先在服务器文档根目录下的 phpbb/ 目录中安装 phpBB3,并按照 phpBB3 快速入门指南中的说明进行配置。然后,我访问了 Zend Server 的 Applications -> Apps 页面,并为其定义了一个新应用实体。

image13-png

应用定义

我登录了 phpBB3 Administration Control Panel,创建了 3 到 4 个新论坛。新论坛出现在应用的索引页面上。

image16-png

phpBB 索引页

该索引页面由 PHP 动态生成,PHP 查询 Oracle 数据库服务器、检索论坛列表并根据每个请求将结果设置为 HTML 格式。

接下来,我使用 ApacheBench 监视工具定量分析了 Zend Page Cache 和 Zend OPcache 的优势。首先,我访问了 Zend Server 的 Configurations -> Components 页面,关闭 Zend Page Cache 和 Zend OPcache,并重新启动 Zend Server 使更改生效。

image04-png

缓存组件关闭

然后,我通过针对论坛索引页面 URL 同时发送多个请求,使用 ApacheBench 生成服务器响应时间的基准测试。例如,下面这条命令发送 500 个请求,每次发送 10 个:

shell> ab -n 500 -c 10 http://192.168.1.9/phpbb/index.php

然后返回 Configurations -> Components 页面,启用 Zend Page Cache,并设置了一条新的索引页面 URL 缓存规则,如下所示:

image17-png

缓存规则

重新启动 Zend Server 之后,使用与之前相同的参数再次运行 ApacheBench。然后,重复此过程,这次激活 Zend OPcache。在示例服务器上,下面是三次基准测试的摘要:

image14-png

页面缓存和 opcode 缓存的结果

很显然,在我的演示实例上,Zend Page Cache 将服务响应能力提高了 16 倍,每秒服务的请求数从 13 跃升至 213。加入 Zend OPcache 之后,又提高 4 倍,服务器现在每秒能够服务 980 个请求。每个请求的平均时间也大幅下降。简而言之,只需启用这两个组件(无需其他微调或代码优化)即可显著提高性能。

除了 Zend Page Cache 和 Zend OPcache 之外,Zend Server 还包括其他一些有用的性能相关组件:

  • Zend Server Job Queue 让您可以安排 PHP 脚本稍后执行或在特定时间重复执行。这样可以轻松地将特定任务分流到非高峰时段(例如,迁移或处理数据库记录或发送电子邮件),同时仍可通过运行时统计信息和动态调度策略进行控制。您可以通过 Zend Server 管理界面配置作业。

  • Zend Data Cache API 之于数据正如 Zend OPcache 之于字节码:它提供了一种将如对象、数组和变量等 PHP 数据结构缓存在共享内存或磁盘文件中的方法。这就减少了每次请求命中数据库服务器的需要。要使用它,您需要通过 Zend Server 管理界面设置缓存配置参数,然后在 PHP 代码中调用相应的 API 函数。

记录和分析瓶颈和错误

Zend Server 6.3 还通过其监视和代码跟踪特性简化了根源分析,从而允许开发人员详细检查与预定义规则匹配的请求的完整执行流程。因此,举例来说,您可以定义一个识别慢速请求的规则,再定义一个识别导致未捕获异常的请求的规则,另外再定义一个捕获数据库错误的规则,依此类推。这些规则可以按应用指定,也可以全局指定(适用于服务器上的所有 PHP 脚本),对于每条规则,您可以进一步指定是否跟踪代码。

要查看 Zend Server 的某些监视规则(并创建您自己的规则),请访问 Applications -> Monitoring Rules 页面:

image09-jpg

Zend Server 默认监视规则

例如,您将看到一条针对数据库错误的默认规则,当与数据库相关的函数产生错误时,它将自动创建一个事件。此规则跟踪上一示例中使用的 oci_connect() 函数(及其他函数)。

image18-png

慢速查询规则

如果您要将 OPAL 应用更新为使用无效凭证,然后尝试访问它,将触发以上规则,您将在仪表盘中看到该应用的错误事件。单击事件记录,您将能查看堆栈跟踪、函数数据以及环境和服务器变量。

image03-png

数据库错误事件

对某个事件启用代码跟踪时,您将获得更精细的视图:脚本调用的所有函数和方法的列表,同时还包含其返回值和内存使用情况(Overview -> Code Tracing)。数据分层次呈现,从而易于执行细粒度的代码分析,或者准确追溯到引发错误的代码行。

慢速请求跟踪输出如下所示:

image07-png

慢速查询的代码跟踪输出

“Running Time”列便于识别导致最大开销的函数调用。跟踪输出包括所请求脚本的统计信息,显示特定函数或方法的调用次数,并提供有关执行时间和内存使用的信息。

总结

如以上示例所示,Zend Server 对应用的关注令企业环境中的开发运营团队可以更轻松地打包、配置、部署、监视和调试 Oracle+PHP 应用。强大而灵活的缓存引擎、内置的 Oracle Database 支持、易于通过会话集群和连接池扩展完善了软件包,使其成为在 Oracle 基础架构上部署 PHP 应用的优秀解决方案。

关于作者

Vikram VaswaniMelonfire(一家在开源工具和技术方面具有专业技能的咨询服务公司)的创始人和 CEO。他还著有《Zend Framework:A Beginners Guide》《PHP:A Beginners Guide》

版权所有 Zend Technologies,2014。许可发布。