From f11e73e5259dece407a29d370e5885026e1bca3a Mon Sep 17 00:00:00 2001 From: Aleksey Filippov Date: Thu, 4 Jun 2026 19:49:42 +0300 Subject: [PATCH] =?utf8?q?fix:=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B0=D1=83?= =?utf8?q?=D1=82=D1=8B=20HTTP-=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=BE?= =?utf8?q?=D0=B2=20=D0=BA=20Telegram=20API=20(=D1=83=D1=81=D1=82=D1=80?= =?utf8?q?=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20504=20=D0=BD=D0=B0=20dev)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Запросы к api.telegram.org выполнялись через Guzzle/cURL без таймаутов. При недоступности api.telegram.org (резолвится только в IPv6, маршрута нет) cURL виснет ~130с. Отправка идёт синхронно внутри обработки запроса (в т.ч. из лог-таргета на каждый Yii::error), поэтому воркер PHP-FPM блокировался, пул (max_children=5) исчерпывался и весь сайт отдавал 504. Добавлены connect_timeout=2с и timeout=5с ко всем вызовам Telegram API через единый клиент getHttpClient(), а также CURLOPT_CONNECTTIMEOUT/ CURLOPT_TIMEOUT в cURL-вызовах sendPromoMessageToTelegramDocument. --- erp24/services/TelegramService.php | 43 +++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/erp24/services/TelegramService.php b/erp24/services/TelegramService.php index 2b015865..9c6da498 100644 --- a/erp24/services/TelegramService.php +++ b/erp24/services/TelegramService.php @@ -20,6 +20,33 @@ class TelegramService const TARGET_PROD_URL = "erp.erp-flowers.ru"; + /** + * Таймаут установки TCP/TLS-соединения с Telegram API (секунды). + * + * Почему важно: api.telegram.org резолвится в IPv6, и при отсутствии + * IPv6-маршрута cURL по умолчанию виснет ~130с. Запросы к Telegram + * выполняются синхронно внутри обработки HTTP-запроса (в т.ч. из + * лог-таргета на каждый Yii::error()), поэтому без таймаута блокируется + * воркер PHP-FPM, пул исчерпывается и весь сайт отдаёт 504. + */ + private const CONNECT_TIMEOUT = 2; + + /** + * Таймаут всего HTTP-запроса к Telegram API (секунды). + */ + private const REQUEST_TIMEOUT = 5; + + /** + * HTTP-клиент с обязательными таймаутами для запросов к Telegram API. + */ + private static function getHttpClient(): Client + { + return new Client([ + 'connect_timeout' => self::CONNECT_TIMEOUT, + 'timeout' => self::REQUEST_TIMEOUT, + ]); + } + /** * Получить токен бота для dev окружения */ @@ -66,7 +93,7 @@ class TelegramService if ($reply_markup) { $url .= "&reply_markup=" . json_encode($reply_markup, JSON_UNESCAPED_UNICODE); } - $client = new \GuzzleHttp\Client(); + $client = self::getHttpClient(); return $client->request('GET', $url); } @@ -102,7 +129,7 @@ class TelegramService $chatId = $chatIdErp; } - $client = new Client(); + $client = self::getHttpClient(); try { $client->post($apiURL, [ 'json' => [ @@ -123,7 +150,7 @@ class TelegramService $apiURL = "https://api.telegram.org/bot{$botToken}/sendMessage"; $chats = ['337084327', '730432579']; //Алексей и Владимир $message = self::escapeMarkdown($message); - $client = new Client(); + $client = self::getHttpClient(); foreach ($chats as $chatId) { try { $buttons = self::getTgButtons($chatId); @@ -199,6 +226,8 @@ class TelegramService curl_setopt($ch, CURLOPT_POSTFIELDS, $arrayQuery1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::CONNECT_TIMEOUT); + curl_setopt($ch, CURLOPT_TIMEOUT, self::REQUEST_TIMEOUT); $res1 = curl_exec($ch); curl_close($ch); @@ -217,6 +246,8 @@ class TelegramService curl_setopt($ch, CURLOPT_POSTFIELDS, $arrayQuery2); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::CONNECT_TIMEOUT); + curl_setopt($ch, CURLOPT_TIMEOUT, self::REQUEST_TIMEOUT); $res2 = curl_exec($ch); curl_close($ch); @@ -257,7 +288,7 @@ class TelegramService try { $buttons = self::getTgShortButtons($chatId); - $client = new Client(); + $client = self::getHttpClient(); $media = [ [ @@ -311,7 +342,7 @@ class TelegramService return $e->getMessage(); } - $client = new Client(); + $client = self::getHttpClient(); try { $response = $client->post($apiURL2, [ @@ -363,7 +394,7 @@ class TelegramService $message = self::escapeMarkdown($message); $buttons = self::getTgButtons($chatId); - $client = new Client(); + $client = self::getHttpClient(); try { $response = $client->post($apiURL, [ 'json' => [ -- 2.39.5