edge-redirect
edge-redirect - це єдиний сервіс Elido на шляху запиту публічного перенаправлення. Він працює в Hetzner FRA, Hetzner ASH та OVH SGP за Caddy і відповідає на кожен запит https://elido.me/<slug> статусом 302 на цільовий URL. Все інше - це “холодний шлях” (cold-path).
Ця сторінка описує логіку дизайну: що є в бінарному файлі, чого немає і чому бюджет затримки визначає реалізацію.
1. Бюджет затримки
| Етап | p50 | p95 | Примітки |
|---|---|---|---|
| TLS-рукостискання (тепле) | 0.5мс | 2мс | Відновлення сесії Caddy + TLS 1.3 |
| Anycast DNS + вхідний трафік на межі (edge ingress) | - | - | Обмежено мережею відвідувача |
| Пошук у кеші L1 | 0.2мс | 0.5мс | LRU всередині процесу, ristretto |
| Пошук у кеші L2 (при промаху L1) | 1.5мс | 3мс | Redis Cluster, той самий дата-центр |
| Отримання з джерела (при промаху L2) | 12мс | 30мс | gRPC до api-core, рідко |
| Обчислення правил смарт-лінків | 0.3мс | 1мс | Той самий процес, без додаткових вузлів |
| Запис відповіді + публікація кліку | 1мс | 3мс | redpanda працює за принципом “відправив і забув” |
| Загалом при попаданні в кеш | 5мс | 15мс | Без урахування TLS |
Показник 15мс p95 є жорстким. Усе, що виходить за ці межі - синхронне читання з БД, блокуючий I/O на події кліку, компіляція регулярних виразів (regex) на запит - безжально видаляється.
2. Що в бінарному файлі
Лише три важливі пакети:
internal/cache- клієнт L1 LRU + L2 Redis, ~600 рядків коду (LOC)internal/rules- обчислювач правил смарт-лінків, ~400 LOCinternal/redirect- обробник запитів + публікатор кліків, ~300 LOC
Плюс невеликий cmd/edge-redirect main та стандартна бібліотека. Бінарний файл займає 18МБ (stripped); холодний старт <200мс. Поступові перезапуски (rolling restarts) завершуються за 30 секунд по всьому кластеру.
3. Чого НЕМАЄ в бінарному файлі
За задумом, на “гарячому шляху” (hot path):
- Без SQL - Postgres знаходиться у джерелі на холодному шляху, він ніколи не використовується при попаданні в кеш.
- Без парсингу JSON на гарячому шляху - метадані посилання зберігаються в Redis у упакованому бінарному форматі (msgpack) і декодуються без виділення пам’яті (zero-allocation).
- Без компіляції регулярних виразів (regex) на кожен запит - регулярні вирази user-agent із правил смарт-лінків компілюються один раз під час завантаження посилання; скомпільовані матчери зберігаються у записі кешу.
- Без вихідного HTTP - кліки записуються в redpanda, а не в зовнішні пікселі. Розсилка по пікселях (fan out) виконується пізніше воркерами на холодному шляху.
- Без автентифікації - кінцева точка перенаправлення є публічною за визначенням. Єдине, що ми робимо - це обмеження швидкості (rate-limit) за IP через Caddy ще до того, як запит потрапить до нас.
Усе перелічене вище або працює у воркерах на холодному шляху, або не працює взагалі.
4. Архітектура кешу
Два рівні, обидва ліниві (lazy).
L1 - ristretto LRU на процес. ~50,000 записів за замовчуванням, TTL 60 секунд для посилань із правилами та 5 хвилин для звичайних. Різниця в TTL важлива, оскільки зміни правил мають поширюватися швидко; цілі звичайних посилань змінюються рідко.
L2 - Redis Cluster, один кластер на регіон. Ті самі TTL, але є авторитетним джерелом. При промаху L1 запит отримує дані з L2 і на зворотному шляху наповнює L1; при промаху L2 він переходить до api-core через gRPC, наповнює обидва рівні та повертає перенаправлення.
Інвалідація кешу - це публікація в канал Redis pub/sub (link:invalidate); кожна точка присутності (edge POP) підписана на нього і видаляє відповідні записи L1 протягом 1 секунди.
5. Публікація кліків
Кліки працюють за принципом “відправив і забув” у redpanda. Виклик публікації є async з точки зору обробника запиту - він додає подію в буфер кожного процесу і негайно повертає відповідь. Окрема goroutine очищає буфер кожні 100мс або після 1000 подій, залежно від того, що настане раніше.
Якщо redpanda недоступна, буфер заповнюється, і goroutine скидає надлишок у локальний WAL на диску. Коли redpanda відновлюється, WAL очищається. Ми допускаємо до 5 хвилин буферизованих кліків перед надсиланням сповіщення.
Це означає, що жоден клік не буде втрачено при збої redpanda в одному регіоні, а шлях перенаправлення не сповільнюється.
6. Правила смарт-лінків
Двигун правил є частиною того ж процесу - немає окремого “сервісу правил”, до якого треба звертатися. Обчислення правил додає <1мс навіть коли посилання має шість правил, тому що скомпільовані матчери знаходяться безпосередньо в записі кешу.
Перемагає перший збіг (First-match). Правило спрацьовує, коли всі його умови match є істинними (країни, пристрої, ОС, браузери, мови, часові вікна, реферер-хости). Правила обчислюються в порядку, встановленому в дашборді.
Якщо жодне правило не підходить, використовується default_destination_url посилання. Типове значення обов’язкове - смарт-лінк ніколи не повертає 404.
Див. Смарт-лінки для ознайомлення зі схемою правил та деталями їх створення.
7. Топологія розгортання
Три точки присутності (POP) станом на травень 2026 року:
- FRA (Франкфурт, Hetzner) - основний в ЄС
- ASH (Ешберн, Hetzner) - основний у США
- SGP (Сінгапур, OVH) - основний в APAC, регіон Business+
Кожен POP запускає 4-12 подів edge-redirect на bare metal (не віртуальні машини - бюджет затримки не витримує віртуалізацію на мережевому шляху). Caddy попереду обробляє термінацію TLS, Brotli та обмеження швидкості.
Anycast DNS (BGP через Hetzner + OVH) спрямовує відвідувачів до найближчого POP. Перемикання (failover) між POP відбувається автоматично через BGP withdraw; перемикання на основі DNS не використовується.
8. Що ми вимірюємо
Метрики, що мають значення:
elido_redirect_latency_seconds{cache="l1|l2|origin"}- розділено за шарами кешу, оскільки ці три групи абсолютно різніelido_redirect_requests_total{status,cache}- частота помилок + коефіцієнт попадання в кешelido_link_cache_size- підтримуйте коефіцієнт попадання в L1 вище 95% при стабільному трафікуelido_click_publish_lag_seconds- має бути близьким до нуля; сповіщення при >5с
Див. Спостережуваність для перегляду повного дашборду Grafana.
Див. також
- Смарт-лінки - що саме обчислює двигун правил
- Спостережуваність - метрики та трасування для гарячого шляху
- Self-hosting - Helm-чарт, який постачає edge-redirect для розгортання on-prem