Vert.x는 빠르게 성장하고 있는 서버 프레임워크입니다. 각 서버 프레임워크는 자신들의 강점을 다양한 프로토콜이 지원되는 고성능이라고 얘기하지만 Vert.x는 그것보다 한발 더 나아갑니다. 서버 네트워크 환경을 구축하고 운영하는 환경을 고려합니다. 다시 말해, Vert.x는 클러스터링 환경에서 실행되는 여러 '서버 프로세스 데몬'을 생성하는 것뿐만 아니라 하나의 서버 프로세스 데몬을 생성하는 것에도 세심한 고려를 포함합니다.
따라서 Vert.x: 어떤 네트워크 환경을 고려하고 어떻게 고성능을 제공하는지 검토하는 것이 중요합니다. 그래서 Vert.x 구조를 충분히 검토하는 것은 중요합니다.
Vert.x는 Node.js의 영향을 받는 프로젝트입니다. Node.js와 마찬가지로 Vert.x는 이벤트 기반 프로그래밍 모델을 제공하는 서버 프레임워크이입니다. 따라서 Vert.x API는 Node.js의 API와 매우 유사합니다. 두 모델 모두 비동기 API를 제공하기 때문입니다.
Node.js는 자바스크립트를 사용하여 생성되지만 Vert.x는 자바를 사용하여 생성됩니다. 그러나 Vert.x를 Node.js의 자바 버전으로 이해하는 것은 무리입니다. Vert.x는 Node.js의 영향을 받았으나, Vert.x는 Node.js와는 다른 고유한 철학을 가지고 있습니다.
Vert.x의 가장 전형적인 디자인 철학은 다음과 같습니다.
Polyglot - 여러 언어를 지원합니다.
Vert.x 자체는 자바로 구축되어 있습니다. 그러나 자바는 Vert.x를 사용할 필요가 없습니다.
자바나 그루비와 같은 JVM 연산에 기반을 둔 언어들뿐만 아니라 Vert.x는 루비, 파이썬, 자바스크립트와 함께 사용될 수 있습니다. JavaScript를 사용하여 서버 응용 프로그램을 빌드해야 하는 경우 Node.js 대신 사용할 수 있는 방법이 있습니다. 이외에도 스칼라, 클로저 등이 지원될 예정입니다.
초단순 동시성 모형
Vert.x를 사용하여 서버 응용 프로그램을 빌드할 때 사용자는 단일 스레드 응용 프로그램으로 코드를 작성할 수 있습니다. 즉, 동기화, 잠금 또는 휘발성 없이 멀티 스레드 프로그래밍 효과를 달성할 수 있습니다.
Node.js에서 JavaScript 실행 엔진은 멀티 스레드를 지원하지 않습니다. 그러나 모든 CPU 코어를 활용하기 위해서는 동일한 자바스크립트 프로그램을 여러 개 실행해야 합니다.
그러나 Vert.x는 하나의 프로세스만 실행되는 동안 CPU 코어의 수에 따라 여러 개의 스레드를 만들 수 있게 합니다. 사용자가 비즈니스 로직을 구현하는 데 집중할 수 있도록 멀티 스레딩을 처리합니다.
이벤트 버스 제공
서론에서 설명한 것처럼 Vert.x의 목표는 '단일 서버 프로세스 데몬'을 생성하는 것만이 아니다. Vert.x는 다양한 Vert.x 기반 서버 프로그램들이 서로 잘 소통할 수 있도록 하는 것을 목표로 합니다. 이를 위해 Vert.x는 이벤트 버스를 제공합니다. 따라서 Point to Point 또는 Pub/Sub과 같은 MQ 함수를 사용할 수 있습니다(이벤트 버스 기능을 제공하기 위해 Vert.x는 In-Memory Data Grid인 Hazelcastm을 사용합니다).
이 이벤트 버스를 사용하면 서로 다른 언어로 구축된 서버 응용 프로그램이 서로 쉽게 통신할 수 있습니다.
모듈 시스템 및 공용 모듈 저장소
Vert.x는 모듈 시스템을 가지고 있다. 이러한 모듈 시스템은 구성 요소의 한 종류로 이해될 수 있다. 이는 Vert.x가 구축한 서버 애플리케이션 프로젝트 자체가 모듈화되어 있음을 의미한다. 재사용이 목적입니다. 이 모듈은 공용 모듈 리포지토리에 등록할 수 있습니다. 공용 모듈 리포지토리를 통해 모듈을 공유할 수 있습니다.
###Netty와 Vert.x의 관계와 차이점
Vert.x 성능에 대해 논의하기 전에 Netty와 Vert.x의 관계를 요약해야 합니다. Vert.x는 Netty를 사용합니다. 즉, Netty를 사용하여 모든 IO를 처리합니다. 따라서 Vert.x와 Netty의 성능 차이를 확인하는 것은 의미가 없습니다.
Vert.x는 API를 제공하는 서버 프레임워크로 Netty와는 다른 목적으로 설계되었습니다.
Netty는 낮은 수준의 IO를 처리할 수 있는 프레임워크이고 Vert.x는 Netty보다 높은 수준의 IO를 처리할 수 있습니다.
Vert.x가 제공하는 함수가 Node.js의 함수와 다르더라도 이들 사이의 성능을 비교하는 것은 중요한 문제이다. 아래 그림 1과 그림 2는 Vert.x(Java, Ruby, Groovy)와 Node.js(출처: http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-benchmarks/))의 성능을 보여줍니다.
그림 1은 HTTP 서버가 구축되고 200/OK 응답만 반환된 경우의 성능을 비교한 것입니다. 그림 2는 72바이트의 정적 HTML 파일이 응답으로 반환될 때의 성능 비교를 보여줍니다.
이 성능은 Vert.x 개발자들에 의해 발표되었지만 엄격한 환경에서 테스트되지 않았습니다.
또한 주목할 점은 Vert.x-JavaScript의 성능이 Node.js보다 우수하다는 것입니다. 그러나 성능 결과가 매우 신뢰할 수 있다고 하더라도 Vert.x가 Node.js보다 낫다고 말하기는 어려울 수 있습니다. Node.js가 Socket.io과 같은 훌륭한 모델을 제공하고 많은 레퍼런스를 가지고 있기 때문입니다.
Vert.x를 이해하기 위해서는 Vert.x 정의 용어를 이해해야 합니다. 다음은 Vert.x에서 사용되는 일반적인 용어입니다.
자바에서는 메인 메서드를 가진 클래스입니다. Verticle은 또한 Main method에 의해 참조되는 다른 스크립트들을 포함할 수 있습니다. 또한 jar 파일 또는 리소스를 포함할 수 있습니다. 애플리케이션은 이벤트 버스를 통해 통신하는 하나의 Verticle 또는 여러 Verticle로 구성될 수 있습니다. 자바와 함께 독립적으로 실행 가능한 클래스나 jar 파일로 이해될 수 있습니다.
Verticle은 Vert.x 인스턴스 내에서 실행되고 Vert.x 인스턴스는 해당 JVM 인스턴스에서 실행됩니다. 따라서 단일 Vert.x 인스턴스에서 동시에 실행되는 많은 Verticle이 있습니다. 각 Verticle에는 고유한 클래스 로더가 있을 수 있습니다. 이러한 방식으로 정적 멤버와 전역 변수를 통해 만들어진 Verticle 간의 직접적인 상호 작용을 방지할 수 있습니다. 많은 Verticle이 네트워크상의 여러 호스트에서 동시에 실행될 수 있으며 Vert.x 인스턴스는 이벤트 버스를 통해 클러스터링될 수 있습니다.
Verticle 인스턴스는 항상 동일한 스레드에서 실행되도록 보장합니다. 모든 코드를 단일 스레드 작업 유형으로 개발할 수 있어 Vert.x를 쉽게 개발할 수 있는 환경을 이용하는 개발자가 많습니다. 또한, 레이스 컨디션이나 교착 상태를 방지할 수 있습니다.
Node.js 프레임워크와 마찬가지로 Vert.x는 이벤트 기반 프로그래밍 모델을 제공합니다. Vert.x를 사용하여 서버를 프로그래밍할 때 대부분의 개발 코드는 이벤트 핸들러와 관련이 있습니다. 예를 들어 TCP 소켓에서 데이터를 수신하도록 이벤트 핸들러를 설정하거나 데이터가 수신될 때 호출되는 이벤트 핸들러를 생성해야 합니다. 또한 이벤트 처리기는 '이벤트 버스가 메시지를 수신했을 때', 'HTTP 메시지를 수신했을 때', '연결이 끊겼을 때', '타이머가 시간 초과되었을 때' 경보를 수신하도록 생성해야 합니다.
Vert.x 인스턴스는 스레드 풀을 내부적으로 관리합니다. Vert.x는 스레드 풀의 수와 CPU 코어 수를 최대한 가깝게 일치시킵니다.
각 스레드는 이벤트 루프를 실행합니다. 이벤트 루프는 이벤트가 루프를 반올림하는 것으로 확인합니다. 예를 들어, 소켓에 읽을 데이터가 있는지 또는 이벤트가 발생한 타이머를 확인합니다. 루프에서 처리할 이벤트가 있으면 Vert.x는 해당 핸들러를 호출합니다(물론 핸들러 처리 기간이 너무 길거나 I/O 차단이 있을 경우 추가 작업이 필요하다).
Verticle은 통신을 위해 Event Bus를 사용합니다. Verticle을 배우로 가정한다면, Message Passing은 얼랑 프로그래밍 언어에서 유명했던 배우 모델과 유사합니다. Vert.x 서버 인스턴스에는 많은 Verticle 인스턴스가 있으며 인스턴스 간에 메시지를 전달할 수 있습니다. 따라서 시스템은 멀티 스레드를 통해 Verticle 코드를 실행하지 않고도 사용 가능한 코어에 따라 확장할 수 있습니다.
메시지 전달은 매우 유용합니다. 그러나 모든 유형의 응용 프로그램 동시성 상황에서 항상 최선의 접근 방식은 아닙니다. 캐시는 가장 인기 있는 예 중 하나입니다. 하나의 버티컬에만 특정 캐시가 있다면 매우 비효율적입니다. 만약 다른 Verticle이 캐시를 필요로 한다면, 각 Verticle은 동일한 캐시 데이터를 관리해야 합니다.
따라서 Vert.x는 글로벌 액세스를 위한 메서드를 제공합니다. verticle은 불변 데이터만 공유합니다.
이름처럼, 이것은 Vert.x의 핵심 함수입니다. Verticle이 직접 호출할 수 있는 함수들이 코어에 포함되어 있습니다. 따라서 코어는 Vert.x가 지원하는 각 프로그래밍 언어 API에 의해 접근할 수 있습니다.
Vert.x의 간단한 아키텍처는 다음 그림에 나와 있습니다.
Vert.x의 기본 실행 단위는 Verticle이며 한 Vert.x 인스턴스에서 여러 Verticle을 동시에 실행할 수 있다. Verticles는 이벤트 루프 스레드에서 실행됩니다. 여러 Vert.x 인스턴스는 여러 호스트 및 네트워크의 한 호스트에서 실행될 수 있습니다. 이때 Verticles 또는 모듈은 이벤트 버스를 사용하여 통신합니다.
요약하자면 vert.x 애플리케이션은 Verticle 또는 모듈의 조합으로 구성되며 이들 간의 통신은 Event Bus를 사용하여 이루어집니다.