가이드 코드에 따라 두 개의 API를 호출하고 RxJava 및 Vertx와 비동기적으로 긴 차단 요청을 보내는 방법을 배울 것입니다.
다른 구성 요소와 상호 작용해야 하는 서비스를 개발한다고 가정해 보겠습니다. 안타깝게도 이러한 구성 요소는 느리고 차단됩니다. 이것은 매우 느린 레거시 서비스이거나 우리가 사용해야 하는 일부 차단 API일 수 있습니다. 그럼에도 불구하고, 우리는 그것을 통제할 수 없습니다.
또한 두 응답이 모두 사용 가능해지면 응답 상태 코드를 출력해야 합니다. 예전 방식, 무반응 방식으로 하면 5초 동안 호출 스레드를 차단할 수 있습니다.
서비스
"httpstat.us "을 웹 서비스로 사용했습니다. 이것은 웹 클라이언트를 테스트하기 위해 다양한 HTTP 코드를 생성하기 위한 간단한 서비스입니다. 제공된 시간 동안 HTTP 요청을 차단하는 추가 매개 변수(이 경우 절전)를 제공할 수 있습니다.
"httpie"를 사용하여 두 서비스를 모두 테스트할 것입니다.
서비스 1은 5초 동안 차단된 후 상태 코드 200으로 응답을 반환합니다:
http://httpstat.us/200?sleep=5000
_____________________________________________
HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain
Date: Tue, 08 Mar 2022 17:05:08 GMT
Request-Context: appId=cid-v1:1e93d241-20e4-4513-bbd7-f452a16a5d69
Server: Kestrel
Set-Cookie: ARRAffinity=e2c17206c539113795daf64bd958d003f2b29b9f62da53617beea05468875ba5;Path=/;HttpOnly;Domain=httpstat.us
200 OK
서비스 2는 5초 대신 2초 동안 차단된다는 점을 제외하고는 이전 서비스와 동일합니다:
http://httpstat.us/200?sleep=2000
_____________________________________________
HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain
Date: Tue, 08 Mar 2022 17:11:53 GMT
Request-Context: appId=cid-v1:1e93d241-20e4-4513-bbd7-f452a16a5d69
Server: Kestrel
Set-Cookie: ARRAffinity=e2c17206c539113795daf64bd958d003f2b29b9f62da53617beea05468875ba5;Path=/;HttpOnly;Domain=httpstat.us
200 OK
웹 클라이언트
웹 클라이언트에 대해 논의하겠습니다. 이 섹션에서는 Vert.x 웹 클라이언트를 사용했습니다. RxJava도 지원하는 사용하기 쉬운 비동기식 HTTP 및 HTTP/2 클라이언트입니다.
private static Single<Integer> service1(WebClient webClient) {
return webClient.getAbs("http://httpstat.us/200?sleep=5000")
.rxSend()
.doOnSuccess(response -> out.println("[" + Thread.currentThread().getName() + "] service 1: response received"))
.map(HttpResponse::statusCode);
}
private static Single<Integer> service2(WebClient webClient) {
return webClient.getAbs("http://httpstat.us/200?sleep=2000")
.rxSend()
.doOnSuccess(response -> out.println("[" + Thread.currentThread().getName() + "] service 2 response received"))
.map(HttpResponse::statusCode);
}
두 방법 모두 매우 유사합니다. WebClient를 매개 변수로 사용하고 Single을 반환하는 HTTP 요청을 보냅니다. 여기서 정수는 HTTP 응답 코드입니다. RxJava Single을 반환하면 결과가 비동기식임을 확인할 수 있습니다. 상태 코드는 나중에 사용 가능할 때 액세스할 수 있습니다. 이는 또한 우리에게 게으른 평가를 제공합니다. 즉, 활성 구독이 있는 경우에만 서비스가 호출됩니다.
단일 소스 사용
구독해야 할 두 가지 소스가 있습니다. RxJava에는 단일 소스를 함께 결합하는 편리한 방법이 있습니다. 첫 번째 소스에서 method .zipWith를 호출하고 두 개의 매개 변수를 제공할 수 있습니다. 첫 번째는 zip으로 사용할 소스이고 두 번째는 결과를 모두 소비하고 처리하고 다른 것을 반환하는 기능입니다.
이 경우 반환 유형은 AbstractMap입니다.단순 입력 <Integer, Integer>, 이는 두 정수의 단순 튜플입니다. 장황해 보이죠? 안타깝게도 핵심 Java 라이브러리에는 더 나은 튜플 또는 페어 구현이 없습니다.
Java Lamdas 덕분에 다음과 같은 동작을 매개 변수로 전달할 수 있습니다:
Single<Integer> service1Code = service1(webClient);
Single<Integer> service2Code = service2(webClient);
Single<AbstractMap.SimpleEntry<Integer, Integer>> tupleSource =
service1Code.zipWith(service2Code, (s1, s2) -> new AbstractMap.SimpleEntry<>(s1, s2));
참고: AbstractMap의 경우 자체 튜플 또는 쌍을 구현할 수 있습니다.단순 항목이 너무 장황하게 느껴집니다.
올 투게더
마지막으로 아래와 같이 모든 비트와 피스를 함께 배치할 수 있습니다:
// Vertx instance and web client
Vertx vertx = Vertx.vertx();
WebClient webClient = WebClient.create(vertx);
// single sources. Lazy evaluation, no invocation at this point
Single<Integer> service1Code = service1(webClient);
Single<Integer> service2Code = service2(webClient);
// combine results together and create tuple
Single<AbstractMap.SimpleEntry<Integer, Integer>> tupleSource =
service1Code.zipWith(service2Code, (s1, s2) -> new AbstractMap.SimpleEntry<>(s1, s2));
// subscribe and invoke services
tupleSource
.doFinally(countDownLatch::countDown)
.subscribe(Services::printResult);
코드를 실행한 후 콘솔에 인쇄된 결과입니다. 두 요청 모두 동일한 vertx 이벤트 루프 스레드에서 발송되었습니다. 또한 프로그램은 스레드가 매초마다 차단되지 않는다는 메시지를 출력합니다. 마지막으로 두 상태 코드가 모두 최종 결과로 출력됩니다. 모든 것이 동일한 스레드에서 발생한 것을 알 수 있습니다:
[vert.x-eventloop-thread-1] is released
[vert.x-eventloop-thread-1] is released
[vert.x-eventloop-thread-1] service 2 response received
[vert.x-eventloop-thread-1] is released
[vert.x-eventloop-thread-1] is released
[vert.x-eventloop-thread-1] is released
[vert.x-eventloop-thread-1] service 1: response received
[vert.x-eventloop-thread-1] Result: service1:200 service2:200
결론
현재 우리가 하고 있는 모든 것입니다. 이 기사가 유익했기를 바라며, 이제 RxJava 및 Vertx와 비동기적으로 긴 차단 요청을 보내는 방법을 더 잘 이해하기를 바랍니다. 이 문서에 사용된 전체 코드는 여기에 연결되어 있습니다.
'SW > Java' 카테고리의 다른 글
자카르타 EE 10과 글래스피쉬 7로 업그레이드하는 방법 (0) | 2023.07.28 |
---|---|
Java : Java 모듈의 이점, 예제, 설명 (0) | 2023.06.24 |
Java : this 키워드 : 개념, 개요, 예제, 설명 (0) | 2023.02.28 |
Java : 자바 생성자 : 개념, 예제, 개요, 설명 (0) | 2023.02.26 |
Java : 자바 OOP 컨셉, 개념, 개요, 설명 (0) | 2023.02.22 |