Symfony 不服务并发请求

mar*_*ris 3 php mysql concurrency symfony doctrine-orm

我的问题是,我的 Symfony 应用程序在Apache/2.4.6 (CentOS) PHP/5.6.31 MySQL 5.7.19 的远程计算机上运行,​​无法处理并发请求。这意味着当同时请求两个不同的页面时。第一个必须先完成,然后才能渲染第二个。

我在同一服务器上有一个用普通 Php 编写的另一个站点,它可以同时渲染尽可能多的页面(它使用已弃用的 mysql 连接,而不是像 Doctrine 这样的 pdo)

也就是说,我做了以下测试:我插入了 sleep(3); 在我的 DefaultController 处。我请求了该页面,同时请求了另一个页面。请参阅下面的两个分析器:

睡眠页面(称为第 1 页): 睡眠页面(称为第 1 页) 没有睡眠的页面(称为第二页)。 没有睡眠的页面(称为第二页)

  • 第1页正常加载时间为782ms
  • 第2页正常加载时间为108ms

正如你所看到的,Symfony 的 Http Firewall 占用了第二个页面的所有时间来加载。我的猜测(可能很愚蠢)是,第一个操作保留数据库连接,只有在完成它之后,它才会放手让其他请求使用它。尤其是与 Doctrine 使用 PDO 连接有关的事情。

顺便说一句,我已经阅读过帮助和文章,例如: - Symfony 防火墙在做什么,需要这么长时间? -为什么构建 PDO 连接很慢? - https://www.drupal.org/node/1064342

PS 我尝试在 apache 配置中使用 app.php 和 app_dev.php 没有任何改变。坚持使用 app_dev.php,这样我就可以使用分析器。使用 Symfony 内置服务器的本地开发具有相同的结果

alb*_*ert 6

在 PHP 中,同一个打开的会话不能有 2 个并发请求。当您使用防火墙时,Symfony 会锁定用户会话,直到您手动释放它或请求得到服务。

要释放会话锁,请使用以下命令:

$session->save();
Run Code Online (Sandbox Code Playgroud)

请注意,会有一些缺点和影响。保存会话后,您将无法更新它(更改属性),直到下一个请求到达。

会话管理:https://symfony.com/doc/current/components/http_foundation/sessions.html

会话接口:http://api.symfony.com/4.0/Symfony/Component/HttpFoundation/Session/SessionInterface.html#method_save

注意 2. 如果您有多个具有不同会话的并发用户,PHP 将同时处理这些请求。