Asterisk: func_curl.c CURL connection timeout occurred external dialplan URL
- Предупреждение:
WARNING: func_curl.c: CURL connection timeout occurred fetching external dialplan URL. - Входящие звонки замирают в тишине на несколько секунд перед дальнейшей маршрутизацией.
- Вызовы сбрасываются по тайм-ауту абонента, не дождавшись ответа CRM/ERP сервиса.
- Рост очереди ожидающих обработки каналов в выводе
core show channels.
1. Жесткое ограничение тайм-аутов в диалплане с помощью CURLOPT
Никогда не вызывайте функцию ${CURL()} без явного задания тайм-аута соединения и ответа. Отредактируйте extensions.conf:
[sub-crm-request]
exten => s,1,NoOp(Making HTTP API Call to CRM)
; Ограничение времени установки TCP соединения (в секундах)
same => n,Set(CURLOPT(conntimeout)=1)
; Ограничение максимального времени передачи данных (в секундах)
same => n,Set(CURLOPT(timeout)=2)
; Отключение проверки SSL при самоподписанных сертификатах (только в Intranet)
same => n,Set(CURLOPT(ssl_verifypeer)=0)
; Выполнение запроса
same => n,Set(CURL_RESPONSE=${CURL(https://crm.local/api/callerid?phone=${CALLERID(num)})})
same => n,Set(CURL_HTTP_CODE=${CURLOPT(httpcode)})
; Проверка успешности HTTP-запроса
same => n,GotoIf($["${CURL_HTTP_CODE}" = "200"]?success:fallback)
same => n(success),Set(CALLERID(name)=${CURL_RESPONSE})
same => n,Return()
same => n(fallback),Verbose(1, [WARNING] CRM API timed out or returned HTTP ${CURL_HTTP_CODE})
same => n,Set(CALLERID(name)=Default_Client)
same => n,Return()2. Проверка доступности и DNS-резолвинга внешнего URL
Проверьте время отклика API прямо с сервера Asterisk:
curl -w "\nTime Total: %{time_total}s | HTTP Code: %{http_code}\n" -s -o /dev/null https://crm.local/api/health3. Использование FastAGI для асинхронных тяжелых запросов
Для высоконагруженных систем выносите веб-запросы из диалплана в отдельный FastAGI сервис, чтобы не блокировать потоки PBX:
exten => s,1,AGI(agi://127.0.0.1:4573/get_client_info) Частые вопросы (FAQ)
Почему вызов функции CURL() без тайм-аутов опасен для Asterisk?
По умолчанию libcurl использует системный таймаут TCP соединения (до 60-120 секунд). Если внешний веб-сервис зависает, поток Asterisk, обслуживающий звонок, блокируется на это время, вызывая тишину в трубке.
В каких единицах задаются тайм-ауты в CURLOPT?
Параметры CURLOPT(conntimeout) и CURLOPT(timeout) принимают целые значения в секундах.
Как передать POST параметры и JSON через func_curl?
Используйте: Set(CURLOPT(httppost)={"phone":"${CALLERID(num)}"}) и Set(CURLOPT(httpheader)=Content-Type: application/json).
Как обработать ошибку DNS сбоя в func_curl?
Проверяйте значение переменной ${CURLOPT(httpcode)} — при сетевых и DNS сбоях код будет равен 0.