Настройка автоматического перезапуска торгового бота

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Настройка автоматического перезапуска торгового бота
Простой
~1 день
Часто задаваемые вопросы

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

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1286
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    902
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1122
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    859

Настройка автоматического перезапуска торгового бота

Торговый бот должен работать 24/7. Процесс падает — из-за сетевой ошибки, OOM, необработанного исключения или просто системного перезапуска. Без автоматического перезапуска бот лежит до тех пор, пока кто-то не заметит. Правильная настройка — это не просто "restart always", это ещё и проверка состояния, graceful shutdown и алерты.

systemd: production-стандарт на Linux

systemd — правильный инструмент для управления долгоживущими сервисами на Linux. Поддерживает автоматический перезапуск, зависимости между сервисами, лимиты ресурсов, ротацию логов.

# /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
# Ждать 10 секунд перед перезапуском (не спамить при быстрых падениях)
RestartSec=10
# Если бот падает быстрее 5 раз за 60 секунд — остановить (что-то серьёзно не так)
StartLimitIntervalSec=60
StartLimitBurst=5

# Переменные окружения
EnvironmentFile=/opt/trading-bot/.env

# Лимиты ресурсов
MemoryLimit=2G
CPUQuota=80%

# Логирование через journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=trading-bot

[Install]
WantedBy=multi-user.target

Активация и управление:

systemctl daemon-reload
systemctl enable trading-bot  # автозапуск при старте системы
systemctl start trading-bot
systemctl status trading-bot
journalctl -u trading-bot -f   # live логи

StartLimitBurst=5 + StartLimitIntervalSec=60 — важная защита. Без неё бот в crash loop будет непрерывно перезапускаться, накапливая ошибки (открытые позиции, дублирующиеся ордера). После 5 быстрых падений 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)  # backoff перед следующей итерацией

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

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

Если бот запускается в 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

restart: unless-stopped — перезапускает при падении и при перезагрузке хоста, но не перезапускает если остановлен вручную через docker-compose stop.

Health check — критически важен. Docker перезапускает контейнер только если он полностью упал. Если бот завис (hanging без ошибки) — Docker этого не заметит. Health check endpoint должен проверять не просто "процесс жив", а реальное состояние:

from aiohttp import web

async def health_check(request):
    # Проверяем что последний цикл был не больше 5 минут назад
    last_loop_age = time.time() - bot.last_loop_time
    if last_loop_age > 300:  # 5 минут
        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 → Telegram:

# /etc/systemd/system/trading-bot-notify.service
[Unit]
Description=Notify on trading bot failure

[Service]
Type=oneshot
ExecStart=/opt/scripts/notify-telegram.sh "Trading bot restarted on $(hostname)"
# В trading-bot.service добавить:
OnFailure=trading-bot-notify.service

Prometheus Alertmanager для более сложных сценариев:

# alert rule
- alert: TradingBotRestarted
  expr: changes(process_start_time_seconds{job="trading-bot"}[5m]) > 0
  annotations:
    summary: "Trading bot restarted {{ $value }} times in last 5 minutes"

Разумный минимум: Telegram-уведомление при каждом (пере)запуске с именем хоста и временем. Достаточно для 95% случаев.