连接到 Azure Database for MySQL 时,Azure App Service 上的 PHP 性能下降

Bla*_*cle 4 php mysql azure azure-web-app-service azure-database-mysql

我在 Linux Azure 应用服务(计划 P1v2)上托管在 CodeIgniter 3 框架上编写的 PHP 7.2 网站。数据库是 MySQL 5.7,在 Azure Database for MySQL(通用,2vCores,5GB 存储)上运行,禁用 SSL。

当我浏览我的网站时,它实际上需要大约 8-9 秒的时间来加载浏览器将停留在白色页面并在加载完成后立即显示所有内容的地方。(大部分网站内容是从数据库中提取的)

我一直在监视应用服务和 MySQL 数据库,平均 %CPU 从未达到其分配资源的 50%,因此规格似乎不是问题。

我的外包开发团队有他们自己的测试环境(不在 Azure 上),他们说它几乎立即加载到他们的环境中,所以他们指责 Azure。

然后我注意到 Azure 顾问告诉我关于这个数据库的两件事,其中影响很大

改善 MySQL 连接延迟 我们的内部遥测表明您连接到 MySQL 服务器的应用程序可能无法有效地管理连接。这可能会导致更高的应用程序延迟。为了改善连接延迟,我们建议您启用连接重定向。这可以通过启用 PHP 驱动程序的连接重定向功能来完成。

改进 MySQL 连接管理 我们的内部遥测表明您连接到 MySQL 服务器的应用程序可能没有有效地管理连接。这可能会导致不必要的资源消耗和整体更高的应用程序延迟。为了改进连接管理,我们建议您减少短连接的数量并消除不必要的空闲连接。这可以通过配置服务器端连接池来完成,例如 ProxySQL。

我现在正在努力启用连接重定向以减少延迟,但仍然没有成功,因为我不熟悉 CodeIgniter,所以我需要等待开发人员修复它。

我的问题是:这个性能问题的原因是什么?这两个建议真的是这个问题的原因吗?

应用服务和数据库都在同一个区域。它们是否像某种 LAN 连接那样在本地进行通信?我希望来自 App Service 的连接不会通过 Internet 然后返回到 Azure DB,从而导致性能下降。

谢谢。

Bla*_*cle 6

我已经解决了这个问题,结果 Azure 顾问是对的!我已启用连接重定向,现在我的网站在 3 秒内完成加载。这是我所做的。

TL;DR 将您的应用程序配置为在连接到数据库时使用 SSL,并将mysqlnd_azure扩展程序文件放入已部署的应用程序中,设置 Azure Web 应用程序的应用程序设置以读取使其加载扩展程序的 ini 文件。然后将 Azure MySQL DB 服务器参数设置redirect_enabled为 ON 并启用 Enforce SSL with TLS 1.2。重新启动应用程序。

注意:确保设置 Enforce SSL 是您做的最后一件事,否则它会拒绝所有非 SSL 连接并且您的应用程序根本无法运行。


2021 年 1 月更新

我刚刚发现微软似乎已经mysqlnd_azure为 Azure 应用服务内置了所需的扩展。不再需要以下大部分步骤。

您应该首先按照步骤 7 测试扩展是否已加载。如果mysqlnd_azure扩展在列表中,那么您可以继续执行步骤 8-10。不过,您仍然需要按照步骤 1. 为您的数据库配置 SSL 证书。

然后,按照本答案末尾参考中的示例代码链接,确认是否正在使用数据库连接重定向。您应该会看到文本mysqlnd_azure.enableRedirect: preferred,然后是以下格式的文本:[random text and numbers].[random text and numbers again].[your azure region].worker.database.windows.net

如果文本仍然显示您使用的 MySQL 主机名,例如mydatabase.mysql.database.azure.com,则连接重定向未在使用中。再检查一遍。

