SpringMVC 비동기 처리 의 5 가지 방식 예시 상세 설명

얼마 전에 diamond 의 원 리 를 연 구 했 는데 그 중에서 중요 한 지식 점 은 긴 연결 의 실현 이 고 servlet 의 비동기 처 리 를 사용 했다.비동기 처리 의 가장 큰 장점 은 병발 량 을 높 여 현재 스 레 드 를 막 지 않 는 다 는 것 이다.사실 Spring MVC 도 비동기 처 리 를 지 원 했 고 본 고 는 관련 기술 점 을 기록 했다.
비동기 처리 demo
비동기 반환 을 사용 하려 면@EnableAsync 를 켜 야 합 니 다.다음 코드 에 서 는 Deferred Result 를 사용 하여 비동기 처 리 를 합 니 다.
들 어 오 라 고 요청 하면 먼저 Deferred Result 대상 을 만 들 고 시간 초과 시간 을 60 초 로 설정 합 니 다.그리고 Deferred Result 가 비동기 적 으로 완성 되 고 시간 이 초과 되 기 를 기다 리 는 반전 을 지정 합 니 다.동기 화 처 리 는 비동기 화 된 것 을 만 들 고 Deferred Result 로 돌아 가면 됩 니 다.이렇게 하면 Spring MVC 가 이번 요청 을 처리 한 후 클 라 이언 트 에 response 를 즉시 되 돌려 주지 않 고 Deferred Result 처리 가 완 료 될 때 까지 기다 릴 것 입 니 다.Deferred Result 가 60 초 안에 처리 되 지 않 으 면 시간 초과 가 발생 하고 response 를 클 라 이언 트 에 게 되 돌려 줍 니 다.

@RequestMapping(value = "/async/demo")
public DeferredResult<String> async(){
 //    DeferredResult,       60s
 DeferredResult<String> deferredResult = new DeferredResult<>((long)60 * 1000);

 String uuid = UUID.randomUUID().toString();
 Runnable callback = () -> manager.remove(deferredResult, uuid);
 //           
 deferredResult.onCompletion(callback);
 deferredResult.onTimeout(callback);

 //       
 manager.addAsyncTask(deferredResult, uuid);

 //      DeferredResult
 return deferredResult;
}
비동기 작업 에 있어 서 Deferred Result 대상 을 가 져 야 합 니 다.비동기 처리 가 끝 날 때 Deferred Result.set Result 를 수 동 으로 호출 하여 출력 을 완성 해 야 합 니 다.setResult 를 호출 할 때 데이터 출력 을 클 라 이언 트 에 기록 한 다음 비동기 로 이 벤트 를 실행 합 니 다.

