Я управляю веб-сайтом, созданным в Laravel, который на некоторых серверах иногда зависает ровно на 30 секунд или кратно этому (60, 90, 120 или даже 150 секунд). «30-секундная ошибка» (как ее здесь называют внутри) может быть легко воспроизведена простым быстрым выполнением нескольких вызовов ajax. Это случается и с другими вызовами, но с помощью этого вызова его проще реплицировать и изолировать от одного вызова.
Тот факт, что он всегда кратен 30 секундам, заставил меня думать, что ошибка — это своего рода ограничитель скорости, который срабатывает, когда многие запросы выполняются очень быстро. Но мое исследование сказало мне иначе.
Чтобы исследовать это, я начал с добавления некоторых записей в журнале 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, но не смог воспроизвести ее там. Наша установка (как в нашей хостинговой компании, так и в DigitalOcean) — это Ubuntu 16.04 с Apache перед ним. Если вам нужна дополнительная информация об этом, дайте мне знать.
Задача ещё не решена.
Других решений пока нет …