μλ‘
HTTP μμ²μ λ€νΈμν¬ μ§μ°, μΌμμ μΈ μλ² μ€λ₯, μλͺ»λ μμ² λ± λ€μν μ΄μ λ‘ μ€ν¨ν μ μμ΅λλ€. μ΄λ° κ²½μ° μ ν리μΌμ΄μ μ μ€ν νλ¦μ λ¬Έμ λ₯Ό μΌμΌν¬ μ μκΈ°μ μλ¬λ₯Ό μ¬λ°λ₯΄κ² μ²λ¦¬ν΄μΌ ν©λλ€.
μ΄λ² κΈμμλ WebClientλ₯Ό μ¬μ©μ HTTPμμ² κ³Όμ μμ λ°μν μλ¬λ₯Ό μ²λ¦¬νλ λ°©λ²κ³Ό 볡ꡬνκΈ° μν΄ μ¬μλ μ²λ¦¬νλ μ λ΅μ λν΄ μ λ¦¬ν΄ λ³΄κ² μ΅λλ€.
μλ¬ μ²λ¦¬
onErrorReturn()
onErrorReturn()μ μλ¬κ° λ°μνμ λ μ£Όμ΄μ§ default κ°μ λ°ννλ λ©μλμ λλ€. μ΄λ λΉλκΈ° ν΅μ μμ μ€μν μν μ νλλ°, νΉν λ€νΈμν¬ μ€λ₯ λλ μλ²μ λ¬Έμ λ‘ μΈν μλ¬κ° λ°μνμ λ ν΅μ μ체λ₯Ό μ€λ¨μν€μ§ μκ³ , λν΄νΈ κ°μ λ°ννμ¬ μ μμ μΌλ‘ κ³μ μλν μ μλλ‘ ν μ μκΈ° λλ¬Έμ λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.just(new CustomClientException()))
.onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.just(new CustomServerException()))
.bodyToMono(String.class)
.onErrorReturn("Default Value")
.subscribe(System.out::println);
μ μ½λμμλ 4xx ν΄λΌμ΄μΈνΈ μλ¬λ 5xx μλ² μλ¬κ° λ°μνμ κ²½μ°μλ μ¬μ©μκ° μ μν μμΈλ₯Ό λ°νν©λλ€. κ·Έλ¦¬κ³ onErrorReturn()μ μ¬μ©νμ¬ μμΈλ₯Ό λ°ννλ λμ μ΅μ’ μ μΌλ‘ default κ°μ λ°ννλλ‘ μ€μ λ©λλ€. μ΄λ₯Ό ν΅ν΄ μλ¬κ° λ°μν΄λ λ°μ΄ν° νλ¦μ΄ μ€λ¨λμ§ μκ³ μ§μ λ "Default Value"λΌλ κ°μ΄ λ°νλμ΄ νμ μ²λ¦¬κ° κ°λ₯ν©λλ€.
onErrorResume()
onErrorResume()λ μλ¬ λ°μ μ λ체ν μ μλ μλ‘μ΄ λ°μ΄ν° μ€νΈλ¦Όμ μ 곡νλ λ©μλμ λλ€. onErrorReturn()μ λΉμ·νμ§λ§, λ μΌλ°μ μΈ λ°©λ²μΌλ‘ μλ¬λ₯Ό μ²λ¦¬ν©λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.onErrorResume(e -> {
log.error("Error: ", e);
return Mono.just("Fallback");
})
.subscribe(System.out::println);
μμ μ½λμμ onErrorResume()μ onErrorReturn()κ³Ό λ¬λ¦¬ μλ‘μ΄ Monoλ₯Ό μμ±νκ³ "Fallback"μ΄λΌλ κ°μ λ°νν©λλ€. μ΄ κ²½μ°, μλμ Monoμμ μλ¬κ° λ°μνλ©΄ onErrorResume()μ μν΄ μλ‘μ΄ Monoλ‘ κ΅μ²΄λκ³ , "Fallback" κ°μ λ°ννκ² λ©λλ€.
doOnError()
doOnError()λ μλ¬κ° λ°μνμ λ μΆκ°μ μΈ λ‘μ§μ μννλλ‘ ν©λλ€. μ΄ λ°©λ²μ μ¬μ©νλ©΄ μλ¬κ° λ°μνλ©΄μλ λͺ μμ μΌλ‘ μλ¬λ₯Ό μ²λ¦¬νμ§ μκ³ λμ± κ΅¬μ²΄μ μΈ λ‘μ§μ μνν μ μμ΅λλ€. μλ₯Ό λ€μ΄, μλ¬κ° λ°μν λλ§λ€ μΉ΄μ΄ν°λ₯Ό μ¦κ°μν€κ±°λ λ‘κ·Έλ₯Ό μΆλ ₯νλ λ±μ μμ μ μνν μ μμ΅λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.doOnError(e -> {
log.error("Error occurred: ", e);
errorCounter.incrementAndGet();
})
.subscribe(System.out::println);
μ μ½λμμ, doOnError()λ μλ¬κ° λ°μνμ λ λ‘κ·Έλ₯Ό μΆλ ₯νκ³ μλ¬ μΉ΄μ΄ν°λ₯Ό μ¦κ°μν΅λλ€. κ·Έλ¬λ μ΄ κ²½μ°μλ onErrorReturn()μ΄λ onErrorResume()μ²λΌ μλ¬λ₯Ό μ²λ¦¬νκ±°λ μλ‘μ΄ μ€νΈλ¦ΌμΌλ‘ κ΅μ²΄λ νμ§ μμ΅λλ€.
onErrorMap()
onErrorMap()μ μλμ μμΈλ₯Ό λ€λ₯Έ μμΈλ‘ λ³ννλ λ° μ¬μ©λ©λλ€. μ΄λ λ€μν νμ μ μμΈλ₯Ό νΉμ μμΈλ‘ 맀ννμ¬, μμ λ 벨μμ μΌκ΄λ μμΈ μ²λ¦¬λ₯Ό ν μ μλλ‘ ν©λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.onErrorMap(original -> new CustomException("Something went wrong", original))
.subscribe(System.out::println);
μ μ½λμμ onErrorMap()μ μλμ μμΈλ₯Ό CustomExceptionμΌλ‘ λ³νν©λλ€.
μ¬μλ μ λ΅
retry()
retry()λ μλ¬ λ°μ μ μ£Όμ΄μ§ νμλ§νΌ μ¬μλλ₯Ό μννλ κΈ°λ₯μ μ 곡ν©λλ€. μ΄ λ©μλλ₯Ό μ¬μ©νλ©΄ μΌμμ μΈ μ€λ₯λ‘ μΈν μμ² μ€ν¨λ₯Ό μλμΌλ‘ 볡ꡬνλ λ° μ μ©ν©λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.retry(3)
.subscribe(System.out::println);
μμ μ½λμμ retry(3)λ μΉ μμ²μ΄ μ€ν¨νλ©΄ μ΅λ 3λ²κΉμ§ μμ²μ μ¬μλνλλ‘ μ€μ ν©λλ€. λ°λΌμ μΌμμ μΈ λ€νΈμν¬ μ€λ₯λ μλ² μ€λ₯ λ±μΌλ‘ μΈν΄ μμ²μ΄ μ€ν¨νλλΌλ μ€μ ν λ§νΌ μ¬μλνμ¬ μ±κ³΅μ μΌλ‘ μλ΅μ λ°μ μ μμ΅λλ€.
retryWhen()
retryWhen()λ retry()λ³΄λ€ μ’ λ μ λ΅μ μΈλ°νκ² μ€μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, νΉμ μκ° κ°κ²©μΌλ‘ μ¬μλνκ±°λ, νΉμ 쑰건μ λ§μ‘±ν λλ§ μ¬μλλ₯Ό μννλ λ±μ 볡μ‘ν μ¬μλ μ λ΅μ μ€μ ν μ μμ΅λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1)))
.subscribe(System.out::println);
μ μ½λμμ retryWhen(Retry.backoff(3, Duration.ofSeconds(1)))λ μμ²μ΄ μ€ν¨νλ©΄ μ΅λ 3λ²κΉμ§ μ¬μλνλ, κ° μ¬μλ μ¬μ΄μλ 1μ΄μ λλ μ΄λ₯Ό κ°μ§λλ‘ μ€μ ν©λλ€.
retryBackOff()
retryBackOff()λ μ€ν¨ν μμ μ μ¬μλνλ λμ μ§μ λ°±μ€ν μ λ΅μ μνν©λλ€. μ¦, μ¬μλ κ°μ μ§μ° μκ°μ΄ μ μ°¨μ μΌλ‘ μ¦κ°νλλ‘ νμ¬, μλ²μ λΆνμν λΆνλ₯Ό μ£Όμ§ μλλ‘ ν©λλ€. μ§μ° μκ°μ μ΅λμΉλ₯Ό μ€μ νκ±°λ μ¬μλ νμμ μ΅λμΉλ₯Ό μ€μ ν μλ μμ΅λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.retryBackoff(3, Duration.ofMillis(100), Duration.ofSeconds(1))
.subscribe(System.out::println);
μ μ½λμμλ μμ²μ΄ μ€ν¨νλ©΄ μ΅λ 3λ²κΉμ§ μ¬μλνλ©°, κ° μ¬μλ μ¬μ΄μ μ§μ° μκ°μ μ΄κΈ° μ§μ°μκ°μΈ 100λ°λ¦¬ μ΄λΆν° μμνμ¬, κ° μ¬μλλ§λ€ μ§μμ μΌλ‘ μ¦κ°νλ©°, 1μ΄λ₯Ό μ΄κ³Όνμ§ μμ΅λλ€.
κΈ°ν
timeout()
timeout()μ μ§μ λ μκ° λ΄μ μνλ κ²°κ³Όκ° λλ¬νμ§ μμ κ²½μ° TimeoutExceptionμ λ°μμν΅λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(1))
.subscribe(System.out::println);
μ μ½λμμλ μμ²μ λν μλ΅μ΄ 1μ΄ μ΄λ΄μ λλ¬νμ§ μμΌλ©΄ TimeoutExceptionμ΄ λ°μν©λλ€.
repeat()
repeat()λ μ±κ³΅μ μΌλ‘ μλ£λ μμ μ λ°λ³΅νλ λ©μλμ λλ€. μ΄λ μ€λ₯κ° μλλΌ μ±κ³΅μ μΌλ‘ μλ£λ μμ μ λν λ°λ³΅μ΄ νμν λ μ¬μ©λλλ°, μλ₯Ό λ€μ΄, λ°μ΄ν°λ₯Ό μ£ΌκΈ°μ μΌλ‘ κ°μ ΈμμΌ νλ κ²½μ° repeat() ν¨μλ₯Ό μ¬μ©νμ¬ μμ²μ μ κΈ°μ μΌλ‘ λ°λ³΅ν μ μμ΅λλ€.
webClient.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.repeat(3)
.subscribe(System.out::println);
μ μ½λλ μΉ μμ²μ μ±κ³΅μ μΌλ‘ μλ£ν νμ 3λ² λ μμ²μ λ°λ³΅ν©λλ€.
λ§λ¬΄λ¦¬
WebClientλ₯Ό μ¬μ©νμ¬ HTTP μμ²μ λ³΄λΌ λ, μ΄λ¬ν λ€μν μλ¬ μ²λ¦¬μ μ¬μλ μ λ΅μ μ¬μ©νλ©΄ λ°μν μ μλ λ€μν λ¬Έμ λ€μ λ³΄λ€ ν¨κ³Όμ μΌλ‘ μ²λ¦¬νκ³ λ³΅κ΅¬ν μ μμ΅λλ€.
'BackEndπ± > Spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
TestContainerλ‘ ν΅ν© ν μ€νΈ νκ²½ ꡬμΆνκΈ° (3) | 2023.10.15 |
---|---|
λΆμ°λ½μΌλ‘ μ μ°©μ μ΄λ²€νΈ ꡬννκΈ° (3) | 2023.08.31 |
Spring Data Redisμ @Indexed μ¬μ© μ μ£Όμμ (0) | 2023.08.07 |
Spring Batchλ? κ°λ¨ν κ°λ κ³Ό μ½λ μ΄ν΄λ³΄κΈ° (0) | 2023.07.29 |
μ€νλ§μμ @Asyncλ₯Ό μ¬μ©ν λ μ£Όμμ (4) | 2023.07.24 |
Kafka κ°λ κ³Ό Spring Boot + Kafka κ°λ¨ν μ°λ (1) | 2023.07.19 |
λκΈ