很奇怪:如何在 Laravel Controller 中找到挂起的代码?

问题描述 投票:0回答:1

我正在管理一个用 Laravel 构建的网站,该网站在某些服务器上有时会挂起 30 秒或其倍数(60、90、120 甚至 150 秒)。 “30 秒错误”(这里内部是这样称呼的)可以通过简单地快速执行多次 ajax 调用来相当容易地复制。其他调用也会发生这种情况,但使用此调用可以更轻松地复制和隔离到一个调用。

事实上,它总是 30 秒的倍数,这让我认为这个 bug 是某种速率限制器,当许多请求非常快地发出时,就会出现这种情况。但我的研究告诉我事实并非如此。

为了研究这个问题,我首先在 laravel

public/index.php
文件中添加了一些日志语句,使文件看起来像这样(没有注释):

<?php
syslog(1, "# 1");
require __DIR__.'/../bootstrap/autoload.php';
syslog(1, "## 2");
$app = require_once __DIR__.'/../bootstrap/app.php';
syslog(1, "### 3");
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
syslog(1, "#### 4");
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
syslog(1, "##### 5");
$response->send();
syslog(1, "###### 6");
$kernel->terminate($request, $response);
syslog(1, "####### 7");

我看到它要么挂在

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

或在

$kernel->terminate($request, $response);

这对我来说已经很奇怪了。为什么有时会在一个点挂起,有时又在另一个点挂起?

所使用的路线在

routes/web.php
文件中定义如下:

Route::post('/ajax', 'DashboardController@ajax')->name('dashboard.ajax');

为了继续查找第一个选项中挂起的特定代码段 (

$response = $kernel->handle( etc..
),我还在所使用的控制器文件中放置了一些系统日志:
app/Http/Controllers/DashboardController.php
。我在构造函数中放置了一些系统日志:

    public function __construct()
    {
syslog(1, '- CONSTRUCT 1');
        $this->middleware('auth');
syslog(1, '-- CONSTRUCT 2');
        $this->middleware('permission:' . Permission::getDashboardPermissions('view'));
syslog(1, '--- CONSTRUCT 3');
    }

并在控制器功能中。

    public function ajax(Request $request)
    {
syslog(1, '= AJAX 1');
        $action = $request->input('action');
syslog(1, '== AJAX 2');
        $allowed_actions = ['getConsentData', 'getEPDDetails'];
syslog(1, '=== AJAX 3');
        if (in_array($action, $allowed_actions)) {
syslog(1, '==== AJAX 4');
            return response($this->$action(), 200)->header('Content-Type', 'application/json');
        }
syslog(1, '===== AJAX 5');

        return false;
    }

在这里我发现了一些非常奇怪的事情。我在系统日志中看到以下内容:

# 1
## 2
### 3
#### 4
- CONSTRUCT 1
-- CONSTRUCT 2
--- CONSTRUCT 3

它会挂起 30 秒。仅在 30 秒后,控制器才会继续执行控制器功能并显示

= AJAX 1

我被困住了。它怎么挂在构造函数和

ajax()
函数之间呢?我以为中间不会发生任何事情,但不知怎么的,它确实发生了。有比我更聪明的人能对这个问题有所启发吗?欢迎所有提示!

[编辑]

我只能在我们与一家特定托管公司合作的服务器上重现此错误。我尝试在简单的 DigitalOcean VM 上重现该错误,但无法在那里重现。我们的设置(在我们的托管公司和 DigitalOcean)是 Ubuntu 16.04,前面有 Apache。如果您需要有关此的更多信息,请告诉我。

php ajax laravel rate-limiting
1个回答
0
投票

我知道这是一篇旧帖子,但我也遇到了完全相同的问题。经过三天的测试,我想我终于弄清楚了。希望它可以帮助某人。

storage/framework/sessions 文件夹中有超过 220,000 个文件!我清除了所有这些,现在一切看起来都很好。我还在会话配置文件中修改了以下内容以阻止这种情况再次发生:

'expire_on_close' => false,
© www.soinside.com 2019 - 2024. All rights reserved.