← Назад к вопросам

Что будет с сервисом при перегрузке запросами?

2.0 Middle🔥 241 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что будет с сервисом при перегрузке запросами

При перегрузке запросами сервис может столкнуться с серьёзными проблемами, которые приводят к деградации или полному отказу в обслуживании. Важно понимать, какие именно ресурсы исчерпываются и как это влияет на систему.

Исчерпание потоков (Thread exhaustion)

Каждый входящий HTTP-запрос обычно обрабатывается отдельным потоком. В Java-сервисах есть ограничение на количество потоков:

// Tomcat по умолчанию имеет max-threads примерно 200
// Если все потоки заняты, новые запросы встают в очередь
// Когда очередь переполняется - запросы отклоняются с ошибкой 503

// Проблема: долгие операции блокируют потоки
long startTime = System.currentTimeMillis();
databaseCall();  // 5 сек
long duration = System.currentTimeMillis() - startTime;
// За это время один поток не может обработать другие запросы

Исчерпание памяти (Memory exhaustion)

Если каждый запрос создаёт объекты, при большом числе одновременных запросов память может исчерпаться:

// Опасный код при высокой нагрузке
@PostMapping("/process")
public String processRequest(String data) {
    // Если много одновременных запросов
    List<String> cachedData = new ArrayList<>();
    for (int i = 0; i < 1000000; i++) {
        cachedData.add(data);  // OutOfMemoryError при множественных запросах
    }
    return "OK";
}

Симптомы:

  • OutOfMemoryError: Java heap space
  • Garbage Collection паузы (stop the world)
  • Полный отказ приложения

Исчерпание подключений к БД (Connection pool exhaustion)

// HikariCP обычно имеет лимит примерно 10 подключений
DataSource dataSource = createDataSource();

@Service
public class UserService {
    public User getUser(Long id) {
        // Если 11 запросов одновременно запросят этот метод
        // 11-й запрос будет ждать освобождения соединения
        // или выбросит исключение SQLException
        return userRepository.findById(id);
    }
}

Каскадный отказ (Cascading failure)

Перегрузка одного сервиса может привести к отказу всей системы:

// Сервис A перегружен
// Сервис B пытается обратиться к A
// Но вместо отказа B ждёт ответа A
// Это блокирует потоки B
// Вскоре B тоже перегружен

@Service
public class BService {
    @Autowired
    private RestTemplate restTemplate;  // Нет timeout!
    
    public Data getData() {
        // Если A перегружен, этот вызов может зависнуть
        return restTemplate.getForObject("http://service-a/data", Data.class);
    }
}

Признаки перегрузки

  • Медленные ответы (latency растёт)
  • Timeouts
  • Ошибки 503 (Service Unavailable)
  • Ошибки 502 (Bad Gateway)
  • Logs наполняются ошибками
  • CPU/Memory в 100%
  • Невозможность подключиться по SSH

Как защитить сервис

Rate limiting (ограничение частоты запросов)

@Component
public class RateLimitingFilter extends OncePerRequestFilter {
    private final RateLimiter rateLimiter = RateLimiter.create(100);
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    FilterChain filterChain) throws Exception {
        if (!rateLimiter.tryAcquire()) {
            response.setStatus(429);  // Too Many Requests
            return;
        }
        filterChain.doFilter(request, response);
    }
}

Circuit Breaker (выключатель цепи)

@Service
public class UserService {
    @CircuitBreaker(name = "userServiceBreaker", fallbackMethod = "fallback")
    public User getUser(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    public User fallback(Long id, Exception e) {
        return User.cached(id);
    }
}

Таймауты и асинхронность

// С таймаутом
RestTemplate rt = new RestTemplate();
rt.setRequestFactory(new HttpComponentsClientHttpRequestFactory() {{
    setConnectTimeout(Duration.ofSeconds(2));
    setReadTimeout(Duration.ofSeconds(5));
}});

// Или асинхронно
@Async
public CompletableFuture<Data> getDataAsync(String url) {
    return CompletableFuture.supplyAsync(() -> 
        restTemplate.getForObject(url, Data.class)
    );
}

Connection pool optimization

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 20000

Резюме

При перегрузке сервис теряет потоки, память, подключения и перестаёт отвечать на запросы. Это влечёт отказ других сервисов. Защита: rate limiting, circuit breakers, таймауты, масштабирование и мониторинг.