최종프로젝트 관련 정리

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;
      }
    }
  );
}