WebClient 구현한 부분에서 추가 수정에 들어갔다.
원래는 서버로 요청을 하고 Exception 이 발생하면 바로 뱉았지만
1server 로 요청을 하고 실패했을 때
2server 로 재요청을 한 뒤 그때도 실패한다면 Exception 을 뱉는 것이다.
다음은 원래 코드의 일부 예시다.
1
2
3
4
5
this.webClient = webClientBuilder
.clientConnector(new ReactorClientHttpConnector(httpClient))
.baseUrl(baseUrl)
.build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
return this.webClient.post()
.uri(uriBuilder -> {
URI uri = uriBuilder.path("/task.do").build();
log.info("[{}] Sending POST request to URL: {}", "Task-Server-Connection", uri);
return uri;
})
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(bodyBuilder.build())) // 멀티파트 데이터를 요청데이터에 추가
.retrieve()
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
.transform(this::handleServerErrors) // 서버간 통신 중 발생하는 오류 처리
.doOnSuccess(map -> {handleDoOnSuccess(value, map);}) // 성공시 처리되는 로직
.doOnError(ApiClient::handleDoOnError) // 통신은 성공했으나 처리중의 오류 처리 로직
.then();
원래 코드에서는 이렇게 1번만 요청했던 것을
1
2
this.webClient1 = webClientBuilder.clientConnector(new ReactorClientHttpConnector(httpClient)).baseUrl(baseUrl1).build();
this.webClient2 = webClientBuilder.clientConnector(new ReactorClientHttpConnector(httpClient)).baseUrl(baseUrl2).build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
return this.webClient1.post()
.uri(uriBuilder -> {
URI uri = uriBuilder.path("/task.do").build();
log.info("[{}] Sending POST request to URL: {}", "Task-Server-Connection", uri);
return uri;
})
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(bodyBuilder.build())) // 멀티파트 데이터를 요청데이터에 추가
.retrieve()
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
.onErrorResume(throwable -> {
// 서버1로 요청시 통신 중 오류가 발생했을 땐 exception 을 던지지 않고, 같은 과정으로 서버2로 요청을 재시도 한다.
log.error(SERVER1_CONNECTION_ERROR.getErrorCode() + " :: "+ SERVER1_CONNECTION_ERROR.getErrorMsg());
return webClient2.post()
.uri(uriBuilder -> {
URI uri = uriBuilder.path("/task.do").build();
log.info("[{}] Sending POST request to URL: {}", "Task-Server-Connection", uri);
return uri;
})
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(bodyBuilder.build()))
.retrieve()
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
.transform(this::handleServerErrors); // 2server: 서버2로 재요청도 실패했을 경우의 에러 처리 로직
})
.doOnSuccess(map -> {handleDoOnSuccess(value, map);}) // 통신 성공 후: 성공시 처리되는 로직
.doOnError(ApiClient::handleDoOnError) // 통신 성공 후: 통신은 성공했으나 처리중의 오류 처리 로직
.then();
2server 로 재시도 하는 코드로 변경하였다.
원래는 1server로 통신하는 게 맞으나
만일의 사태를 대비하여 통신이 안될시 2server로 운영할 수 있게 설정을 추가하였다.
(관련 글)