MikroTik: script,error run failed: execution time limit exceeded
Архитектура интерпретатора скриптов RouterOS и ограничения выполнения
Начиная с RouterOS v7 (а также в ряде веток v6), встроенный планировщик задач (Scheduler) и обработчик сценариев (Scripting Engine) используют жесткие сторожевые таймеры (Watchdog Timers) для изоляции процессов управления от ядра маршрутизации. Событие script,error run failed: execution time limit exceeded возникает, когда синхронный скрипт превышает установленный квант процессорного времени (CPU Execution Quota / Script Timeout, по умолчанию от 20 до 120 секунд в зависимости от контекста вызова). Интерпретатор принудительно прерывает поток выполнения (Kill Thread), не сохраняя промежуточные переменные.
Бизнес-риски
Срыв регламентных сценариев: резервного копирования конфигураций (Backup/Export), обновления динамических списков блокировок (Address Lists / BGP Feeds), переключения резервных каналов провайдеров (Failover Scripts) и отправки телеметрии в Telegram/Zabbix.
Основные триггеры превышения лимита времени
| Операция | Причина зависания | Влияние на CPU |
|---|---|---|
/ip firewall address-list find | Линейный перебор таблицы из $> 50\,000$ записей без индексов. | 100% утилизация одного ядра CPU. |
:resolve domain.com | Опрос недоступного внешнего DNS-сервера с таймаутом до 10 секунд на итерацию. | Блокирующий I/O поток. |
Вложенные циклы :foreach | Алгоритмическая сложность $O(N^2)$ при обработке больших массивов строк. | Экспоненциальный рост времени работы. |
Регламент оптимизации скриптов RouterOS
Сценарий 1: Замена тяжелых операций find на прямые выборки
Использование find внутри циклических итераций перегружает стек памяти. Заменяйте перебор прямым обращением по имени или фильтрацией:
# ПЛОХО: Алгоритмический тупик на больших таблицах
:foreach i in=[/ip firewall address-list find where list="BLOCK_LIST"] do={
/ip firewall address-list remove $i
}
# ХОРОШО: Быстрое атомарное удаление через RouterOS CLI
/ip firewall address-list remove [find where list="BLOCK_LIST"]Сценарий 2: Оптимизация резолвинга DNS и обработки внешних вызовов
Всегда перехватывайте ошибки и задержки сетевых команд с помощью конструкции :do { ... } on-error={ ... }:
# Безопасный скрипт опроса с ограничением таймаута
:local targetHost "backup.corp.local"
:local resolvedIP ""
:do {
:set resolvedIP [:resolve $targetHost server=1.1.1.1]
} on-error={
:log warning ("[DNS-Timeout] Failed to resolve " . $targetHost)
}
:if ($resolvedIP != "") do={
:log info ("Host resolved: " . $resolvedIP)
}Сценарий 3: Фоновое выполнение долгих задач через Scheduler
Если скрипт обязан выполнять долгую работу (например, парсинг логов или выгрузку бэкапа на удаленный FTP), разделите его на асинхронные порции или запускайте без ожидания завершения консоли:
# Запуск скрипта в изолированной среде фонового планировщика
/system scheduler add name="NIGHTLY_ASYNC_TASK" interval=24h start-time=03:00:00 \
on-event="/system script run LongRunningProcess" policy=read,write,testТиповые ошибки администраторов
- Помещение :delay 60s внутри синхронных триггеров: Использование длительных пауз внутри скриптов DHCP-Lease или Netwatch блокирует родительский процесс и вызывает немедленный kill по таймауту.
- Запуск бесконечных циклов :while (true): Блокирует поток выполнения скриптового движка; регулярные задачи должны управляться исключительно через
/system scheduler.
Эксперты ITSTM проведут аудит кода RouterOS скриптов, перепишут логику переключения каналов и настроят стабильный мониторинг через REST API / SNMP.
Частые вопросы (FAQ)
Какой лимит времени выполнения скрипта по умолчанию в RouterOS v7?
Для интерактивных скриптов и триггеров системных событий (PPP On-Up, Netwatch, DHCP) жесткий таймаут составляет от 20 до 60 секунд. Задачи из Scheduler могут выполняться дольше, если не вызывают взаимоблокировок ядра.
Как узнать, на какой именно строке упал скрипт?
Включите расширенное логирование темы script: /system logging add topics=script,debug action=memory. Добавьте в код скрипта отладочные маркеры: :log debug ("Checkpoint 1 reached").
Влияет ли политика безопасности (Policies) на тайминги скрипта?
Напрямую нет, но если скрипт без политики 'sensitive' пытается прочитать пароли, он тратит время на безуспешные запросы к системной шине, после чего падает с ошибкой прав доступа.
Можно ли увеличить execution time limit в настройках RouterOS?
Нет, этот параметр жестко зашит в бинарный код ядра RouterOS для защиты маршрутизатора от зависания интерфейсов управления. Оптимизировать необходимо сам алгоритм скрипта.