← На главную Портфолио
🏆 Production-кейс · Self-Healing · Atomic RPC · 2026

Автономная платформа восстановления workflow

Система с атомарным PostgreSQL RPC, exponential backoff с jitter, circuit breaker и дедупликацией алертов. Zero race conditions, zero duplicate alerts, 100% observability.

90%
Меньше ручных перезапусков
<3 мин
Полный цикл автовосстановления
24/7
Автономная работа
0 ₽
Self-hosted, без подписок
ЗадачаProduction-workflow падали из-за таймаутов и rate limit'ов. Каждый сбой требовал ручного перезапуска.
Моя работаРазработал self-healing платформу: атомарный RPC (PostgreSQL), exponential backoff с jitter, circuit breaker, дедупликация алертов.
Технологииn8n 2.27.3, Supabase (PostgreSQL + PostgREST), Telegram Bot API, Grafana, Docker/Dokploy
Результат90% меньше ручных перезапусков, <3 мин восстановление, 0 race conditions

Когда автоматизация ломается молча

Production-сценарии периодически падали из-за внешних факторов: таймауты API, rate limit'ы, сетевые сбои. Каждая ошибка требовала ручного вмешательства. При параллельных запусках возникали race conditions и дублирующие алерты.

🔥

Тихие падения

Workflow падали без оповещений. Команды обнаруживали проблемы спустя часы.

Ручное восстановление

Каждый упавший сценарий перезапускался вручную — не масштабируемая рутина.

🎯

Race conditions

Параллельные Error Handler'ы создавали дубликаты записей и множественные алерты.

📊

Отсутствие наблюдаемости

Не было единой картины: какие workflow падают, какие ошибки повторяются.

Атомарный state machine на PostgreSQL RPC

Каждая retry-сессия — атомарная операция через PostgreSQL RPC-функцию. Никаких race conditions: UPSERT + инкремент выполняются в одной транзакции.

🥊Workflow падает
🔧Global Error Handler
Retryable?
Atomic RPC UPSERT
Exponential Backoff
🔄Restart
Схема workflow в n8n
Полная схема Global Error Handler: от детекции ошибки до атомарного UPSERT через PostgreSQL RPC
Скриншот: n8n workflow canvas

Production-ready решения

Классические паттерны из мира распределённых систем, адаптированные под low-code.

ATOMICITY

⚡ PostgreSQL RPC UPSERT

Атомарная функция increment_retry_session() выполняет SELECT + UPDATE + инкремент в одной транзакции. Zero race conditions даже при 100+ параллельных запросах.

INSERT ... ON CONFLICT DO UPDATE RETURNING attempt_number INTO v_new_attempt;
DEDUPLICATION

🛑 Smart Alert Flag

Флаг should_send_alert через PostgreSQL FOUND гарантирует: только первый Handler, достигший лимита, отправит Telegram-алерт. Остальные — просто логируют.

UPDATE ... WHERE status = 'retrying'; v_should_send_alert := FOUND;
INTELLIGENCE

🔐 5-min Window + FNV-1a Hash

Детерминированный retry_session_id = workflow_id-YYYY-MM-DD-HH-MM-hash группирует одинаковые ошибки в одну сессию. FNV-1a hash — чистый JS, без модулей.

session = workflow_id-2026-06-17-08-15-ab72daab
RELIABILITY

📈 Exponential Backoff + Jitter

Растущие задержки (30с → 60с → 120с) плюс random(0-10с) защищают восстанавливающийся сервис от thundering herd.

delay = min(30 × 2^attempt + random(10), 3600)

Атомарная RPC-функция PostgreSQL

Вся логика retry-сессии выполняется в одной SQL-функции. Никаких промежуточных SELECT/INSERT — только атомарный UPSERT.

