Автоперезапуск торгового бота: systemd, Docker, алерти

Налаштування автоматичного перезапуску торгового бота Торговий бот працює 24/7. Збій через мережеву помилку, OOM, необроблене виключення або оновлення системи — і процес падає. Без автоперезапуску бот залишається мертвим, поки не втрутиться оператор. Чим довший простій, тим більше втрачений прибу

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1004
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1270
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1011

Налаштування автоматичного перезапуску торгового бота

Торговий бот працює 24/7. Збій через мережеву помилку, OOM, необроблене виключення або оновлення системи — і процес падає. Без автоперезапуску бот залишається мертвим, поки не втрутиться оператор. Чим довший простій, тим більше втрачений прибуток і ризик пропустити торгові сигнали. У production ми досягаємо uptime 99.9% завдяки зв'язці systemd, graceful shutdown та алертів. Розкажу, як це налаштувати, на прикладі реального проекту: бот на Python з aiohttp, що працює на Ubuntu 22.04 з 4 ядрами. Ми використовуємо systemd для керування, Docker для ізоляції та Prometheus для моніторингу.

systemd — стандартний менеджер сервісів у Linux. Він вміє автоматично перезапускати процес, обмежувати ресурси та логувати. Але одного налаштування Restart=always недостатньо — потрібен захист від crash loop. Розглянемо три ключові компоненти: systemd unit, graceful shutdown у коді бота та алерти при збоях. Для контейнеризованих ботів доповнимо Docker restart policy та health check.

Як налаштувати systemd для автоматичного перезапуску?

Створіть unit-файл у /etc/systemd/system/ з параметрами Restart=always та RestartSec=10. Додатково вкажіть StartLimitBurst=5 і StartLimitIntervalSec=60, щоб уникнути нескінченного перезапуску при критичній помилці. Активуйте сервіс: systemctl enable trading-bot.

# /etc/systemd/system/trading-bot.service [Unit] Description=Trading Bot After=network-online.target Wants=network-online.target [Service] Type=simple User=botuser WorkingDirectory=/opt/trading-bot ExecStart=/opt/trading-bot/venv/bin/python -u bot.py Restart=always RestartSec=10 StartLimitIntervalSec=60 StartLimitBurst=5 EnvironmentFile=/opt/trading-bot/.env MemoryLimit=2G CPUQuota=80% StandardOutput=journal StandardError=journal SyslogIdentifier=trading-bot [Install] WantedBy=multi-user.target 

Активація:

systemctl daemon-reload systemctl enable trading-bot systemctl start trading-bot journalctl -u trading-bot -f # live логи 

Параметр StartLimitBurst=5 + StartLimitIntervalSec=60 — захист від crash loop. Без нього бот при постійних падіннях буде безперервно перезапускатися, накопичуючи помилки (відкриті позиції, дублюючі ордери). Після 5 швидких падінь systemd зупинить службу та надішле алерт (якщо налаштовано). Це в 5 разів надійніше, ніж простий cron-моніторинг.

Параметри systemd unit: детальний розбір

Параметр Опис Приклад
Restart Політика перезапуску always
RestartSec Пауза між рестартами 10
StartLimitBurst Ліміт швидких перезапусків 5
StartLimitIntervalSec Інтервал для ліміту 60
MemoryLimit Обмеження пам'яті 2G
CPUQuota Квоти CPU 80%

Ці параметри підвищують стабільність: бот не падає через перевантаження, а при частих помилках systemd блокує запуск, запобігаючи втраті коштів через подвійні ордери.

Що таке graceful shutdown і для чого він потрібен?

Бота не можна вбивати SIGKILL — можна залишити відкриті ордери, незафіксовані позиції, невідправлені алерти. Обробляємо SIGTERM:

