二、持续分析和监测

在本章中,我们将学习如何安装和配置评测和监控工具,帮助您在持续集成CI)和持续部署CD环境中轻松优化 PHP 代码。

我们将首先安装和配置一个基本的Blackfire.io设置,以便在将代码提交到存储库时轻松自动地分析代码。我们还将学习如何安装 TICK 堆栈,以便在实时生产服务器上部署代码后持续监控代码的性能。

因此,在本章中,我们将介绍以下几点:

  • 安装和配置Blackfire.io代理、客户端和 PHP 扩展
  • Blackfire.io客户端与 Google Chrome 集成
  • Blackfire.io客户端与 Travis 等已知 CI 工具集成
  • 使用 Grafana 安装和配置完整的 TICK 堆栈

什么是 Blackfire.io?

如黑火官方网站(所述)https://blackfire.ioBlackfire 授权所有开发者和 IT/OP 在其整个生命周期内,通过在正确的时刻获取正确的信息,不断验证和改进其应用程序的性能。因此,它是一种性能管理解决方案,允许您在应用程序的整个生命周期内,特别是在开发阶段,通过断言自动评测代码并设置性能标准。Blackfire.io是一种工具,通过从项目一开始就将性能测试作为开发周期的一部分,使 Fabien Povertier 将性能称为功能成为可能。

安装和配置 Blackfire.io

安装和配置Blackfire.io意味着设置三个组件:代理、客户端和 PHP 探测器。在本书的上下文中,我们将在 LinuxforPHP 容器中安装Blackfire.io。有关在其他操作系统上安装Blackfire.io的更多信息,请参阅以下说明:https://blackfire.io/docs/up-and-running/installation

我们将从安装 Blackfire 代理开始。在容器的命令行界面上,输入以下命令:

# rm /srv/www
# ln -s /srv/fasterweb/chapter_2 /srv/www
# cd /srv/www
# wget -O blackfire-agent https://packages.blackfire.io/binaries/blackfire-agent/1.17.0/blackfire-agent-linux_static_amd64

下载完成后,您将看到以下结果:

Blackfire agent download is done

如果是,请键入以下命令继续:

# mv blackfire-agent /usr/local/bin/ 
# chmod +x /usr/local/bin/blackfire-agent 

现在,我们将把一个基本代理配置文件复制到我们的etc目录:

# mkdir -p /etc/blackfire 
# cp agent /etc/blackfire/ 

这是我们刚才复制的文件的内容。正如 Blackfire 团队所建议的,它是一个基本配置文件:

[blackfire] 
; 
; setting: ca-cert 
; desc   : Sets the PEM encoded certificates 
; default: 
ca-cert= 

; 
; setting: collector 
; desc   : Sets the URL of Blackfire's data collector 
; default: https://blackfire.io 
collector=https://blackfire.io/ 

; 
; setting: log-file 
; desc   : Sets the path of the log file. Use stderr to log to stderr 
; default: stderr 
log-file=stderr 

; 
; setting: log-level 
; desc   : log verbosity level (4: debug, 3: info, 2: warning, 1: error) 
; default: 1 
log-level=1 

; 
; setting: server-id 
; desc   : Sets the server id used to authenticate with Blackfire API 
; default: 
server-id= 

; 
; setting: server-token 
; desc   : Sets the server token used to authenticate with Blackfire 
API. It is unsafe to set this from the command line 
; default: 
server-token= 

; 
; setting: socket 
; desc   : Sets the socket the agent should read traces from. Possible 
value can be a unix socket or a TCP address 
; default: unix:///var/run/blackfire/agent.sock on Linux, 
unix:///usr/local/var/run/blackfire-agent.sock on MacOSX, and 
tcp://127.0.0.1:8307 on Windows. 
socket=unix:///var/run/blackfire/agent.sock 

; 
; setting: spec 
; desc   : Sets the path to the json specifications file 
; default: 
spec= 

然后,创建一个将用作代理套接字的空文件:

# mkdir -p /var/run/blackfire 
# touch /var/run/blackfire/agent.sock 

最后,我们将向 Blackfire service 注册我们的代理:

# blackfire-agent -register 

输入最后一个命令后,必须提供 Blackfire 服务器凭据。这些可以在您的 Blackfire 帐户中找到:https://blackfire.io/account#server 。输入凭据后,可以通过输入以下命令启动代理:

# blackfire-agent start & 

启动代理后,您应该会看到代理的 PID 编号。这表明代理正在侦听我们先前创建的默认 UNIX 套接字。在本例中,代理的 PID 编号为八(8):

