Back to questions
Middle+
4
Как бы ты спроектировал сервис на 50k RPS с минимальной обработкой данных и отправкой на внешний API, с гарантией доставки и без дубликатов?
Companies where asked
Servicepipi
Answer from AI
sobes.tech AI
Для сервиса с нагрузкой 50k RPS, минимальной обработкой и отправкой на внешний API с гарантией доставки и без дубликатов, можно спроектировать архитектуру с учетом следующих аспектов:
-
Приём запросов и очередь
- Использовать высокопроизводительный HTTP-сервер (например, на Go с net/http или fasthttp).
- Принимать запросы и ставить задачи в очередь (например, в Redis, Kafka или внутреннюю очередь).
-
Обработка и отправка
- Пул воркеров, которые читают из очереди и отправляют запросы на внешний API.
- Реализовать retry с экспоненциальной задержкой при ошибках.
-
Гарантия доставки и отсутствие дубликатов
- Использовать уникальные идентификаторы сообщений (например, UUID) для идемпотентности.
- Внешний API должен поддерживать идемпотентные операции или сервис должен хранить статус отправленных сообщений.
- Хранить состояние доставки (например, в базе или кэше) для отслеживания успешных отправок.
-
Масштабируемость и отказоустойчивость
- Горизонтальное масштабирование сервиса и очереди.
- Мониторинг и алерты по задержкам и ошибкам.
Пример упрощённой схемы на Go:
// Приём запросов
http.HandleFunc("/event", func(w http.ResponseWriter, r *http.Request) {
id := r.Header.Get("X-Request-ID")
if id == "" {
id = generateUUID()
}
// Положить в очередь (например, Redis или канал)
enqueue(id, r.Body)
w.WriteHeader(http.StatusAccepted)
})
// Воркеры отправляют на внешний API с retry и проверкой идемпотентности
func worker() {
for task := range taskQueue {
if !isSent(task.id) {
err := sendToExternalAPI(task)
if err == nil {
markAsSent(task.id)
} else {
// retry logic
}
}
}
}
Таким образом достигается высокая пропускная способность, гарантия доставки и отсутствие дубликатов.