-- Атомарный инкремент retry-сессии CREATE OR REPLACE FUNCTION increment_retry_session(...) RETURNS JSON AS $$ DECLARE v_new_attempt INTEGER; v_delay INTEGER; v_should_retry BOOLEAN; v_should_send_alert BOOLEAN := false; BEGIN -- 1. Проверяем текущее состояние SELECT attempt_number, status INTO v_current_attempt, v_current_status FROM workflow_retries WHERE retry_session_id = p_session_id; -- 2. Если лимит достигнут - НЕ инкрементируем IF v_current_attempt >= p_max_attempts THEN RETURN json_build_object(..., 'should_send_alert', false); END IF; -- 3. Атомарный UPSERT с инкрементом INSERT INTO workflow_retries (...) ON CONFLICT (retry_session_id) DO UPDATE SET attempt_number = workflow_retries.attempt_number + 1, ... RETURNING attempt_number INTO v_new_attempt; -- 4. Вычисляем backoff с jitter v_delay := LEAST(30 * POWER(2, v_new_attempt - 1) + (RANDOM() * 10)::INTEGER, 3600); -- 5. КРИТИЧНО: только первый Handler меняет статус на 'failed' IF NOT v_should_retry THEN UPDATE workflow_retries SET status = 'failed' WHERE retry_session_id = p_session_id AND status = 'retrying'; v_should_send_alert := FOUND; -- PostgreSQL magic! END IF; RETURN json_build_object( 'attempt_number', v_new_attempt, 'should_retry', v_should_retry, 'should_send_alert', v_should_send_alert, ← ключевой флаг! ... ); END; $$ LANGUAGE plpgsql;
Таблица workflow_retries
Таблица workflow_retries: одна запись на сессию, attempt_number растёт атомарно
Скриншот: Supabase Table Editor

От прототипа до production за одну сессию

Шесть этапов. На каждом решалась конкретная инженерная проблема. Финальный результат: zero race conditions, zero duplicate alerts.

Этап 1 · Фундамент

🏗 Self-hosted инфраструктура

n8n, Supabase, Grafana на VPS через Dokploy. Traefik + Let's Encrypt SSL.

Этап 2 · Ядро

🔧 Global Error Handler

Централизованный обработчик ошибок с классификацией retryable/non-retryable.

Этап 3 · State

🗄 Атомарная RPC-функция

PostgreSQL UPSERT с инкрементом attempt_number в одной транзакции. Zero race conditions.

Этап 4 · Интеллект

🧠 FNV-1a Hash + 5-min Window

Детерминированный session_id группирует одинаковые ошибки. Чистый JS, без модулей.

Этап 5 · Deduplication

🛑 should_send_alert Flag

PostgreSQL FOUND гарантирует: только первый Handler отправит алерт. Zero duplicate alerts.

Этап 6 · Валидация

✅ Parallel-тест: 5 запросов → 1 алерт

5 параллельных webhook'ов → одна запись с attempt:3 → один Telegram-алерт. Production-ready.

Измеримые результаты

90%
Меньше ручных перезапусков
<3 мин
Полный цикл восстановления
0
Race conditions
1
Алерт на сессию (не 5!)
Telegram-алерт
Финальный алерт: все 3 попытки исчерпаны, указана причина и execution URL
Скриншот: Telegram-чат

Четыре вывода для production

Технические решения, которые превратили прототип в надёжную систему.

⚡ Атомарность > IF-цепочки

Одна RPC-функция с UPSERT надёжнее, чем SELECT → Calculate → INSERT. PostgreSQL гарантирует сериализацию.

🛑 FOUND — PostgreSQL magic

Переменная FOUND после UPDATE возвращает true, если строка была изменена. Идеально для дедупликации алертов.

🔐 FNV-1a > crypto

Детерминированный hash на чистом JS без модулей. Быстрее, безопаснее, работает в n8n task runner.

📊 5-min окно > часовое

Более точная группировка: разные сбои в одном часе не сливаются в одну сессию.

🎯 should_send_alert флаг

Передаём флаг из SQL в n8n → IF-нода решает, слать алерт или нет. Чистая архитектура.

🧪 Parallel-тест — must-have

Только 5 параллельных запросов покажут, есть ли race conditions. Без этого — не production.

Self-hosted production stack

Только open-source. Полный контроль над данными, нулевые ежемесячные платежи.

n8n

Оркестрация workflow

🗄

Supabase

PostgreSQL + PostgREST RPC

📊

Grafana

Мониторинг и дашборды

📱

Telegram Bot

Real-time алерты

🚀

Dokploy

Платформа деплоя

🔒

Traefik

Reverse proxy + SSL

🐳

Docker

Контейнеризация

☁️

VPS

Self-hosted инфраструктура

Нужна такая же система?

Соберу production-grade self-healing платформу под ваши workflow за 1-2 недели. С полной документацией, дашбордами и обучением команды.

Обсудить проект →