컨테이너, 마이크로서비스, NoSQL은 최신 애플리케이션을 구축하기 위한 멋진 3인방을 제공합니다. 이러한 애플리케이션은 민첩해야 하고, 끊임없이 진화하는 고객의 요구를 충족해야 하며, 널리 퍼져 있어야 하고, 모바일, 웹 및 IoT 플랫폼 전반에서 작동해야 합니다.
이 블로그에서는 다음을 사용하여 간단한 마이크로서비스 스택에 대해 설명합니다. 와일드플라이 군단, Docker및 카우치베이스. 이 블로그의 전체 코드와 지침은 에 문서화되어 있습니다: github.com/arun-gupta/wildfly-swarm-couchbase.
먼저 이 스택의 주요 구성 요소를 이해해 보겠습니다!
와일드플라이 군단 를 사용하면 JavaEE 애플리케이션을 다음과 같은 서버 런타임에 필요한 만큼만 패키징하여 실행할 수 있습니다. java -jar 애플리케이션을 검색할 수 있습니다. 서비스 검색 기능이 내장되어 있습니다, 키클로크를 사용한 싱글 사인온, Hawkular를 사용한 모니터링등 다양한 기능을 갖춘 WildFly Swarm은 마이크로서비스를 개발하는 데 필요한 모든 구성 요소를 제공합니다.
Mac용 Docker 는 Mac OSX에서 Docker 컨테이너를 실행하기 위한 기본 지원을 제공합니다. 이는 다음을 기반으로 합니다. Hypervisor.framework 를 지원합니다. 도커 엔진은 알파인 리눅스 배포판에서 실행됩니다. xhyve 가상 머신을 관리할 수 있으며, 가상 머신도 Docker에서 관리합니다. Docker Machine이나 VirtualBox가 필요하지 않으며, OSX 보안 샌드박스 모델과 통합됩니다. DockerCon 2016에서는 Mac용 Docker의 비공개 베타 제한이 제거되어 이제 누구나 사용할 수 있습니다. 
NoSQL 는 스키마가 없는 데이터베이스의 민첩성과 유연성을 제공합니다. 따라서 번거로운 데이터베이스 마이그레이션을 거치지 않고도 애플리케이션을 독립적으로 빠르게 발전시킬 수 있습니다. Couchbase는 다음을 통해 진정한 수평적 확장을 제공합니다. 동질적인 아키텍처확장 불가능한 마스터/슬레이브 아키텍처와는 대조적입니다. 또한 자동 샤딩을 제공합니다, JSON을 위한 SQL과 유사한 쿼리 언어 (N1QL), 모바일 데이터베이스 백엔드 서버와의 동기화 등 다양한 기능을 제공합니다. 이 블로그의 전체 샘플 애플리케이션은 여기에서 확인할 수 있습니다: github.com/arun-gupta/wildfly-swarm-couchbase.
WildFly 스웜 애플리케이션
Java EE REST 엔드포인트를 살펴보겠습니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.couchbase.wildfly.swarm; . . . @Path("airline") public class AirlineResource { @Inject Database database; @GET public String getAll() { N1qlQuery query = N1qlQuery.simple("SELECT * FROM `travel-sample` LIMIT 10"); N1qlQueryResult result = database.getBucket().query(query); return result.allRows().toString(); } . . . } |
표준 JAX-RS 어노테이션을 사용하여 POJO를 REST 엔드포인트로 변환합니다. 카우치베이스 자바 API 는 유창한 API를 제공하고 N1QL 문을 사용하여 문서를 쿼리하고 결과를 반환합니다. N1QL 문은 쿼리 결과에서 처음 10개의 요소를 반환합니다. 이 문서에서 N1QL 구문에 대해 자세히 알아보세요. 대화형 튜토리얼. 데이터베이스 추상화는 다음과 같이 정의됩니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.couchbase.wildfly.swarm; . . . @Singleton @Startup public class Database { CouchbaseCluster cluster; Bucket bucket; public CouchbaseCluster getCluster() { if (null == cluster) { String couchbaseURI = System.getenv("COUCHBASE_URI"); if (null == couchbaseURI) { System.err.println("WARING: No COUCHBASE_URI specified, defaulting to localhost"); couchbaseURI = "localhost:8093"; } System.out.println("Couchbase endpoint: " + System.getenv("COUCHBASE_URI")); cluster = CouchbaseCluster.create(couchbaseURI); } return cluster; } public Bucket getBucket() { if (null == bucket) { bucket = getCluster().openBucket("travel-sample"); } return bucket; } } |
이것은 열심히 초기화되는 싱글톤 EJB입니다. 이것은 카우치베이스 자바 SDK 를 클릭하여 Couchbase에 연결합니다. 데이터베이스 엔드포인트는 다음을 사용하여 지정할 수 있습니다. COUCHBASE_URI 환경 변수입니다. 다음은 pom.xml 와 와일드플라이 스웜을 구성하기 위한 카우치베이스 자바 클라이언트:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
org.wildfly.swarm bom ${version.wildfly-swarm} pom import javax javaee-web-api 7.0 provided org.wildfly.swarm jaxrs-cdi org.wildfly.swarm ejb com.couchbase.client java-client 2.2.5 |
모든 종속성을 가져오기 위해 WildFly Swarm "자재 명세서"를 사용합니다. 빌드에 필요한 특정 종속성만 빌드에 필요한 종속성만 . 그런 다음 "뚱뚱한 항아리"에 패키징됩니다. 애플리케이션을 패키징하고 실행하는 데는 WildFly Swarm Maven 플러그인이 사용됩니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
org.wildfly.swarm wildfly-swarm-plugin ${version.wildfly-swarm} package ${COUCHBASE_URI} |
COUCHBASE_URI 는 카우치베이스 데이터베이스 서버가 실행되고 있는 호스트를 읽는 데 사용됩니다.
카우치베이스 서버 실행
Mac용 Docker를 사용하여 Couchbase 서버를 실행합니다:
|
1 |
docker run -d --name db -p 8091-8093:8091-8093 -p 11210:11210 arungupta/couchbase |
그리고 아룽업타/카우치베이스 는 표준 카우치베이스 이미지 및 용도 Couchbase REST API 를 클릭해 서버를 구성합니다. 샘플 버킷이 JSON 문서로 채워질 때까지 몇 분 정도 기다립니다. 샘플 버킷에서 카우치베이스 CLI 도구 cbq 샘플 버킷에 기본 인덱스를 생성합니다:
|
1 |
docker run -it --link db:db arungupta/couchbase cbq -u Administrator -p password -engine https://db:8093 -s "create primary index `travel-sample-primary-index` on `travel-sample`;" |
출력은 다음과 같이 표시됩니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Connected to : https://db:8093/. Type Ctrl-D or QUIT to exit. Path to history file for the shell : /root/.cbq_history { "requestID": "d0b2e4dd-b702-49e2-971c-a4c640ddb498", "signature": null, "results": [ ], "status": "success", "metrics": { "elapsedTime": "3.154540272s", "executionTime": "3.154493281s", "resultCount": 0, "resultSize": 0 } } |
이 출력은 인덱스 생성 결과가 성공했음을 보여줍니다. Mac용 Docker를 실행할 때의 장점 중 하나는 모든 컨테이너를 다음 위치에서 액세스할 수 있다는 것입니다. localhost. 이는 다음을 의미합니다. 카우치베이스 웹 콘솔 에서 액세스할 수 있습니다. localhost:8091. 
이 화면에서는 Couchbase가 올바르게 구성되었는지 확인합니다.
WildFly 스웜 마이크로서비스 실행
독립형 마이크로서비스를 패키징하고 실행합니다:
|
1 |
mvn wildfly-swarm:run |
Couchbase가 다른 호스트에서 실행 중인 경우 명령이 다음과 같이 변경됩니다:
|
1 |
mvn -DCOUCHBASE_URI= wildfly-swarm:run |
출력은 다음과 같이 표시됩니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building nosql-microservices 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] . . . 2016-06-27 22:21:47,170 WARN [org.jboss.as.dependency.private] (MSC service thread 1-6) WFLYSRV0018: Deployment "deployment.nosql-microservices.war" is using a private module ("org.jboss.jts:main") which may be changed or removed in future versions without notice. 2016-06-27 22:21:47,203 INFO [org.jboss.weld.deployer] (MSC service thread 1-1) WFLYWELD0003: Processing weld deployment nosql-microservices.war 2016-06-27 22:21:47,542 INFO [org.hibernate.validator.internal.util.Version] (MSC service thread 1-1) HV000001: Hibernate Validator 5.2.3.Final 2016-06-27 22:21:47,600 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named 'Database' in deployment unit 'deployment "nosql-microservices.war"' are as follows: java:global/nosql-microservices/Database!com.couchbase.wildfly.swarm.Database java:app/nosql-microservices/Database!com.couchbase.wildfly.swarm.Database java:module/Database!com.couchbase.wildfly.swarm.Database java:global/nosql-microservices/Database java:app/nosql-microservices/Database java:module/Database 2016-06-27 22:21:47,731 INFO [org.jboss.weld.deployer] (MSC service thread 1-3) WFLYWELD0006: Starting Services for CDI deployment: nosql-microservices.war 2016-06-27 22:21:47,758 INFO [org.jboss.weld.Version] (MSC service thread 1-3) WELD-000900: 2.3.2 (Final) 2016-06-27 22:21:47,780 INFO [org.wildfly.extension.undertow] (MSC service thread 1-1) WFLYUT0018: Host default-host starting 2016-06-27 22:21:47,788 INFO [org.jboss.weld.deployer] (MSC service thread 1-8) WFLYWELD0009: Starting weld service for deployment nosql-microservices.war 2016-06-27 22:21:48,180 INFO [stdout] (ServerService Thread Pool -- 10) Couchbase endpoint: 2016-06-27 22:21:48,275 INFO [com.couchbase.client.core.CouchbaseCore] (ServerService Thread Pool -- 10) CouchbaseEnvironment: {sslEnabled=false, sslKeystoreFile='null', sslKeystorePassword='null', queryEnabled=false, queryPort=8093, bootstrapHttpEnabled=true, bootstrapCarrierEnabled=true, bootstrapHttpDirectPort=8091, bootstrapHttpSslPort=18091, bootstrapCarrierDirectPort=11210, bootstrapCarrierSslPort=11207, ioPoolSize=8, computationPoolSize=8, responseBufferSize=16384, requestBufferSize=16384, kvServiceEndpoints=1, viewServiceEndpoints=1, queryServiceEndpoints=1, searchServiceEndpoints=1, ioPool=NioEventLoopGroup, coreScheduler=CoreScheduler, eventBus=DefaultEventBus, packageNameAndVersion=couchbase-jvm-core/1.2.5 (git: 1.2.5), dcpEnabled=false, retryStrategy=BestEffort, maxRequestLifetime=75000, retryDelay=ExponentialDelay{growBy 1.0 MICROSECONDS, powers of 2; lower=100, upper=100000}, reconnectDelay=ExponentialDelay{growBy 1.0 MILLISECONDS, powers of 2; lower=32, upper=4096}, observeIntervalDelay=ExponentialDelay{growBy 1.0 MICROSECONDS, powers of 2; lower=10, upper=100000}, keepAliveInterval=30000, autoreleaseAfter=2000, bufferPoolingEnabled=true, tcpNodelayEnabled=true, mutationTokensEnabled=false, socketConnectTimeout=1000, dcpConnectionBufferSize=20971520, dcpConnectionBufferAckThreshold=0.2, queryTimeout=75000, viewTimeout=75000, kvTimeout=2500, connectTimeout=5000, disconnectTimeout=25000, dnsSrvEnabled=false} 2016-06-27 22:21:48,829 INFO [com.couchbase.client.core.node.Node] (cb-io-1-1) Connected to Node localhost 2016-06-27 22:21:49,035 INFO [com.couchbase.client.core.config.ConfigurationProvider] (cb-computations-1) Opened bucket travel-sample 2016-06-27 22:21:49,415 INFO [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool -- 10) RESTEASY002225: Deploying javax.ws.rs.core.Application: class com.couchbase.wildfly.swarm.MyApplication 2016-06-27 22:21:49,438 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 10) WFLYUT0021: Registered web context: / 2016-06-27 22:21:49,457 INFO [org.jboss.as.server] (main) WFLYSRV0010: Deployed "nosql-microservices.war" (runtime-name : "nosql-microservices.war") |
이제 애플리케이션에 다음 계정으로 액세스할 수 있습니다:
|
1 |
curl https://localhost:8080/webresources/airline |
형식이 지정된 출력은 다음과 같습니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[ { "travel-sample": { "country": "United States", "iata": "Q5", "callsign": "MILE-AIR", "name": "40-Mile Air", "icao": "MLA", "id": 10, "type": "airline" } }, . . . { "travel-sample": { "country": "France", "iata": "A5", "callsign": "AIRLINAIR", "name": "Airlinair", "icao": "RLA", "id": 1203, "type": "airline" } } ] |
따라서 Docker 컨테이너로 실행되는 Couchbase 데이터베이스에 액세스하는 WildFly Swarm을 사용하여 간단한 마이크로서비스를 구축했습니다. 이제 이상적으로는 이 WildFly Swarm 서비스를 Docker 이미지로 패키징한 다음 해당 Docker 이미지가 서비스 역할을 하도록 해야 합니다. 이름이 도커 에 이미 추가되어 있습니다. pom.xml 하지만 이슈 #3 이 시나리오를 실패하게 만들고 있습니다.
