> Как масштабировать сервис коротких ссылок и настроить балансировку нагрузки (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-код (фрагмент):
GOpackage mainimport ("github.com/gin-gonic/gin""github.com/go-redis/redis/v8")var rdb *redis.ClusterClientfunc 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.
Этот подход обеспечивает отказоустойчивость и линейное масштабирование при росте нагрузки.
> Похожие задачи по Go
Подходит ли слайс в Go для хранения и частого увеличения массива событий
Как реализовать TTL кэш на Redis без использования таблиц
Что такое starvation локальной очереди и когда она возникает
Как происходит балансировка нагрузки в планировщике Go
> Похожие задачи по backend
Подходит ли слайс в Go для хранения и частого увеличения массива событий
Как реализовать TTL кэш на Redis без использования таблиц
Что происходит, если по userId пользователь не найден?
Работал ли ты с Cassandra, MongoDB, Redis, ElasticSearch, ClickHouse
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью