Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты на сайте предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, программного обеспечения, баз данных, сетевого оборудования и других компонентов инфраструктуры. Перед выполнением действий создайте резервную копию и по возможности протестируйте изменения в безопасной среде. Пользователь самостоятельно оценивает риски и несет ответственность за результат. При отсутствии необходимых знаний обратитесь к квалифицированному ИТ-специалисту.

LOCK_CONTENTION_WARNING IP-Телефония и СКУД

Asterisk: Excessive lock contention detected on channel lock

Обновлено: 24.08.2026 · Официальная документация ↗
  • В журнале появляется предупреждение: WARNING: asterisk.c: Excessive lock contention detected on channel lock.
  • Внезапные «заикания» и пропадание звука в разговорах (Audio Stuttering) при росте одновременных звонков.
  • Задержки при выполнении команд CLI и зависание интерфейсов AMI/ARI.
  • Высокое потребление процессора системными вызовами ядра (высокий %sys в top).

1. Анализ блокировок каналов в реальном времени

Проверьте количество каналов и очередей, удерживающих мьютексы:

asterisk -rx "core show channels verbose"
asterisk -rx "core show locks"

(Команда core show locks доступна только при сборке с флагом DEBUG_THREADS в menuselect).

2. Выявление тяжелых операций в диалплане

Избегайте выполнения синхронных дисковых и сетевых операций, пока канал удерживает блокировку (Channel Lock):

; ПЛОХО: Синхронный тяжелый запрос держит блокировку канала
exten => 200,1,Set(CURL_DATA=${CURL(http://api.crm.local/slow_lookup)})

; ХОРОШО: Использование неблокирующих AGI/ARI или оптимизация таймаутов
exten => 200,1,Set(CURLOPT(conntimeout)=1)
same => n,Set(CURLOPT(timeout)=2)
same => n,Set(CURL_DATA=${CURL(http://api.crm.local/fast_lookup)})

3. Оптимизация менеджера очередей в /etc/asterisk/queues.conf

Отключите избыточный расчет статистики для снижения нагрузки на мьютексы очередей:

[general]
monitor-type = MixMonitor
updatecdr = no
shared_lastcall = yes

[support_queue]
strategy = rrmemory
ringinuse = no
autopause = yes

4. Включение детектирования дедлоков в menuselect

При повторении проблемы скомпилируйте тестовый билд с отладкой мьютексов:

cd /usr/src/asterisk
menuselect/menuselect --enable DEBUG_THREADS --enable DETECT_DEADLOCKS menuselect.makeopts
make -j$(nproc) && make install
💡 Практика специалистов: Частая скрытая причина блокировок каналов — тяжелые запросы MySQL/PostgreSQL через модуль func_odbc. Всегда настраивайте connection timeout и пул коннектов в res_odbc.conf.

Частые вопросы (FAQ)

Что такое Lock Contention в Asterisk?

Это состояние высокой конкуренции потоков за доступ к единому ресурсу (структуре канала ast_channel или очереди), когда потоки тратят больше процессорного времени на ожидание освобождения мьютекса (futex wait), чем на полезную работу.

Как ringinuse = no помогает снизить Lock Contention?

Опция предотвращает отправку вызовов на уже занятых операторов, снижая частоту проверки состояния каналов (Device State) и блокировок структур очередей.

Чем опасен Lock Contention?

Он приводит к лавинообразному росту задержек обработки медиа-потоков RTP, рассинхронизации таймеров и полному зависанию PBX в дедлоке.

Как увидеть потоки, вызвавшие взаимную блокировку?

Снимите дамп потоков через gdb: gdb -p $(pgrep asterisk) -ex "thread apply all bt" -ex "detach" -ex "quit" > /tmp/locks_trace.txt.

Полезные материалы
Рекомендуем