Blackfire agent process ID number is displayed

一旦安装并配置了代理,就可以安装 Blackfire 客户端。我们将通过发出以下命令来安装和配置客户端。让我们从下载二进制文件开始:

# wget -O blackfire https://packages.blackfire.io/binaries/blackfire-agent/1.17.0/blackfire-cli-linux_static_amd64 

下载完成后,您将看到以下消息:

Blackfire client download is done

现在可以继续配置客户端。输入以下命令:

# mv blackfire /usr/local/bin/ 
# chmod +x /usr/local/bin/blackfire 
# blackfire config 

输入最后一个命令后,您必须提供 Blackfire 客户端凭据。也可以在您的 Blackfire 帐户的以下 URL 中找到这些内容:https://blackfire.io/account#client

在我们的服务器上运行Blackfire.io的最后一步是将 Blackfire Probe 安装为 PHP 扩展。为此,请从下载库开始:

# wget -O blackfire.so https://packages.blackfire.io/binaries/blackfire-php/1.20.0/blackfire-php-linux_amd64-php-71.so

下载完成后,您将收到以下确认消息:

Blackfire probe download is done

然后可以将共享库文件复制到 PHP 扩展目录中。如果不确定此目录的位置,可以在将库文件移动到其中之前发出以下命令:

# php -i | grep 'extension_dir' 
# mv blackfire.so $( php -i | grep extensions | awk '{print $3}' )

在本例中,扩展的目录是/usr/lib/php/extensions/no-debug-non-zts-20160303

您现在可以在PHP.INI文件中配置扩展名。激活 Blackfire 探测器时,建议您停用其他调试和评测扩展,如 xdebug。请运行以下命令(或者,您可以复制并粘贴包含在我们的存储库中且已包含这些修改的PHP.INI文件):

# sed -i 's/zend_extension=\/usr\/lib\/php\/extensions\/no-debug-non-zts-20160303\/xdebug.so/;zend_extension=\/usr\/lib\/php\/extensions\/no-debug-non-zts-20160303\/xdebug.so/' /etc/php.ini
# sed -i 's/^xdebug/;xdebug/' /etc/php.ini
# cat >>/etc/php.ini << 'EOF'

[blackfire]
extension=blackfire.so
; On Windows use the following configuration:
; extension=php_blackfire.dll

; Sets the socket where the agent is listening.
; Possible value can be a unix socket or a TCP address.
; Defaults to unix:///var/run/blackfire/agent.sock on Linux,
; unix:///usr/local/var/run/blackfire-agent.sock on MacOSX,
; and to tcp://127.0.0.1:8307 on Windows.
;blackfire.agent_socket = unix:///var/run/blackfire/agent.sock

blackfire.agent_timeout = 0.25

; Log verbosity level (4: debug, 3: info, 2: warning, 1: error)
;blackfire.log_level = 1

; Log file (STDERR by default)
;blackfire.log_file = /tmp/blackfire.log

;blackfire.server_id =

;blackfire.server_token =
EOF 

请通过重新启动 PHP-FPM 完成扩展的安装和配置:

# /etc/init.d/php-fpm restart 

让我们从命令行分析第一个脚本。现在可以通过在容器的 CLI 上输入以下命令来运行客户端:

# blackfire curl http://localhost/index.php 

配置文件完成后,您将获得一个 URL 和一些配置文件统计信息。如果浏览到 URL,您将看到配置文件的调用图,并获得有关配置文件脚本的更详细信息:

The Blackfire client returns a preliminary profiling report and a URL to view the script’s call graph

您还可以选择将客户端作为浏览器插件安装。在本例中,我们将使用 Blackfire Companion,一个 Google Chrome 扩展。要安装扩展,请使用 Chrome 访问以下 URL 并单击安装按钮:https://blackfire.io/docs/integrations/chrome 。完成后,通过浏览页面并单击工具栏中 Blackfire Companion 的图标,然后单击 profile 按钮,可以评测服务器上的资源:

Blackfire Companion for Chrome allows you to profile a PHP script directly from the browser

使用 Blackfire.io 手动评测

我们将从手动评测两个 PHP 脚本开始,以便更好地理解 Blackfire 工具的有用性和强大性。我们将使用以下脚本,可以在我们的存储库(chap2pre.php中找到该脚本):

<?php 

function getDiskUsage(string $directory) 
{ 
    $handle = popen("cd $directory && du -ch --exclude='./.*'", 'r'); 

    $du = stream_get_contents($handle); 

    pclose($handle); 

    return $du; 
} 

