위 와 같이 msa 환경에서 많은 네트워크 IO가 일어나게 되었고 이 때 해당 스레드는 blocking 상태가 되어 전체적인 서버 측면에서 보았을 때 스레드 풀안에 한정된 스레드 안에서 많은 스레드가 놀게 되고 cpu도 낭비되고 있어 많은 request가 들어왔을 때 레이턴시가 늘어나게 된다.

 

 

톰캣 맥스 스레드를 1로 제한 100개의 요청스레드 동시에 요청 테스트 -> 서블릿 스레드가 max=1 로 잡혀 있기 때문에 스레드가 늘어나지 않고 해당 1개의 스레드로 작업이 진행됨

 

 

 

2초가 걸리는 외부 API를 호출 했을 때 호출한 서버의 해당 스레드는 2초의 blocking이 걸리게 된다. 여기서는 호출한 서버의 톰캣 스레드가 1이기 때문에 계속 2초씩 blocking이 걸리게 되고 2초의 하나씩 하나의 작업을 처리하게 됨

스프링 4.0 부터 나온 AsyncRestTemplate을 사용하게되면 async 형태로 호출하게 되서 레이턴시는 줄었지만, 스레드가 늘어났다.

서블릿 스레드는 1개로 유지 된다. 하지만 AsyncRestTemplate 자체가 워크 스레드를 만들게 되고 그 스레드가 blocking에 걸리게 된 것이다.

 



이와 같이 AsyncRestTemplate에 Netty4ClinetHttpRequestFactory(New NioEventLoopGrop(1)) 네티 라이브러리를 이용하면

nonblocking + async 처리를 할 수 있고 위와 같이 스레드 개수가 늘어나지 않는다라는 걸 알 수 있다.

 

만약 받은 데이터를 맵핑하거나 다른 처리를 하고 싶다면

위와 같이 콜백 함수를 등록하고 DefferdResult에 설정해주면 된다.

 

한번 가져온 데이터 응답을 가지고 다른 api로 넘겨줘서 2번호출 할 때 위와 같이 콜백을 두번 등록

2번 api콜을 통해 가져온 데이터를 어플리케이션 스레들 풀에서 비동기로 한번 더 작업을 하기 위해 다시 콜백등록

 

 

이런식으로 계속 콜백의 콜백을 등록하는 형식으로 데이터를 제어 할 수 있음 하지만 코드가 깔끔하지 않다 어떻게 해결할까?

+ Recent posts