import signal import asyncio class TradingBot: def __init__(self): self.running = True self.open_orders: list = [] async def shutdown(self): self.running = False for order_id in self.open_orders: try: await self.exchange.cancel_order(order_id) except Exception as e: logger.error(f"Failed to cancel order {order_id}: {e}") logger.info("Graceful shutdown complete") async def run(self): loop = asyncio.get_event_loop() loop.add_signal_handler( signal.SIGTERM, lambda: asyncio.create_task(self.shutdown()) ) while self.running: try: await self.main_loop() except Exception as e: logger.exception(f"Error in main loop: {e}") await asyncio.sleep(5) 

systemd при systemctl stop надсилає SIGTERM, потім через TimeoutStopSec (default 90 сек) — SIGKILL. Для бота з позиціями 90 секунд зазвичай достатньо.

Docker: альтернатива для контейнеризованих ботів

Якщо бот запускається в Docker, використовуйте restart: unless-stopped — він перезапускає при падінні та при перезавантаженні хоста, але не при ручному зупиненні. Health check критично важливий: Docker перезапускає контейнер лише при повному падінні, а зависання без помилки не помітить.

# docker-compose.yml services: trading-bot: image: trading-bot:latest restart: unless-stopped env_file: .env volumes: - ./data:/app/data - ./logs:/app/logs mem_limit: 2g logging: driver: "json-file" options: max-size: "100m" max-file: "5" healthcheck: test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8080/health', timeout=5)"] interval: 30s timeout: 10s retries: 3 start_period: 60s 

Приклад health-ендпоінта на aiohttp:

from aiohttp import web async def health_check(request): last_loop_age = time.time() - bot.last_loop_time if last_loop_age > 300: return web.Response(status=503, text=f"Bot stuck: last loop {last_loop_age:.0f}s ago") if not bot.exchange_connected: return web.Response(status=503, text="Exchange disconnected") return web.Response(status=200, text="OK") app = web.Application() app.router.add_get('/health', health_check) 

Порівняння systemd та Docker для автоперезапуску

Параметр systemd Docker
Механізм перезапуску systemd unit restart policy
Захист від crash loop StartLimitBurst + Interval Немає вбудованого (тільки health)
Graceful shutdown SIGTERM + TimeoutStopSec SIGTERM + stop_grace_period
Моніторинг зависань Немає вбудованого Health check
Рекомендація Для власних Linux‑серверів Для контейнеризованої інфраструктури

Чому потрібні алерти при падінні?

Сам факт перезапуску повинен генерувати сповіщення — навіть якщо бот відновився автоматично. Мінімальне рішення — Telegram-бот з ім'ям хоста та часом. У systemd це робиться через OnFailure=trading-bot-notify.service. Для Prometheus: правило changes(process_start_time_seconds{job="trading-bot"}[5m]) > 0. Отримайте консультацію з налаштування алертів — підкажемо оптимальне рішення для вашої інфраструктури.

Що входить у налаштування автоматичного перезапуску (deliverables)

  • Конфігурація systemd unit або Docker compose з захистом від crash loop
  • Реалізація graceful shutdown з обробкою відкритих ордерів
  • Health check endpoint з перевіркою стану бота та біржі
  • Налаштування алертів (Telegram / Slack) при падінні та частих рестартах
  • Тестування на staging-оточенні до виходу в production
  • Документація конфігурації та інструкція для вашої команди
  • 5+ років досвіду в блокчейн-розробці — гарантуємо стабільність
Приклад crash loop та його наслідки

Якщо бот падає кожні 5 секунд через помилку підключення до біржі, без StartLimitBurst systemd буде перезапускати його нескінченно. Кожен запуск може спробувати скасувати ордери або створити нові, що призведе до подвійних позицій. З StartLimitBurst=5 після п'ятої спроби systemd зупинить сервіс, і ви отримаєте алерт. Це врятує від фінансових втрат.

Замовте налаштування торгового бота в компанії наша команда — ми забезпечимо стабільну роботу 24/7. Отримайте консультацію з конфігурації systemd, Docker та алертів.