此行下方的原始答案。


  1. 将您的应用程序配置为在连接到数据库时使用 SSL。在笨,它的database.php文件/application/config/。确保您使用的所有 MySQL 驱动程序都启用了 SSL。从https://www.digicert.com/CACerts/BaltimoreCyber​​TrustRoot.crt.pem下载 SSL 证书并将其存储在您的应用程序目录中,例如/cert/BaltimoreCyberTrustRoot.crt.pem

     /*Snippet from database.php*/
     $db['production'] = array(
         'dsn'   => '',
         'hostname' => getenv("DB_HOST"),
         'username' => getenv("DB_USER"),
         'password' => getenv("DB_PWD"),
         'database' => getenv("DB_NAME"),
         'dbdriver' => 'mysqli',
         'dbprefix' => '',
         'pconnect' => FALSE,
         'db_debug' => FALSE,
         'cache_on' => FALSE,
         'cachedir' => '',
         'char_set' => 'utf8',
         'dbcollat' => 'utf8_general_ci',
         'swap_pre' => '',
         'encrypt' => [
             'ssl_key'    => NULL,
             'ssl_cert'   => NULL,
             'ssl_ca'     => '/home/site/wwwroot/cert/BaltimoreCyberTrustRoot.crt.pem',
             'ssl_capath' => NULL,
             'ssl_cipher' => NULL,
             'ssl_verify' => FALSE
         ],
         'compress' => FALSE,
         'stricton' => FALSE,
         'failover' => array(),
         'save_queries' => TRUE
     );
    
     /*Snippet for PHP (PDO)*/
     <?php
     define('CONN_HOST', getenv("DB_HOST"));
     define('CONN_DATABASE', getenv("DB_NAME"));
     define('CONN_USER', getenv("DB_USER"));
     define('CONN_PASSWORD', getenv("DB_PWD"));
     define('CONN_OPTION', array(
         PDO::MYSQL_ATTR_SSL_CA          =>     '/home/site/wwwroot/cert/BaltimoreCyberTrustRoot.crt.pem',
         PDO::MYSQL_ATTR_INIT_COMMAND    => "SET NAMES utf8"
     ));
    
    Run Code Online (Sandbox Code Playgroud)
  2. mysqlnd_azure按照此链接安装扩展https://azureossd.github.io/2019/01/29/azure-app-service-linux-adding-php-extensions/或者如果您只想立即安装 .so 扩展,请下载它来自http://www.mediafire.com/file/g6mzeld0wnqedw0/mysqlnd_azure.so/file否则从https://github.com/microsoft/mysqlnd_azure自己构建

  3. 放入mysqlnd_azure.so您的应用程序目录中。例如/bin/mysqlnd_azure.so然后将您的代码部署到 Azure

  4. SSH 进入您的应用服务,在/home/site名为ini. 创建一个任何名称的 .ini 文件,例如 settings.ini

  5. 使用 vi 或 nano 编辑该 ini 文件并粘贴这些行

    extension=/home/site/wwwroot/bin/mysqlnd_azure.so
    mysqlnd_azure.enableRedirect = on
    
    Run Code Online (Sandbox Code Playgroud)
  6. mysqlnd_azure通过添加名为PHP_INI_SCAN_DIRvalue的应用程序设置,告诉您的应用程序加载扩展/usr/local/etc/php/conf.d:/home/site/ini

  7. 保存应用设置后,Azure 将强制重启你的应用。之后,您可以检查扩展是否已被 SSH 再次加载并运行php -m以查看所有加载的扩展。如果您mysqlnd_azure在列表中看到,那么您就在正确的道路上!如果没有,此命令应该说明为什么它无法加载该扩展

  8. 在 Azure 门户上,导航到 Azure MySQL DB 并将服务器参数设置redirect_enabled为 ON

  9. 在连接安全下,启用强制 SSL 连接并选择 TLS 1.2

  10. 再次重新启动应用程序。

如果使用sslmode=verify-casslmode=verify-full,则需要在 2020 年 10 月 26 日切换到新的 SSL 证书。 参考https://docs.microsoft.com/en-us/azure/mysql/concepts-certificate-rotation 更新:微软已延长根证书弃用的截止日期为 2021 年 2 月 15 日。

如果您有任何部署槽,请确保为每个槽执行步骤 4-7。

参考: