[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mikroservisy-chto-takoe-patterny-retry-i-timeout":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},911,"chto-takoe-patterny-retry-i-timeout",23,"mikroservisy","Микросервисы","🔗","Что такое паттерны Retry и Timeout?","Retry и Timeout — базовые паттерны отказоустойчивости при межсервисном взаимодействии. Timeout ограничивает время ожидания ответа, Retry автоматически повторяет запрос при transient-ошибках.\n\n### Timeout\n\nБез таймаута один зависший сервис может «повесить» всю цепочку вызовов.\n\n```java\n\u002F\u002F Таймаут через WebClient\nWebClient webClient = WebClient.builder()\n    .baseUrl(\"http:\u002F\u002Fcustomer-service\")\n    .clientConnector(new ReactorClientHttpConnector(\n        HttpClient.create()\n            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)\n            .responseTimeout(Duration.ofSeconds(5))\n    ))\n    .build();\n```\n\n### Retry\n\nАвтоматический повтор запроса при сбое. Повторять только идемпотентные операции и только при transient (временных) ошибках.\n\n\u003Cdetails>\u003Csummary>Resilience4j Retry\u003C\u002Fsummary>\n\n```java\n@Service\npublic class CustomerService {\n\n    @Retry(name = \"customerService\", fallbackMethod = \"getCustomerFallback\")\n    public CustomerDto getCustomer(Long id) {\n        return customerClient.getCustomer(id);\n    }\n\n    private CustomerDto getCustomerFallback(Long id, Exception e) {\n        log.warn(\"Все попытки вызова customer-service исчерпаны: {}\", e.getMessage());\n        return cachedCustomerRepository.findById(id)\n            .orElseThrow(() -> new ServiceUnavailableException(\"Customer service недоступен\"));\n    }\n}\n```\n\n```yaml\nresilience4j:\n  retry:\n    instances:\n      customerService:\n        max-attempts: 3\n        wait-duration: 500ms\n        exponential-backoff-multiplier: 2  # 500ms, 1s, 2s\n        retry-exceptions:\n          - java.io.IOException\n          - java.net.SocketTimeoutException\n          - org.springframework.web.client.HttpServerErrorException\n        ignore-exceptions:\n          - org.springframework.web.client.HttpClientErrorException  # 4xx — не повторять!\n```\n\n\u003C\u002Fdetails>\n\n### Exponential Backoff с Jitter\n\n```\nПопытка 1: ошибка → ждём 500ms + random(0-200ms)\nПопытка 2: ошибка → ждём 1000ms + random(0-400ms)\nПопытка 3: ошибка → ждём 2000ms + random(0-800ms)\nПопытка 4: ошибка → fallback\n```\n\nБез jitter все клиенты, получившие ошибку одновременно, будут повторять запросы в одно и то же время, создавая пиковую нагрузку («грозовое стадо»).\n\n\u003Cdetails>\u003Csummary>Spring Retry\u003C\u002Fsummary>\n\n```java\n@Configuration\n@EnableRetry\npublic class RetryConfig {}\n\n@Service\npublic class PaymentGatewayService {\n\n    @Retryable(\n        retryFor = {SocketTimeoutException.class, HttpServerErrorException.class},\n        noRetryFor = {HttpClientErrorException.class},\n        maxAttempts = 3,\n        backoff = @Backoff(delay = 1000, multiplier = 2, maxDelay = 10000)\n    )\n    public PaymentResult sendPayment(PaymentRequest request) {\n        return paymentGateway.execute(request);\n    }\n\n    @Recover\n    public PaymentResult recoverSendPayment(Exception e, PaymentRequest request) {\n        log.error(\"Платёжный шлюз недоступен после всех попыток: {}\", e.getMessage());\n        return PaymentResult.deferred(request.getId());\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### Комбинация паттернов (порядок имеет значение!)\n\n```\nЗапрос → Retry → CircuitBreaker → Timeout → Вызов сервиса\n```\n\n```yaml\nresilience4j:\n  retry:\n    instances:\n      paymentGateway:\n        max-attempts: 3\n        wait-duration: 500ms\n  circuitbreaker:\n    instances:\n      paymentGateway:\n        failure-rate-threshold: 50\n        wait-duration-in-open-state: 30s\n  timelimiter:\n    instances:\n      paymentGateway:\n        timeout-duration: 5s\n```\n\n> **На собеседовании:** обязательно упомяните exponential backoff с jitter — это показывает понимание реальных проблем. Ключевое правило: retry только для идемпотентных операций и только для 5xx, не для 4xx. Частая ошибка — ретраить бизнес-ошибки (400 Bad Request).","","middle",[15],"microservices",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":23,"featuredSnippetReady":24},"Что такое паттерны Retry и Timeout? — Gymterview","Retry и Timeout — базовые паттерны отказоустойчивости при межсервисном взаимодействии. Timeout ограничивает время ожидания ответа, Retry автоматически повторяет","Retry и Timeout — базовые паттерны отказоустойчивости при межсервисном взаимодействии. Timeout ограничивает время ожидан",[15,13],"Retry и Timeout — базовые паттерны отказоустойчивости при межсервисном взаимодействии. Timeout ограничивает время ожидания ответа, Retry автоматически повторяет запрос при transient-ошибках.",true]