4

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

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

我一直在监控 App Service 和 MySQL DB,平均 %CPU 从未达到其分配资源的 50%,因此规格似乎不是问题。

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

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

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

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

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

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

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

谢谢。

4

1 回答 1

7

我已经解决了这个问题,结果证明 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_azureAzure App Service 所需的扩展。不再需要以下大多数步骤。

您应该首先按照步骤 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。在 CodeIgniter 中,它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"
     ));
    
  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
    
  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. 在 Connection Security 下,启用 Enforce SSL connection 并选择 TLS 1.2

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

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

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

参考:

于 2020-09-23T15:06:20.763 回答