Spring

멀티스레딩을 사용한 스프링 부트 비동기

기록만이살길 2022. 12. 1. 17:59
반응형

멀티스레딩을 사용한 스프링 부트 비동기

1. 질문(문제점):

여러 서비스를 호출하는 스프링 부트 마이크로 서비스가 있습니다(예: 서비스 A 및 서비스 B). 일부 조건에 따라 여러 스레드에서 이 두 서비스를 비동기식으로 호출하려고 하고 처리가 완료되면 서비스 A와 서비스 B의 응답을 병합하고 싶습니다.

@Async를 사용하여 프로세스를 비동기적으로 실행하고 ExecutorService를 사용하여 서비스에 대한 여러 스레드를 시작할 수 있다는 것을 알고 있습니다.

그러나 나는 모든 것을 함께 유지하는 방법을 확신하지 못합니다. 여기에서 어떤 제안을 찾고 계십니까?

              @Async
              Service A(thread1,thread2) \
MicroService /                             (Merge from Response of ServiceA and ServiceB)
             \ @Async
              Service B(thread1,thread2) /

나는 이것이 위에서 대부분 이론적으로 설명되었다는 것을 알고 있지만 여러 웹 사이트를 따라가거나 통과하려고 시도했지만 대부분의 기사는 Aync 또는 Multithreading에 대해 설명하지만 여러 스레드에서 Async에서 두 프로세스를 기다리고 실행하는 방법을 잘 모르겠습니다. 이 두 후에 계속 실행 서비스 콜 완료!

모든 제안이나 리드에 감사드립니다! 티아 :)

2. 해결방안:

스프링의 AsyncResult클래스를 사용하여 결과를 래핑한 다음 해당 메서드를 사용하여 객체 .completable()를 반환해야 합니다.CompletableFuture

퓨처 객체를 병합할 때 CompletableFuture.thenCompose()CompletableFuture.thenApply() 메서드를 사용하여 다음과 같이 데이터를 병합합니다.

CompletableFuture<Integer> result = futureData1.thenCompose(fd1Value -> 
                futureData2.thenApply(fd2Value -> 
                        merge(fd1Value, fd2Value)));

다음은 기본적인 예입니다.

어노테이션으로 Spring 부트 메인 클래스에 @EnableAsync어노테이션 달기

@SpringBootApplication
@EnableAsync
public class StackOverflowApplication {

    public static void main(String[] args) {
        SpringApplication.run(StackOverflowApplication.class, args);
    }

}

반환할 샘플 서비스를 만듭니다.CompletableFuture

Aservice.java

@Service
public class Aservice {

    @Async
    public CompletableFuture<Integer> getData() throws InterruptedException {
        Thread.sleep(3000); // sleep for 3 sec
        return new AsyncResult<Integer>(2).completable(); // wrap integer 2
    }
}

Bservice.java

@Service
public class Bservice {

    @Async
    public CompletableFuture<Integer> getData() throws InterruptedException {
        Thread.sleep(2000); // sleep for 2 sec
        return new AsyncResult<Integer>(1).completable(); // wrap integer 1
    }
}

다른 두 서비스 데이터를 병합할 다른 서비스 만들기

ResultService.java

@Service
public class ResultService {

    @Autowired
    private Aservice aservice;
    @Autowired
    private Bservice bservice;

    public CompletableFuture<Integer> mergeResult() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> futureData1 = aservice.getData();
        CompletableFuture<Integer> futureData2 = bservice.getData();

        // Merge futures from Aservice and Bservice
        return futureData1.thenCompose(
            fd1Value -> futureData2.thenApply(fd2Value -> fd1Value + fd2Value));
    }
}

테스트용 샘플 컨트롤러 만들기

ResultController.java

@RestController
public class ResultController {

    @Autowired
    private ResultService resultService;

    @GetMapping("/result")
    CompletableFuture<Integer> getResult() throws InterruptedException, ExecutionException {
        return resultService.mergeResult();
    }

}
반응형