task.getDeferredResult().setResult(ConfigJsonUtils.toJsonString(map));
Deferred Result 를 사용 하여 비동기 처 리 를 진행 합 니 다.
Deferred Result 라 는 종 류 는 지연 결 과 를 대표 합 니 다.Deferred Result 는 비동기 작업 에 사용 할 수 있 습 니 다.다른 스 레 드 는 Deferred Result 를 가 져 오고 Deferred Result 의 반환 데 이 터 를 설정 할 수 있 습 니 다.보통 스 레 드 탱크,대기 열 등 을 사용 하여 Deferred Result 와 결합 하여 비동기 처 리 를 할 수 있 습 니 다.
공식 설명 에 따 르 면 Spring MVC 처리 절 차 는 다음 과 같다.
  • controller 가 돌아 온 Deferred Result 를 메모리 대기 열 이나 집합 에 저장 합 니 다
  • Spring MVC 호출 request.startAsync(),비동기 실행;
  • Dispatcher Servlet 과 모든 Filter 가 현재 요청 스 레 드 를 종료 합 니 다
  • 비 즈 니스 는 비동기 스 레 드 에 Deferred Result 의 반환 값 을 설정 하고 Spring MVC 는 다시 요청 을 보 냅 니 다
  • Dispatcher Servlet 이 다시 호출 되 고 Deferred Result 의 반환 값 을 사용 합 니 다
  • Callable 을 사용 하여 비동기 처리
    Callable 을 사용 하여 비동기 처 리 를 하 는 것 은 Deferred Result 와 유사 합 니 다.다른 것 은 Callable 이 시스템 에서 지정 한 TaskExecutor 에 게 실 행 됩 니 다.
    공식 설명 에 따 르 면 Spring MVC 처리 절 차 는 다음 과 같다.
    컨트롤 러 가 호출 가능 으로 되 돌아 갑 니 다.
  • Spring MVC 는 request.startAsync()를 호출 하여 이 보 를 열 고 Callable 을 작업 스 레 드 탱크 에 제출 합 니 다
  • Dispatcher Servlet 과 모든 Filter 가 현재 요청 스 레 드 를 종료 합 니 다
  • 비 즈 니스 는 비동기 스 레 드 에서 값 을 되 돌려 주 고 Spring MVC 는 다시 요청 을 보 냅 니 다
  • Dispatcher Servlet 이 다시 호출 되 고 Callable 의 반환 값 을 사용 합 니 다
  • 
    @RequestMapping(value = "/async/demo")
    public Callable<String> async(){
     Callable<String> callable = () -> String.valueOf(System.currentTimeMillis());
     //     
     return callable;
    }
    ListenableFuture 를 사용 하여 비동기 처 리 를 진행 합 니 다.
    ListenableFuture 는 반환 값 으로 Deferred Result 와 유사 합 니 다.사용자 가 스스로 비동기 스 레 드 를 처리 해 야 하지만 시간 초과,리 셋 을 지원 하지 않 고 자체 적 으로 처리 해 야 한다.
    
    @RequestMapping(value = "/async/demo")
    public ListenableFuture<String> async(){
     ListenableFutureTask<String> ListenableFuture= new ListenableFutureTask<>(() -> {
      return String.valueOf(System.currentTimeMillis());
     });
     Executors.newSingleThreadExecutor().submit(ListenableFuture);
     return ListenableFuture;
    }
    Response Body Emitter 를 사용 하여 비동기 처 리 를 진행 합 니 다.
    Deferred Result 와 Callable 은 하나의 비동기 값 만 되 돌려 줍 니 다.여러 대상 을 되 돌려 주 려 면 Response Body Emitter 를 사용 해 야 합 니 다.돌아 오 는 모든 대상 은 HttpMessage Converter 에 의 해 처리 되 고 출력 흐름 을 다시 씁 니 다.헤더,status 등 더 많은 반환 데 이 터 를 설정 하려 면 Response Body Emitter 를 ResponseEntity 의 실체 데이터 로 되 돌려 줄 수 있 습 니 다.
    
    @RequestMapping("/async/responseBodyEmitter")
    public ResponseBodyEmitter responseBodyEmitter(){
     ResponseBodyEmitter responseBodyEmitter=new ResponseBodyEmitter();
    
     Executors.newSingleThreadExecutor().submit(() -> {
      try {
       responseBodyEmitter.send("demo");
       responseBodyEmitter.send("test");
       responseBodyEmitter.complete();
      } catch (Exception ignore) {}
     });
    
     return responseBodyEmitter;
    }
    StreamingResponseBody 를 사용 하여 비동기 처리
    반환 값 의 자동 변환 을 건 너 뛰 려 면 출력 흐름 을 OutputStream 에 직접 기록 하고 StreamResponse Body 를 사용 할 수 있 습 니 다.ResponseEntity 의 실체 데이터 로 되 돌 릴 수도 있 습 니 다.
    
    @RequestMapping("/async/streamingResponseBody")
    public StreamingResponseBody streamingResponseBody(){
     StreamingResponseBody streamingResponseBody = outputStream -> {
      Executors.newSingleThreadExecutor().submit(() -> {
       try {
        outputStream.write("<html>streamingResponseBody</html>".getBytes());
       } catch (IOException ignore) {}
      });
     };
     return streamingResponseBody;
    }
    각종 처리 방식 의 대비
    반환 가능 횟수
    데이터 변환
    리 턴
    스 레 드 탱크
    DeferredResult
    1 회
    있다
    완성 하 다
    스스로 처리 하 다
    Callable
    1 회
    있다
    없다
    시스템 처리
    ListenableFuture
    1 회
    있다
    없다
    스스로 처리 하 다
    ResponseBodyEmitter
    여러 번
    있다
    없다
    스스로 처리 하 다
    StreamingResponseBody
    여러 번
    없다
    없다
    스스로 처리 하 다
    여기 서 SpringMVC 비동기 처리 에 관 한 5 가지 방법 에 관 한 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringMVC 비동기 처리 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기