스프링 에서 비동기(Async) 사용
일반적으로 사용하는 다음과 같은 컨트롤러 코드는 동기화를 기본으로한다.
@RestController | |
@RequestMapping("/accounts") | |
public class AccountController { | |
private Logger log = LoggerFactory.getLogger(this.getClass()); | |
@Autowired | |
AccountService accountService; | |
@RequestMapping(value ="/", method = RequestMethod.GET) | |
public String test(){ | |
return "testgoood"; | |
} |
하지만 이와 같이 동기화를 하면 어떠한 api에 많은 Request가 들어오거나, 메일서비스같이 오래걸리는 api라면 스레드대기상태가 걸린다.
스레드를 할당 받지 못하는경우도 생길 수 있다.
그렇다면 어떻게 해야하는가!!
해결법 비동기!
비동기란 일반적으로 어떠한 처리를 동기화 하지않고 동시에 여러곳에서 처리하는 것을 말하는데 일반적으로 다음과 같이 움직인다.
- 어떠한 요청이 있을때 바로 리턴값을 받는데 이것을 결과 값이 아니다. 모든 처리가 끝난 후 결과값을 간접적으로 받는다.
- 요청별로 별도의 스레드를 통해 처리한다.
약간 요런느낌??
그리고...
스프링 3.2 부터 비동기를 지원하는 라이브러리가 등장했다.
1.Callable
요청 받은 스레드를 서블릿 컨테이너에 반환하고 스프링에서 제공하는 TaskExcutor의 새로운 스레드를 생성하여 처리한다. 그 동안 원래 스레드는 새로운 요청을 처리할 수 있게 된다. 그리고 분리된 스레드 안에서 Callable클래스를 호출하여 그 리턴 값과 원래 요청된 응답을 서블릿 컨테이너로 보낸다.
- 리턴 타입에 다음과 같이 Callable을 추가만 하면 된다.
@EnableWebMvc | |
public class AsyncConfig extends WebMvcConfigurerAdapter { | |
@Override | |
public void configureAsyncSupport(AsyncSupportConfigurer configurer) { | |
// TODO Auto-generated method stub | |
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); | |
taskExecutor.setCorePoolSize(10); | |
taskExecutor.setMaxPoolSize(20); | |
taskExecutor.setQueueCapacity(50); | |
configurer.setTaskExecutor(taskExecutor); | |
} | |
} |
<스레드풀 생성>
@RestController | |
@RequestMapping("/accounts") | |
public class AccountController { | |
private Logger log = LoggerFactory.getLogger(this.getClass()); | |
@Autowired | |
AccountService accountService; | |
@RequestMapping(value ="/{email}", method = RequestMethod.GET) | |
public @ResponseBody Callable<Account> findByEmail(@ModelAttribute Account account){ | |
return () -> { | |
return accountService.findByEmail(account.getEmail()); | |
}; | |
} |
<컨트롤러 적용>
2.DeferredResult
컨트롤러의 리턴을 별도의 작업에서 할 수 있게 해준다. 하지만 이스레드는 스프링에의해 관리 되는 것이 아니다.
DeferredResult클래스는 어떤 요청에 대한 응답을 이벤트를 Queue에 저장하고 있다가 DeferredResult.setResult() 메소드가 호출되면 DispatcherSerlvet으로 응답을 보낸다. 즉 서버가 Push하는 기술들을 구현할 수 있게 해준다.
참고 : 3.Asynchronous Support in Spritng MVC 3.2
'Programming > SpringFramework' 카테고리의 다른 글
나의 프레임워크 설계 ref 스프링 - 4 - (0) | 2016.06.05 |
---|---|
나의 프레임워크 설계 ref 스프링 - 3 - (0) | 2016.06.04 |
나의 프레임워크 설계 ref 스프링 - 2 - (0) | 2016.05.21 |
나의 프레임워크 설계 ref 스프링 - 1 - (0) | 2016.05.07 |
나의 프레임워크 설계 ref 스프링 - 0 - (0) | 2016.04.29 |