Этот вопрос проверяет понимание стратегий обработки ошибок в распределенных системах и микросервисной архитектуре.
Обработка исключений в микросервисах требует единого подхода для всех сервисов. Используются глобальные обработчики исключений (@ControllerAdvice), стандартизированные форматы ошибок (Problem Details for HTTP APIs), корреляционные идентификаторы для отслеживания запросов через сервисы, и паттерны устойчивости (retry, circuit breaker). Важно различать бизнес-исключения и системные ошибки, обеспечивая понятные сообщения для клиентов.
Эффективная обработка исключений критически важна в микросервисной архитектуре для обеспечения надежности и отказоустойчивости.
Ключевые стратегии обработки исключений:
Единый формат ошибок:
Стандартизированный JSON-формат для всех сервисов
Пример структуры ответа об ошибке:
{
"correlationId": "123e4567-e89b-12d3-a456-426614174000",
"timestamp": "2023-10-01T12:00:00Z",
"status": 404,
"error": "Not Found",
"message": "User with id 123 not found",
"path": "/api/users/123"
}Глобальная обработка исключений:
Использование @ControllerAdvice для централизованной обработки
Пример реализации:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(EntityNotFoundException ex) {
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "Something went wrong");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}Корреляционные идентификаторы:
Сквозная идентификация запроса через все сервисы
Реализация через HTTP headers или MDC (Mapped Diagnostic Context)
Пример настройки фильтра:
@Component
public class CorrelationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
String correlationId = ((HttpServletRequest) request).getHeader("X-Correlation-ID");
if (correlationId == null) {
correlationId = UUID.randomUUID().toString();
}
MDC.put("correlationId", correlationId);
((HttpServletResponse) response).setHeader("X-Correlation-ID", correlationId);
chain.doFilter(request, response);
MDC.clear();
}
}Паттерны устойчивости:
Retry Pattern: Повтор запроса при временных ошибках
Circuit Breaker: Прекращение запросов при частых ошибках
Fallback: Альтернативная логика при недоступности сервиса
Пример:
@CircuitBreaker(name = "userService", fallbackMethod = "fallbackGetUser")
@Retry(name = "userService")
public User getUser(String userId) {
return userServiceClient.getUser(userId);
}
public User fallbackGetUser(String userId, Exception ex) {
return cachedUserService.getUser(userId);
}Классификация исключений:
Бизнес-исключения: Ошибки логики приложения (ValidationException, EntityNotFoundException)
Системные исключения: Технические ошибки (NetworkException, DatabaseException)
Клиентские ошибки: Некорректные запросы (400 Bad Request)
Вывод: Единый подход к обработке исключений с использованием стандартизированных форматов и паттернов устойчивости обеспечивает надежность микросервисной системы.