function getDirList(string $directory, string &$du) 
{ 
    $result = getDiskUsage($directory); 

    $du = empty($du) 
        ? '<br />' . preg_replace('/\n+/', '<br />', $result) 
        : $du; 

    $fileList = []; 

    $iterator = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); 

    foreach($iterator as $entry) { 

        if (!$entry->isDir() && $entry->getFilename()[0] != '.') { 
            $fileList[$entry->getFilename()] = 'size is ' . $entry->getSize(); 
        } else { 
            if ($entry->isDir() && $entry->getFilename()[0] != '.') { 
                $fileList[$entry->getFilename()] = getDirList( 
                    $directory . DIRECTORY_SEPARATOR . $entry->getFilename(), 
                    $du 
                );
 }
        } 

    } 

    return $fileList; 
} 

$du = ''; 

$baseDirectory = dirname(__FILE__); 

$fileList = getDirList($baseDirectory, $du); 

echo '<html><head></head><body><p>'; 

echo 'Disk Usage : ' . $du . '<br /><br /><br />'; 

echo 'Directory Name : ' . $baseDirectory . '<br /><br />'; 

echo 'File listing :'; 

echo '</p><pre>'; 

print_r($fileList); 

echo '</pre></body></html>'; 

该脚本基本上列出了存储库中包含的所有文件(目录及其子目录),并计算每个文件的大小。此外,它还提供了每个目录大小的聚合结果。请使用 Chrome 浏览到以下 URL 以查看脚本的输出,并使用 Blackfire Companion 启动配置文件:http://localhost:8181/chap2pre.php

Clicking on the Blackfire icon in the upper-right toolbar will allow you to launch a profiling session

单击配置文件按钮并等待几秒钟后,您应该可以选择单击查看调用图按钮:

You can click on the ‘View call graph’ button to view the script’s call graph

结果如下:

The script took 14.3 ms to complete its execution and five processes were created using the 'popen' function

结果显示,该脚本的实时性(墙时间[1])为 14.3 毫秒,唯一具有重要排他时间的函数为stream_get_contentspopen。这是合乎逻辑的,因为脚本必须处理磁盘访问和可能的大量 I/O 延迟。不那么合乎逻辑的是,脚本似乎在创建五个子进程,以便获得一个简单的文件列表。

此外,如果向下滚动,我们会注意到SplInfo::getFilename被调用了 67 次,这几乎是目录中文件数量的两倍:

The SplFileInfo::getFilename function was called 67 times

从分析器中获得的信息使我们能够快速确定代码库的哪些部分应该成为代码审阅候选对象,以及在审阅它们时要查找哪些内容。快速查看一下我们的代码,就会发现我们在每次目录迭代中都调用了popen,而不是在开始时只调用一次。一个简单的修复方法是替换这两行代码:

