ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring - Asynchronous request processing (비동기 요청 처리)
    최종프로젝트 관련 정리 2020. 8. 22. 10:45

     

    Spring - Asynchronous request processing (비동기 요청 처리)

     

    1. pom.xml 

    <!-- Servlet -->
    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>javax.servlet-api</artifactId>
       <version>3.0.1</version>
       <scope>provided</scope>
    </dependency>

     

    2. web.xml 

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
     
        ...
     
    </web-app>

     

    3. web.xml 내의 servlet설정에 async-supported 태그 값을 true로 설정한다.

    <servlet>
       <servlet-name>appServlet</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
       <async-supported>true</async-supported>
    </servlet>

    종류

     

    1.Callable

     

    요청을 처리하는 Servlet쓰레드가 반환되면 Spring MVC에서 제어하는 쓰레드에 의해 비동기처리된다.

    Callable의 처리과정은 다음과 같다.

    1. Controller의 RequestMapping method에서 일반적인 뷰 객체나 String값을 리턴하는 것이 아니라 Callable객체를 리턴한다.

    2. Callable이 리턴될 때 Servlet쓰레드가 반환되며 비동기처리를 Callable에게 위임한다.

    3. Spring MVC내의 TaskExcutor에서 관리되는 쓰레드에서 Async처리가된다.

    4. Callable내부의 call()함수에서 리턴되는 값이 다시 Servlet쓰레드로 전달된다.

    Callable은 주로 요청처리가 오래걸리는 DB작업, REST API요청처리를 하는 데 적합하다.

    @RequestMapping(“/view”)
    public Callable<String> callableWithView(final Model model) {
      return new Callable<String>() {
        @Override
        public String call() throws Exception {
          Thread.sleep(2000);
          model.addAttribute(“foo”, “bar”);
          model.addAttribute(“fruit”, “apple”);
          return “view”;
        }
      }

    2. DefferedResult

     

    Servlet 스레드는 반환하고 Spring MVC가 제어하지 않는 쓰레드를 통해 비동기를 처리한다. DefferedResult는 JMS, AMQP, 스케쥴러, Redis, 다른 HTTP요청에서 사용된다.

    DefferedResult의 처리과정은 다음과 같다.

    1. Controller에서 DefferedResult를 반환하고 In-Memory Queue또는 List에 DefferedResult를 저장한다.

    2. Servlet쓰레드는 반환되고 이벤트 발생 시 Queue에서 DefferedResult객체를 꺼내 사용한다.

    @RequestMapping("/quotes")
    @ResponseBody
    public DeferredResult<String> quotes() {
      DeferredResult<String> deferredResult = new DeferredResult<String>();
      // Save the deferredResult in in-memory queue ...
      queue.add(defferedResult);
     
      return deferredResult;
    }
     
    // In some other thread...
    @RequestMapping("/someEvent")
    @ResponseBody
    public String someEvent(String data) {
      for(DefferedResult<String> result : queue) {
        result.setResult(data);
      }
     
      return "view";
    }

    3. AsyncTask

     

    Callable과 동일한 방식으로 사용하며 Controller에서 Callable을 담아서 반환한다.

    Timeout을 추가할 수 있으며 AsyncTaskExecutor를 지정하거나 작업의 종류에 따라 쓰레드 풀을 분리하여 사용할 수 있다.

     

    @RequestMapping("/facebooklink")
    public WebAsyncTask<String> facebooklink() {
      return new WebAsyncTask<String>(
        30000L, // Timeout
        "facebookTaskExecutor", // TaskExecutor
        new Callable<String>() {
          @Override
          public String call() throws Exception {
          // 작업
            return result;
          }
        }
      );
    }

    댓글

Designed by Tistory.