[vert.x] 컨커런시 모델
https://github.com/purplefox/vert.x/wiki/Concurrency-model
vert.x의 컨커런시 모델은 멀티 리액터 패턴이다. 이 패턴은 Java 1.4에 추가된 NIO로 구현할 수 있다. 그리고 이미 그 기반으로 조금 더 쉽게 코딩할 수 있도록 Netty라는 오픈소스 프로젝트도 있고, vert.x는 netty 위에서 조금 더 최근 기술 동향에 어울리는 프레임워크로 자리잡고자 노력중이다.
최근 기술 동향에 어울리는.. 이라고 함은 vert.x 첫 페이지에서 볼 수 있다.
- 모든게 non-blocking
- Polyglot (물론, 그래봤자 JVM에서 돌아가는 언어 들이지만...그래도 폴리글롯은 폴리곳이니깐..ㅋ)
- True Scalable. (다른 이벤트 기반 프레임워크에 비해 이 점을 장점으로 내세운다. 즉 멀티 리액터 패턴이라는 것이다.)
- 컨커런시 모델이 깔끔해서 race condition이나 lock 걱정 없이 코딩해도 된단다.
- 다양한 네트워크 프로토콜 지원: TCP, SSL, HTTP, HTTPS, Websockets.
- SockJS 지원 (플래시 소켓을 사용하지 않는다고 node.js 진영의 Socket.IO보다 낫다고 주장한다.)
- Sinatra/Express 스타일(매우 간편한 MVC 스타일)로 코딩할 수 있다.
- 분산 이벤트 버스 제공
이 중에서 핵심은 단연 컨커런시 모델이라고 할 수 있으니 컨커런시 모델을 살펴보자.
리액터 패턴의 장점은 locking이나 race condition을 신경쓸 필요 없다는 것이다. 쓰레드 하나로 코드를 실행하기 때문이다. 하지만 이런 전통적인 방식의 리액터 패턴은 멀티 코어 서버에서도 최대한 오직 단일 코어만 사용하게 된다는 문제가 있다. 따라서 만약 32 코어 서버를 최대한 활용하려면 인스턴스를 32개 띄워야 된다. 그런데 만약에 그 애플리케이션이 stateless하지 않고, 상태 정보를 관리해야 한다면, 프로세스 간에 메시지를 주고 받아야 하는 등 상태 관리가 까다로워진다.
vert.x는 프로세스당 여러 이벤트 루프를 돌릴 수 있도록 지원하기 때문에 인스턴스 한개를 띄워서 한개의 OS 프로세스로 모든 코어를 활용할 수 있다.
vert.x 인스턴스 한개가 여러 애플리케이션 인스턴스를 동시에 호스팅할 수 있다. 각각의 애플리케이션 인스턴스는 싱글 쓰레드로 동작하고 이벤트 루프 하나씩을 할당 받는다. 애플리케이션 인스턴스의 모든 코드는 오직 해당 이벤트 루프로만 실행한다. 여러 애플리케이션 인스턴스를 배포하는 방법으로 확장을 할 수 있다.
vert.x를 사용하면 컨커런시를 걱정할 필요가 없을 뿐 아니라 전통적인 단일 리액터 모델이 지니고 있는 확장성 문제도 신경쓸필요 없다.
상태 공유와 메시지 전송
stateless한 애플리케이션은, 애플리케이션 인스턴스가 상태 정보를 주고받을 필요가 없다. 하지만 대부분의 애플리케이션이 상태 정보를 가지고 있다.
vert.x는 애플리케이션 인스턴스가 정보를 공유할 수 있는 두가지 방법을 제공한다.
- 메시지 전송: 한쪽 컨텍스트에서 다른쪽으로 메시지를 전송할 수 있다. 애플리케이션 인스턴스를 액터로 생각한다면, 액터 모델과 비슷하다고 볼 수 있다. 이런 모델은 특히, 데이터 스트림과 관련된 애플리케이션에서 유용하다.
- 공유 데이터 구조: 공유된 캐시 데이터 같은 경우에는 메시지 전송 방식 보다는 vert.x가 제공하는 데이터 구조를 활용하는 방법이 좋다. immutable 객체만 shared data structure에 넣을 수 있다.
vert.x는 액터만 사용하라거나, 공유 데이터 구조만 사용하라고 강요하지 않는다. 정답은 없기 때문에 애플리케이션에 따라 개발자가 직접 선택할 수 있게 해준다.