본문 바로가기

Java/Vert.x

버텍스 코어: 버티클(Verticle)

이 문서의 내용

    버티클(Verticle)

    버티클은 Vertx 인스턴스를 사용하여 배포합니다.

    버티클은 Vert.x가 지원하는 여러 언어(Polyglot)로 작성 될 수 있으며 하나의 애플리케이션에서 배포 될 수도 있습니다.

    꼭 여러 언어로 작성되지 않았더라도 Vertx 애플리케이션은 일반적으로 N개의 버티클로 구성됩니다.

    버티클은 Verticle 인터페이스로 구현합니다.

    인터페이스를 implement하여 기본 함수를 직접 구현할 수 있으나 AbstractVerticle 추상 클래스를 사용하는 것이 일반적입니다.

    새로운 버티클 클래스를 작성하고 배포하면 start() 메소드가 호출됩니다.

    start()는 버티클이 배포되기 시작될 때 호출되며, 정상 리턴되면 버티클이 배포 된 것으로 간주합니다.

    stop() 메소드 역시 버티클이 중지되기 시작할 때 호출되며, 정상 리턴되면 버티클이 중지 된 것으로 간주합니다.

    public class MyVerticle extends AbstractVerticle 
    {
    	// 버티클이 Deployment되면 호출
    	public void start() { }
    	// 버티클이 Undeployment되면 호출
    	public void stop() {}
    }

    버티클 비동기 배포 및 중지

    어떤 버티클은 배포되면서 수행해야 하는 작업이 오래 걸릴 수 있습니다.

    예를 들어 , 다음 예제는 버티클이 배포되면서 HTTP 서버를 생성하고 Listen 상태로 만듭니다.

    public void start(Promise<Void> startPromise) {
    	HttpServer server = vertx.createHttpServer().requestHandler(req -> {
    		req.response()
    			.putHeader("content-type", "text/plain")
    			.end("Hello from Vert.x!");
    	});
    		
    	// Now bind the server:
    	server.listen(8080, res -> {
    		if (res.succeeded()) {
    			startPromise.complete();
    		} else {
    			startPromise.fail(res.cause());
    		}
    	});
    }
    코드 설명
    Line 11 비동기 함수 리턴(성공) HTTP 서버가 Listen 상태가 되었을 때 버티클이 완전히 배포됩니다.
    Line 13 비동기 함수 리턴(실패) HTTP 서버가 Listen 상태가 되지 못했다면 버티클 역시 배포되지 않습니다.

    마찬가지로 stop()도 비동기로 처리 할 수 있습니다.

    stop()은 버티클이 중지 되면서 리소스를 반환해야 하는 경우 활용 가능합니다.

    public void stop(Future<Void> stopFuture) {
    	doSomethingThatTakesTime(res -> {
    		if (res.succeeded()) {
    			stopFuture.complete();
    		} else {
    			stopFuture.fail();
    		}
    	});
     }

    Vertx로 생성한 리소스는 버티클이 중지될 때 자동 반환되므로 stop()을 구현해서 처리할 작업은 없을 수 있습니다.

    더보기

    버티클에서 생성된 HTTP 서버를 수동으로 정지할 필요가 없습니다.

    버티클이 undeployment 될 때 Vert.x가 서버를 자동으로 중지해줍니다.

    버티클 유형(Standard & Worker)

    버티클은 두 가지 유형으로 구분됩니다.

    표준 버티클(Standard) 워커 버티클(Worker)
    별도의 배포 옵션을 지정하지 않은 경우입니다.
    이 버티클이 실행하는 코드는 항상 이벤트 루프 스레드(Evnet loop thread)에서 실행됩니다.
    워커를 생성하려면 별도의 배포 옵션을 지정해야 합니다.
    워커 버티클이 실행하는 코드는 워커 풀(Worker pool)이라고 부르는 별도의 스레드 풀에서 실행됩니다.
    단, 워커 버티클 인스턴스가 동시에 두 개 이상의 스레드에서 실행되지는 않습니다.

    표준 버티클은 이벤트 루프 스레드를 할당 받고, 배포되며 중지되기 까지 모든 코드가 동일한 스레드에서 실행됩니다.

    버티클 내부에서 전통적인 방식의 스레드를 생성하지 않는 한 동일한 이벤트 루프 스레드에서 실행됨을 보장합니다.

    워커 버티클은 표준 버티클과 동일하지만 이벤트 루프 스레드 대신 별도로 지정된 워커 스레드 풀에서 실행됩니다.

    이런 이유로 워커 버티클은 이벤트 루프 스레드를 차단하지 않습니다(물론 코드가 실행되는 워커 스레드는 차단됩니다).

    더보기

    워커 버티클은 가장 중요한 이벤트 루프 스레드는 차단시키지 않습니다.

    만약 워커 버티클을 사용하지 않고(이벤트 루프 스레드 내에서) 차단 코드를 실행해야 한다면 도큐먼트에서의 inline blocking code 섹션을 참고합니다.

    워커 버티클을 배포하려면 배포 옵션을 지정해야 합니다.

    DeploymentOptions options = new DeploymentOptions().setWorker(true);
    vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

    워커 버티클은 표준 버티클과 달리 동일한 스레드에서의 실행을 보장하지는 않습니다.

    같은 풀 안의 여러 스레드에 의해서 실행 될 수 있으며, 다만 하나의 버티클 인스턴스가 여러 스레드에서 동시에 실행되지는 않습니다.

    버티클 배포

    Vertx 인스턴스의 deployVerticle를 사용하여 버티클을 배포합니다.

    배포를 위해서는 버티클의 이름 또는 버티클 인스턴스 생성이 필요합니다.

    // 버티클 인스턴스를 생성하여 배포
    Verticle myVerticle = new MyVerticle();
    vertx.deployVerticle(myVerticle);
    
    // 버티클 이름을 사용하여 배포
    vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle");
    더보기

    인스턴스를 사용한 배포는 자바에서만 가능합니다.

    버티클 이름은 VerticleFactory에서 찾을 수 있어야 합니다.

    VerticleFactory에서 확인 가능한 버티클 이름은 배포 메소드를 통해 인스턴싱 됩니다.

    서로 다른 프로그래밍 언어로 작성된 버티클 이름을 찾기 위해 여러 개의 VerticleFactory를 사용할 수 있습니다.

    // Java로 작성된 버티클 클래스 배포
    vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle");
    
    // Javascript로 작성된 버티클 클래스 배포
    vertx.deployVerticle("verticles/myverticle.js");
    
    // Ruby로 작성된 버티클 클래스 배포
    vertx.deployVerticle("verticles/my_verticle.rb");

    버티클의 배포는 비동기로 진행됩니다.

    비동기 처리된 결과를 콜백 받으려면 handler를 사용합니다.

    vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", res -> {
    	if (res.succeeded()) {
    		System.out.println("Deployment id is: " + res.result());
    	} else {
    		System.out.println("Deployment failed!");
    	}
    });
    더보기

    버티클이 정상 배포되면 handler 결과로 배포 ID(Deployment ID)를 수신합니다.

    배포 ID는 버티클은 정지(Undeployment)하기 위해 사용 할 수 있습니다.

    버티클 정지

    배포된 버티클을 정지(Undeployment)하려면 undeploy를 사용합니다.

    배포와 마찬가지로 정지 또한 비동기로 진행됩니다.

    비동기 처리된 결과를 콜백 받으려면 handler를 사용합니다.

    vertx.undeploy(deploymentID, res -> {
    	if (res.succeeded()) {
    		System.out.println("Undeployed ok");
    	} else {
    		System.out.println("Undeploy failed!");
    	}
    });
    더보기

    버티클 정지를 위해 사용하는 배포 ID는 버티클 배포 결과로 수신 할 수 있습니다.

    정리 및 복습

    • 버티클은 여러 언어로 작성(Polyglot) 가능하며 이렇게 작성된 버티클은 하나의 애플리케이션에서 동시에 배포 될 수 있습니다.
    • 새로운 버티클 클래스를 생성하려면 AbstractVerticle을 상속하여 구현합니다.
    • 버티클이 배포될 때 start() 메소드가 호출되고, 중지될 때 stop() 메소드가 호출됩니다.
    • 버티클은 표준 버티클과 워커 버티클로 구분 됩니다.
      • 표준 버티클은 이벤트 루프 스레드에서 실행되며, 하나의 인스턴스는 항상 동일한 스레드에서 실행됩니다.
      • 워커 버티클은 워커 스레드 풀에서 실행되며, 하나의 인스턴스는 여러 스레드에서 실행 될 수 있습니다.
    • 버티클을 배포하려면 deployVerticle, 중지하려면 undeploy를 사용합니다.