장문의 글을 올리기 보다는, 바로 어떤 결과가 나오는 짧은 팁만 올리고, 댓글로 보충 내용을 올리는 쪽으로 해보겠습니다. 방송 형태가 적합하겠지만, 할 줄을 몰라서...(컴맹입니다)
------------------------------------------------------------------------------------------------------
역시나 오랫만에 글을 올립니다. 요즘 좀 많이 게을러지기도 해서...
제목이 살짝 바뀌었습니다. 눈치채신 분 계신가요? 그 사이 Vert.x 의 버전이 3.0.0 에서 3.1.0 으로 올라갔습니다. 몇몇 변화점들이 눈에 띄는데, 그 중에서도 제가 구글 그룹스에 글을 남겼던 부분도 개선이 되었네요. (https://groups.google.com/forum/#!topic/vertx/-ZofvUfbzj8 )
하지만, 일반적인 사용에 있어서는 큰 변화가 없으니...제 앞의 게시물들은 여전히 변경 없이 사용 가능할 것입니다.
이번에 알아볼 것은 config 파일와 LocalMap 입니다.
먼저, config 은 vertx run 을 통해 실행될 때 설정 파일을 읽어오는 기능입니다. Vert.x 는 JSON 을 이용해서 데이터들을 주고 받는 것을 기본으로 하고 있어서인지, 설정 파일 역시 JSON 파일로 읽어올 수 있게 개발되어 있습니다. 그냥 JSON 이 들어있는 파일을 실행 시 옵션으로 가리키면 그 파일을 읽어오는 것이죠.
가령 예를 들면 아래와 같습니다.
vertx run Test6_1.java -conf config.json
-conf 에 파일 경로와 이름을 적어주면 해당 파일을 읽어들입니다. 지금은 java 파일과 같은 위치에 존재하기 때문에 특별히 경로를 적지 않았습니다만, 개발 PC 와 서버마다 VCS 외부에 파일을 위치시켜두고 실행을 배치 파일로 하도록 만들어서 각각의 config 파일을 읽게 해주면 Spring 의 profile 와 같은 역할을 할 수 있습니다. JSON 형태를 읽기 때문에 좀 더 강력하다고 할까요...
위와 같이 실행될 경우 Test6_1.java 는 start() 안에서 context.config() 으로 읽어올 수 있습니다.
하지만, 주의할 것은 이 설정 파일은 Test6_1.java 파일에서만 읽을 수 있으며, Test6_1.java 파일에서 deploy 한 다른 파일에서는 context.config() 으로 받을 수 없다는 것입니다. 대신에, deployVerticle() 시 옵션을 통해 config JSON 을 전달할 수 있습니다(물론 중간에 가공한 뒤 보낼 수도 있겠죠). 아래와 같이 말이죠.
{
"TestMessage": "Hello World"
}
public class Test6_1 extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
EventBus eventBus = vertx.eventBus();
JsonObject config = context.config();
DeploymentOptions options = new DeploymentOptions().setConfig(config);
vertx.deployVerticle("Test6_2.java", options);
vertx.deployVerticle("Test6_3.java", options);
앞 글에서 살펴본 DeploymentOptions 을 통해서 여러 설정을 할 수 있는데, 그 중에 config 파일을 담아서 보내는 기능도 있습니다.
그럼, 다른 Verticle 에서 잘 받는지 구문을 만들어봐야겠죠? 아래와 같이 만들어봤습니다.
public class Test6_2 extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
EventBus eventBus = vertx.eventBus();
JsonObject config = context.config();
eventBus.consumer("Test6_2", (Message<Object> message) -> {
String testMessage = config.getString("TestMessage");
실제로 Test6_1~Test6_3 까지 받으신 후 실행하고서, http://localhost:8080/Test6_2 라고 호출하면 브라우저에 config 안에 있던 "Hello World" 가 출력됨을 아실 수 있을 겁니다.
이번에는 LocalMap 입니다. Vert.x 2.x 에서는 SharedMap 이라고만 있었는데, Vert.x 3 가 나오면서 LocalMap 와 ClusterWideMap 으로 나뉘어졌습니다. 예전의 SharedMap 은 LocalMap 와 동일한 것입니다. Embeded 모드에선 ClusterWideMap 이 의미가 없지만, 실행 모드에서 Cluster 구성을 한 뒤에는 차이가 존재합니다. Vert.x 는 Hazelcast 을 통해 Cluster 을 제공하는데, EventBus 을 여러 instance 의 것을 분산해서 사용할 수 있는 형태입니다. 문제는 다른 JVM 이다보니 일반적인 Object 로는 값의 동기화가 안되기 때문에 Hazelcast 의 공유 Object 을 이용하는데, Vert.x 는 이것을 ClusterWideMap 을 통해서 제공합니다. LocalMap 은 Instance 마다 개별적으로 분리되기 때문에 Cluster 환경에선 LocalMap 와 ClusterWideMap 의 사용에 신중을 기해야 합니다. 그리고, ClusterWideMap 은 반드시 비동기 형태로만 작성되는 것도 유의해야 하구요(Hazelcast 는 아닌데...).
LocalMap 은 다음과 같이 String 기반으로 개체를 구분해서 사용할 수 있습니다. 다음 예제는 다른 Verticle 에서 선언한 LocalMap 을 공유해서 쓰는 것을 보여줍니다.
public class Test6_2 extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
EventBus eventBus = vertx.eventBus();
JsonObject config = context.config();
eventBus.consumer("Test6_2", (Message<Object> message) -> {
String testMessage = config.getString("TestMessage");
LocalMap<String, String> map = vertx.sharedData().getLocalMap("Test6.LocalMap");
String localMapValue = map.get("LocalMapKey");
System.out.println("LocalMapValue : " + localMapValue);
String sCount = map.get("Count");
if (sCount == null) {
sCount = "0";
}
int count = Integer.parseInt(sCount) + 1;
map.put("Count", Integer.toString(count));
localMapValue = "Count" + count;
map.put("LocalMapKey", localMapValue);
message.reply(testMessage);
});
}
위의 config 와 같은 파일에 구현을 했는데, config 의 결과는 웹브라우져에 결과가 전송되도록 되어 있고, 이번 예제는 서버 측 콘솔에 결과가 출력되도록 되어 있습니다. 처음 Test6_2 을 호출하게 되면 콘솔에 LocalMapValue : null 가 출력됩니다. 하지만 다음 요청부터는 Test6_2 을 호출하든, Test6_3 을 호출하든 LocalMapValue : Count1 와 같이 개체에 값이 추가된 것을 확인할 수 있습니다. 이렇게 값을 공유할 수 있다는 것이죠.
오늘은 여기까지...
이 글은 제 개인 블로그(http://zepinos.blogspot.kr)와 okky(http://okky.kr)에만 공개되는 글입니다. 퍼 가는 것은 금해주시고, 링크로 대신해주시기 바랍니다. 당연히 상업적 용도로 이용하시면...저랑 경찰서에서 정모하셔야 합니다. ^^;;;
위에 작성한 코드 등은 실제 컴파일한 것이 아니라 제가 글을 적으면서 키보드 코딩(?...손 코딩의 친구) 한 것이므로, 오류가 있다면 저에게 알려주시면 고맙겠습니다.