function getDirList(string $directory, string &$du) 
{ 
    $result = getDiskUsage($directory); 

    $du = empty($du) 
        ? '<br />' . preg_replace('/\n+/', '<br />', $result) 
        : $du;  
[...]  

然后可以在其位置插入以下代码行:

function getDirList(string $directory, string &$du) 
{ 
    $du = empty($du) 
        ? '<br />' . preg_replace('/\n+/', '<br />', getDiskUsage($directory)) 
        : $du;

[...]

最后的调整是用包含函数调用结果的变量替换对SplInfo::getFilename()的所有调用。修改后的脚本将如下所示:

<?php 

function getDiskUsage(string $directory) 
{ 
    $handle = popen("cd $directory && du -ch --exclude='./.*'", 'r'); 

    $du = stream_get_contents($handle); 

    pclose($handle); 

    return $du; 
} 

function getDirList(string $directory, string &$du) 
{ 
    $du = empty($du) 
        ? '<br />' . preg_replace('/\n+/', '<br />', getDiskUsage($directory)) 
        : $du; 

    $fileList = []; 

    $iterator = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); 

    foreach($iterator as $entry) { 

        $fileName = $entry->getFilename(); 

        $dirFlag = $entry->isDir(); 

        if (!$dirFlag && $fileName[0] != '.') { 
            $fileList[$fileName] = 'size is ' . $entry->getSize(); 
        } else { 
            if ($dirFlag && $fileName[0] != '.') { 
                $fileList[$fileName] = getDirList( 
                    $directory . DIRECTORY_SEPARATOR . $fileName, 
                    $du 
                ); 
            } 
        } 

    } 

    return $fileList; 
} 

$du = ''; 

$baseDirectory = dirname(__FILE__); 

$fileList = getDirList($baseDirectory, $du); 

echo '<html><head></head><body><p>'; 

echo 'Disk Usage : ' . $du . '<br /><br /><br />'; 

echo 'Directory Name : ' . $baseDirectory . '<br /><br />'; 

echo 'File listing :'; 

echo '</p><pre>'; 

print_r($fileList); 

echo '</pre></body></html>'; 

让我们试着分析新脚本(chap2post.php),以衡量我们的改进。同样,请使用 Chrome 浏览到以下 URL 以查看脚本的输出,并使用 Blackfire Companion 启动配置文件:http://localhost:8181/chap2post.php

结果如下:

Now, the script takes only 4.26 ms to complete its execution and only one process was created using the 'popen' function

结果显示,该脚本现在的墙时间为 4.26 毫秒,并且函数popen只创建了一个子进程。另外,如果我们向下滚动,我们现在注意到SplInfo::getFilename只被称为三十三次,比以前少了两倍:

Now, the SplFileInfo::getFilename function gets called only 33 times

这些都是显著的改进,特别是当这个脚本在不同的目录结构上每分钟被调用数千次时。确保这些改进不会在应用程序开发周期的未来迭代中丢失的一个好方法是通过性能测试自动化探查器。现在,我们将给出一个如何使用Blackfire.io自动执行性能测试的快速示例。

使用 Blackfire.io 进行性能测试

在开始之前,请注意,此功能仅适用于高级用户和企业用户,因此,它需要付费订阅。

为了自动化性能测试,我们将首先在存储库中创建一个非常简单的blackfire.yml文件。此文件将包含我们的测试。测试应该由一个名称、一个正则表达式和一组断言组成。最好避免创建易失性时间测试,因为这些测试非常脆弱,可能会在一个分析会话到下一个分析会话之间产生非常不同的结果。强性能测试的示例是通过概要文件比较来检查 CPU 或内存消耗、SQL 查询数或测试结果。在我们的例子中,我们将创建一个非常基本且不稳定的时间测试,只是为了给出一个简短的示例。以下是我们.blackfire.yml文件的内容:

tests: 
    "Pages should be fast enough": 
        path: "/.*" # run the assertions for all HTTP requests 
        assertions: 
            - "main.wall_time < 10ms" # wall clock time is less than 10ms 

最后一步是将此性能测试与持续集成工具集成。要选择您选择的工具,请参考以下 URL 上的文档:https://blackfire.io/docs/integrations/index

在本例中,我们将与Travis CI集成。为此,我们必须创建两个文件。其中一个将包括我们的凭证,并且必须加密(.blackfire.travis.ini.enc。另一个将包括我们的 Travis 说明(.travis.yml

以下是加密前我们.blackfire.travis.ini文件的内容(用您自己的凭证替换凭证):

[blackfire] 

server-id=BLACKFIRE_SERVER_ID 
server-token=BLACKFIRE_SERVER_TOKEN 
client-id=BLACKFIRE_CLIENT_ID 
client-token=BLACKFIRE_CLIENT_TOKEN 
endpoint=https://blackfire.io/ 
collector=https://blackfire.io/ 

在提交到存储库之前,必须对该文件进行加密。为此,请在 Linux for PHP 容器中发出以下命令:

# gem install travis
# travis encrypt-file /srv/www/.blackfire.travis.ini -r [your_Github_repository_name_here] 

以下是我们.travis.yml文件的内容:

language: php 

matrix: 
    include: 
        - php: 5.6 
        - php: 7.0 
          env: BLACKFIRE=on 

sudo: false 

cache: 
    - $HOME/.composer/cache/files 

before_install: 
    - if [[ "$BLACKFIRE" = "on" ]]; then 
        openssl aes-256-cbc -K [ENCRYPT_KEY_HERE] -iv [ENCRYPT_IV_HERE] -in .blackfire.travis.ini.enc -out ~/.blackfire.ini -d 
        curl -L https://blackfire.io/api/v1/releases/agent/linux/amd64 | tar zxpf - 
        chmod 755 agent && ./agent --config=~/.blackfire.ini --socket=unix:///tmp/blackfire.sock & 
      fi 

install: 
    - travis_retry composer install 

before_script: 
    - phpenv config-rm xdebug.ini || true 
    - if [[ "$BLACKFIRE" = "on" ]]; then 
        curl -L https://blackfire.io/api/v1/releases/probe/php/linux/amd64/$(php -r "echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;")-zts | tar zxpf - 
        echo "extension=$(pwd)/$(ls blackfire-*.so | tr -d '[[:space:]]')" > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/blackfire.ini 
        echo "blackfire.agent_socket=unix:///tmp/blackfire.sock" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/blackfire.ini 
      fi 

script: 
    - phpunit 

一旦提交,此配置将确保性能测试将在每个 git 推送到 Github 存储库上运行。因此,性能成为一项功能,并像应用程序的任何其他功能一样不断地进行测试。下一步是在生产服务器上部署后监视代码的性能。让我们来发现一些可用的工具,以便这样做。

使用 TICK 堆栈监视性能

TICK Stack 由 InfluxData(InfluxDB)开发,由一系列集成组件组成,允许您轻松处理不同服务随时间生成的时间序列数据。TICK 是一个首字母缩略词,由监控套件每个主要产品的首字母组成。T 代表 Telegraf,它收集我们希望在生产服务器上获得的信息。I 代表 InfluxDB,它是一个时间序列数据库,包含由 Telegraf 或任何其他配置为这样做的应用程序收集的信息。C 代表 Chronograf,这是一种图形工具,使我们能够轻松理解收集的数据。最后,K 代表 Kapacitor,一种警报自动化工具。

监控基础架构性能不仅对于确定应用程序和脚本是否按预期运行非常重要,而且还允许开发更高级的算法,如故障预测和意外行为模式识别,从而使性能监控的许多方面实现自动化。

当然,还有许多其他优秀的性能监控工具,如 Prometheus 和 Graphite,但我们决定改用 TICK stack,因为我们更感兴趣的是做事件日志记录,而不是做纯粹的度量。有关滴答堆栈是什么、内部如何工作以及它的用途的更多信息,请阅读 Gianluca Arbezzano 在 Codeship 网站上发表的这篇信息丰富的文章:https://blog.codeship.com/infrastructure-monitoring-with-tick-stack/

现在,为了看看我们的Blackfire.io支持的分析有多有用,以及我们的代码有多高效,我们将再次运行这两个脚本,但这次,同时使用正式的 TICK-Docker 图像副本,以便在部署优化的 PHP 脚本后,我们可以监控 Web 服务器整体性能的任何改进。我们还将用 Grafana(一种高度可定制的图形工具)取代 Chronograf,我们不会设置 Kapacitor,因为配置警报稍微超出了我们当前目标的范围。

让我们首先在 Apache 服务器上激活mod_status。从 Linux for PHP 的 CLI 中,输入以下命令:

# sed -i 's/#Include \/etc\/httpd\/extra\/httpd-info.conf/Include \/etc\/httpd\/extra\/httpd-info.conf/' /etc/httpd/httpd.conf 
# sed -i 's/Require ip 127/Require ip 172/' /etc/httpd/extra/httpd-info.conf 
# /etc/init.d/httpd restart 

完成此操作后,您应该能够通过使用 Chrome 浏览以下 URL 来查看服务器的状态报告:http://localhost:8181/server-status?auto

下一步是启动 TICK 套件。为此,请打开两个新的终端窗口。

在第一个终端窗口中,键入以下命令:

# docker run -d --name influxdb -p 8086:8086 andrewscaya/influxdb 

然后,在第二个新打开的终端窗口中,通过发出以下命令获取两个容器的 IP 地址:

# docker network inspect bridge 

以下是在我的计算机上执行此命令的结果:

The IP addresses of the two containers

请保留这两个地址,因为配置 Telegraf 和 Grafana 需要它们。

现在,我们将使用一个简单的命令为 Telegraf 生成一个示例配置文件(此步骤是可选的,因为本书的存储库中已经包含了一个示例文件)。

首先,将目录更改为我们项目的工作目录(Git repository),并输入以下命令:

# docker run --rm andrewscaya/telegraf -sample-config > telegraf.conf 

其次,使用您最喜欢的编辑器打开新文件,并取消注释inputs.apache部分中的以下行。不要忘记在urls行输入我们的 Linuxfor PHP容器的 IP 地址:

Configuring Telegraf in order to have it monitor the Apache server running in the other container

在终端窗口中,我们现在可以使用以下命令启动 Telegraf(请确保您位于我们项目的工作目录中):

# docker run --net=container:influxdb -v ${PWD}/telegraf.conf:/etc/telegraf/telegraf.conf:ro andrewscaya/telegraf

在第二个新生成的终端窗口中,使用以下命令启动 Grafana:

# docker run -d --name grafana -p 3000:3000 andrewscaya/grafana

使用 Chrome,浏览至http://localhost:3000/login。您将看到 Grafana 的登录页面。请使用密码 admin 向用户 admin 进行身份验证:

The Grafana login page is displayed

然后,添加一个新的数据源:

Connecting Grafana to a data source

请为 XDB 数据源选择一个名称。选择 XDB 作为类型。输入 InfluxDB 容器实例的 URL,其中包括您在前面的一个步骤中获得的 IP 地址,然后是 InfluxDB 的默认端口号,即 8086。您可以选择直接访问。数据库的名称为 telegraf,数据库的用户和密码为 root:

Configuring Grafana's data source

最后,单击添加按钮:

Adding the data source

现在已经添加了数据源,让我们添加几个仪表板,我们将从 Grafana 网站导入这些仪表板。首先单击仪表板菜单项下的导入:

Click on the import menu item to begin importing dashboards

我们将添加的两个仪表板如下:

The homepage of the Telegraf Host Metrics dashboard

The homepage of the Apache Overview dashboard

在导入屏幕上,只需输入仪表板的编号,然后单击加载:

Loading the Telegraf Host Metrics dashboard

然后,确认新仪表板的名称并选择本地 XDB 连接:

Connecting the Telegraf Host Metrics dashboard to the InfluxDB data source

您现在应该可以看到新的仪表板:

The Telegraf Host Metrics dashboard is displayed

现在,我们将重复最后两个步骤以导入 Apache 概览仪表板。单击仪表板菜单项下的导入按钮后,输入仪表板的标识符(331,然后单击加载按钮:

Loading the Apache Overview dashboard

然后,确认名称并选择本地 XDB 数据源:

Connecting the Apache Overview dashboard to the InfluxDB data source

现在,您应该可以在浏览器中看到第二个仪表板:

The Apache Overview dashboard is displayed

所有 TICK suite 仪表板都允许对图形进行更高级的配置和自定义。因此,例如,可以通过执行自定义 cron 脚本来收集一组自定义的时间序列数据点,然后配置仪表板以显示您认为合适的数据。

在我们当前的示例中,现在安装并配置了 TICK 套件。因此,我们可以开始测试和监控本章第一部分中使用Blackfire.io优化的 PHP 脚本,以测量其性能的变化。我们将从部署、基准测试和监控旧版本开始。在 Linux for PHP 的 CLI 上,输入以下命令以对脚本的旧版本进行基准测试:

# siege -b -c 3000 -r 100 localhost/chap2pre.php 

基准测试应产生类似于以下结果的结果:

The results of the performance benchmark of the original script are displayed

然后,在等待大约十分钟后,通过输入以下命令开始基准测试脚本的新版本:

# siege -b -c 3000 -r 100 localhost/chap2post.php 

以下是我电脑上最新基准测试的结果:

The results of the performance benchmark of the optimized script are displayed

结果已经向我们表明,性能有了相当大的改进。事实上,新脚本允许每秒事务数增加三倍以上,失败事务数减少三倍以上。

现在,让我们来看看我们的 TICK 堆栈收集了哪些关于这两个版本的 PHP 脚本性能的数据:

The gain in performance is clearly seen in the monitoring graphs

Grafana 仪表板中的图表清楚地显示了与基准测试结果相同数量级的性能提升。在 08:00 之后针对我们的脚本的新版本启动的基准测试显然在服务器上产生的负载减少了两倍,导致的输入(I/O)减少了两倍,并且总体上比之前在 7:40 左右进行基准测试的旧版本快三倍多。因此,毫无疑问,我们的Blackfire.io优化使新版本的 PHP 脚本更加高效。

总结

在本章中,我们学习了如何安装和配置基本的Blackfire.io设置,以便在将代码提交到存储库时轻松自动地分析代码。我们还探讨了如何安装 TICK 堆栈,以便在实时生产服务器上部署代码后持续监控代码的性能。因此,我们已经了解了如何在持续集成CI)和持续部署CD环境中安装和配置评测和监控工具,帮助我们轻松优化 PHP 代码。

在下一章中,我们将探讨更好地理解 PHP 数据结构和使用简化函数如何帮助应用程序在其关键执行路径上实现全局性能。我们将从分析项目的关键路径开始,然后微调其某些数据结构和功能。

工具书类

[1] 有关这些性能测试术语的进一步解释,请访问此 URL:https://blackfire.io/docs/reference-guide/time