← Все проекты

Кейс · Go-бэкенд

Шлюз: API-gateway

API-шлюз на чистой stdlib: маршруты по хосту/префиксу из JSON-конфига с горячей перезагрузкой без обрыва соединений, балансировка round-robin и least-conn, health-checks, circuit breaker на узел, ретраи идемпотентных запросов, rate limit, хэшированные API-ключи, метрики Prometheus, живой дашборд на SSE.

  • Go
  • stdlib only
  • Reverse proxy
  • Circuit breaker
  • Token bucket
  • SSE
  • Prometheus
  • slog
  • Vanilla JS
  • embed
  • Docker
  • GitHub Actions

01 · Как выглядит

Скриншоты

Скриншот проекта «Шлюз: API-gateway» на экране 1280 пикселей
Десктоп, 1280 px
Скриншот проекта «Шлюз: API-gateway» на экране телефона, 390 пикселей
Телефон, 390 px

02 · О проекте

Что это и зачем

API-шлюз (обратный прокси) на чистой стандартной библиотеке Go: ни одной внешней зависимости. Маршруты по хосту и префиксу описываются JSON-конфигом, который перезагружается на лету без обрыва соединений.

За маршрутом стоит апстрим с несколькими узлами: балансировка round-robin или least-conn, health-checks, circuit breaker на каждый узел, ретраи идемпотентных запросов. Сверху rate limit, хэшированные API-ключи, метрики Prometheus и живой дашборд на SSE.

В демо-режиме внутри процесса поднимаются три фейковых апстрима и синтетический генератор трафика, который ходит через настоящий шлюз. Это не реальные сервисы и не реальная нагрузка.

Ограничения

Состояние rate limit и circuit breaker живёт в памяти одного процесса: при нескольких репликах лимиты не общие. Нет TLS на входе, счётчики не сохраняются при перезапуске.

WebSocket и Upgrade не поддерживаются (501); HTTP/2 к апстримам и gRPC не проверялись. SIGHUP работает только на Unix, на Windows есть POST /api/reload.

Перцентили считаются по гистограмме с шагом ×1,25, погрешность до 25% вверх. Админка с одним токеном, без ролей и аудита.

Демо-ключ demo-key-not-a-secret публичен. Цифра о нагрузке получена на одной машине и не является бенчмарком.

Что внутри

  • Маршрутизация по хосту и самому длинному префиксу; неизвестный маршрут даёт 404, шлюз не open-proxy (адрес назначения берётся только из конфига)
  • Горячая перезагрузка: состояние неизменяемо и подменяется одним atomic.Pointer, слушающий сокет не трогается, ошибочный конфиг отклоняется целиком
  • Балансировка round-robin и least-conn только по узлам в состоянии healthy; health-loop на каждый узел
  • Circuit breaker на каждый узел (closed, open, half-open) и ретраи на другой узел для идемпотентных методов, тело буферизуется до 1 МиБ
  • Защита от SSRF: адреса апстримов проверяются при загрузке и ещё раз в момент соединения (DNS-rebinding)
  • Rate limit по token bucket (по IP или ключу), API-ключи хранятся как sha256, метрики Prometheus и дашборд на SSE на ванильном JS
  • Нагрузочный тест в наборе тестов: 4000 запросов, 40 клиентов, порядка 12000 запросов в секунду (демо-замер на одной машине, не бенчмарк)
  • Docker и GitHub Actions (go test -race в CI)

03 · Как запустить

Запуск одной командой

git clone <репозиторий по запросу> api-gateway
cd api-gateway
SEED_DEMO=1 go run ./cmd/gateway   # прокси :8087, дашборд http://127.0.0.1:8088
go run ./cmd/gateway -genkey   # новый API-ключ и его sha256

04 · Код

Репозиторий приватный

Исходники лежат в приватном репозитории. Открою доступ по запросу: напишите, и пришлю приглашение.

Запросить код