> Как масштабировать сервис коротких ссылок и настроить балансировку нагрузки (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: amoCRM

Стек: Go

> Пример ответа

Для масштабирования сервиса коротких ссылок на Go и настройки балансировки нагрузки можно применить следующий подход.

Архитектура:

  • Используем горизонтальное масштабирование: несколько экземпляров Go-сервиса (например, с фреймворком Gin или Echo) за балансировщиком (NGINX, HAProxy или облачный ALB).
  • Для хранения ссылок применяем распределённое хранилище: Redis Cluster (для кэша и быстрых редиректов) + PostgreSQL с шардированием (например, по хешу короткого кода) или CockroachDB для автоматического шардирования.
  • Генерация коротких кодов: используем уникальные идентификаторы (например, Snowflake или base62-кодирование от счётчика в Redis) для избежания коллизий.

Балансировка нагрузки:

  • Настраиваем round-robin или least-connections на NGINX. Пример конфигурации:
upstream shortlink_backend {
    least_conn;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}
server {
    listen 80;
    location / {
        proxy_pass http://shortlink_backend;
    }
}
  • Для stateless-сервиса (все состояния в Redis/БД) это работает идеально.

Go-код (фрагмент):

GO
package main
import (
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
)
var rdb *redis.ClusterClient
func redirectHandler(c *gin.Context) {
code := c.Param("code")
longURL, err := rdb.Get(c.Request.Context(), code).Result()
if err != nil {
c.String(404, "Not found")
return
}
c.Redirect(302, longURL)
}
func main() {
rdb = redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"redis-node1:6379", "redis-node2:6379"},
})
r := gin.Default()
r.GET("/:code", redirectHandler)
r.Run(":8080")
}

Дополнительно:

  • Кэшируем популярные ссылки в локальном кэше (например, bigcache) для снижения нагрузки на Redis.
  • Используем health checks в балансировщике для автоматического исключения упавших инстансов.
  • Для записи ссылок применяем очередь (Kafka/NATS) и асинхронную запись в БД, чтобы не блокировать API.

Этот подход обеспечивает отказоустойчивость и линейное масштабирование при росте нагрузки.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью