- Data Microservice in Spring Framework
이 글은, Spring Cloud DataFlow 를 필자가 전혀 모를때, 잠시 공부한 후 급하게 작성했던 글입니다.
https://docs.spring.io/spring-cloud-dataflow/docs/current/reference/htmlsingle/
나중에 시간이 된다면, 각잡고 글을 다시 작성해보겠습니다.
Spring Cloud DataFlow 에 대한 기본적인 개념 및 샘플 예제를 정리한다.
Spring Cloud DataFlow 개요
Spring Cloud DataFlow 필수 컴포넌트
Spring Cloud DataFlow Getting Started
Stream 애플리케이션 구현하기
Rest API 활용하기
Spring Cloud DataFlow 는 Spring XD 라는 프로젝트에서 발전된 프로젝트로, 데이터파이프라인을 구축 기능을 제공하는 Pivotal 의 오픈소스 프로젝트이다. 다양한 런타임 환경에서 스프링 부트 애플리케이션을 결합하여 실시간 데이터 통합 또는 실시간 데이터 처리 등의 기능을 수행한다. 국내 도입 사례가 거의 없어서 필자는 솔직히 확 와닿지가 않는데, 조금 멋지게 표현하면 Microservice Data Flow Orchestrates 라고 표현할수 있을것 같다.
Microservice Data Flow Orchestrates
설명 추가 예정
Spring Cloud DataFlow 는 크게 Streams(스트림) 과 Tasks(태스크)로 프로세스를 구현할 수 있다.
Streams : long running sequences of things
Tasks : one and done (although you can repeat)
이벤트 기반에서는 Stream 를 사용하고, 배치 또는 일회성 Job 은 Task 를 사용하면 될 것 같다. 이번 글에서는 Streams 에 대해서만 정리한다.
Spring Cloud DataFlow는 Microservice Application 를 등록, 모니터링, 원격관리 등의 긴으을 수행한다.
DashBoard
Rest API
Console Shell
Spring Cloud DataFlow 는 RabbitMQ 또는 Kafka 를 메시지 브로커로 사용한다. 필자는 RabbitMQ 를 기반으로 테스트를 진행하였다.
Spring Cloud DataFlow 는 Modern Application Runtime 환경에서 운영하는 것이 좋다. Local 서버에서 실행해도 되기는 하지만 실서비스에 추천하지는 않는다.
Cloud Foundry
Kubernetes
Apache YARN
Apache Mesos
Local Server
Stream App, Task App 의 실행 정보를 저장하기 위해 DB 연동이 필요하다. 특별한 설정을 하지 않는다면 기본적으로 H2 인메모리 환경으로 실행이 된다. 하지만, 휘발성 데이터로 실서비스 운영하기에는 적합하지 않다.
실행하기 위한 App의 저장소를 구축해야 한다. Docker Registry 또는 Maven 으로 구성하면 된다. 저장소가 준비가 안되었다면, 빠르게 구동하기 뒤해서는 File System 기반으로 가능하다. 역시, 실서비스 용도로는 FileSystem 은 적합하지 않다.
필자는 RabbitMQ를 선택하였다. 설치 과정은 생략
Spring Cloud DataFlow 을 로컬서버에 설치해보자. 추가로 콘솔 Shell 도 같이 설치하면 된다. 참고로, 실서버에서는 Modern Application Runtime 환경에 구축해야 할 것이다.
1. Jar 다운로드
wget https://repo.spring.io/release/org/springframework/cloud/spring-cloud-dataflow-server-local/1.5.0.RELEASE/spring-cloud-dataflow-server-local-1.5.0.RELEASE.jar
wget https://repo.spring.io/release/org/springframework/cloud/spring-cloud-dataflow-shell/1.5.0.RELEASE/spring-cloud-dataflow-shell-1.5.0.RELEASE.jar
2. 실행
//기본으로 실행하는 명령어는 아래와 같다.
$ java -jar spring-cloud-dataflow-server-local-1.5.0.RELEASE.jar
//필자는 배포 스크립트를 만들어서 실행하였다.
start.sh
nohup java -jar spring-cloud-dataflow-server-local-1.5.0.RELEASE.jar --spring.cloud.dataflow.applicationProperties.stream.spring.cloud.stream.binders.rabbit3.type=rabbit --spring.cloud.dataflow.applicationProperties.stream.spring.cloud.stream.binders.rabbit3.environment.spring.rabbitmq.host=localhost --spring.cloud.dataflow.applicationProperties.stream.spring.cloud.stream.binders.rabbit3.environment.spring.rabbitmq.port=5672 --spring.cloud.dataflow.applicationProperties.stream.spring.cloud.stream.binders.rabbit3.environment.spring.rabbitmq.username=rabbitmq --spring.cloud.dataflow.applicationProperties.stream.spring.cloud.stream.binders.rabbit3.environment.spring.rabbitmq.password=1234
실행 스크립트에 메시지 브로커의 Global Property 설정을추가한 것이다. Global 설정으로, 각각의 마이크로서비스 애플리케이션에서 메시지 브로커 설정을 하지 않아도 된다. 자동으로, Global 에 설정된 속성 값을 따라서 적용 되는 것이다. 어쨋든 배포 스크립트는 각자 개발환경에 맞게 구성하면 된다. 필자는, 메시지 브로커 로 RabbitMQ 를 선택하였고, 바인더 이름을 rabbit3, 포트는 기본 접속 포트인 5672, 아이디와 패스워드는 rabbitmq/1234 로 설정하였다.
Spring Cloud DataFlow 에 올라오는 스프링 부트 애플리케이션이 해당 메시지 브로커를 통해서 통신 할 것이다!!
아참! 그리고, 이렇게 올리는건 인메모리 환경으로 올리는 것이다. 실서버에서는 RDBMS 에 연동을 하는게 좋을 것이다. 인메모리 환경이므로, 등록한 Spring Cloud DataFlow Streams, Tasks 등 등록한 정보와 실행 기록 등 각종 데이터가 서버 재부팅으로 모두 사라질 것이다. 만약, mysql 에 연동을 하다면 아래와 같이 Properties 설정을 추가해서 서버를 실행하면 된다.
java -jar spring-cloud-dataflow-server-local-1.5.0.BUILD-SNAPSHOT.jar --spring.datasource.url=jdbc:mysql://ip:3306/databasename --spring.datasource.username=userid --spring.datasource.password=password --spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
콘솔 Shell 을 사용하기 위해서는 아래 명령어로 실행하면 된다.
java -jar spring-cloud-dataflow-shell-1.5.0.RELEASE.jar
생략
아주 간단한 스트림을 등록해보자. 아래 공식 가이드를 참고하였다.
1. Register applications.
2. Create a Stream Definition.
3. Deploy the Stream.
Spring Cloud DataFlow UI 에서 직접 등록이 가능하지만, 필자는 콘솔 Shell 에서 실행한다. RabbitMQ 용도로 제공하는 http 라는 source타입의 애플리케이션과, log 라는 sind 타입의 애플리케이션을 등록하자.
dataflow:>app register --name http --type source --uri maven://org.springframework.cloud.stream.app:http-source-rabbit:1.2.0.RELEASE
dataflow:>app register --name log --type sink --uri maven://org.springframework.cloud.stream.app:log-sink-rabbit:1.1.0.RELEASE
애플리케이션을 등록하였으니 이제 httptest라는 이름의, Streams 을 생성하고, 배포하자.
dataflow:>stream create --name httptest --definition "http --server.port=9000 | log".
dataflow:> stream deploy --name httptest
정상적으로 배포가 된다면, 9000 포트가 생성될 것이다. 그리고 런타임 메뉴에서 애플리케이션의 상태가 DEPLOYING ---> DEPLOYED 로 변경 될 것이다. 더 정확히는 로그를 확인해야 한다. 런타임 메뉴에서 아래와 같이 로그 경로를 확인할 수 있는데, stdout 로그를 보자.
로그를 tailf 로 띄어놓고 쉘에서 http 애플리케이션으로 테스트를 위해서 통신을 해보자.
dataflow:>http post --target http://localhost:9000 --data "My name Is Sieun"
드디어 아래와 같이 정상적으로 Stream 이 실행 및 최종 로그가 찍히는 것을 확인 할 수 있다.
아참! 참고로 RabbitMq 에서는 당연히, Queue 가 생성될 것이고, 메시지 통신 결과를 모니터링 할 수 있다. 이번 글의 주제는 RabbitMQ 는 아니기 때문에 자세한 설명은 넘어간다. Kafka 로 연동하는게 더 좋을 수도 있다. 시스템 환경에 따라서 알아서 판단하길 바란다.
최근에는 Docker 환경으로 구축을 많이 한다. 애플리케이션도 Docker Registry 로 올리고, Spring Cloud DataFlow도 마찬가지로 Docker 로 올릴 수 있다.
개발 가이드는 아래 링크를 참고하면 되지만, 내용이 다소 부실하다. ㅠㅠ
위에 설명한대로 Spring Cloud DataFlow 에 등록하는 Application은 Maven 주소만 있으면 등록이 가능하다. 즉, 다른 사람이 만든 애플리케이션도 등록할 수 있다는 얘기다. 기본적으로 App Starter 를 제공해주며, 굳이 커스터마이징이 필요없다면 그대로 사용해도 된다. 한번에 여러개의 애플리케이션 등록도 가능한데, RabbitMQ 용으로 제공하는 기본 App 을 등록해보자.
dataflow:>app import --uri http://bit.ly/stream-applications-rabbit-maven
다양한 애플리케이션이 등록된 것을 확인할 수 있다. 그대로 쓸수 있는 것들은 사용하고 따로 구현이 필요한 애플리케이션만 구현하면 된다.
샘플 1
아주 간단하게 파일을 읽어서, 텍스트를 변경하는 프로세스를 구현해보자. 등록하는 DSL 문법은 file --directory='/tmp/input' | parsing | log 로 설정하였다. tmp/input 디렉토리에 파일이 추가되면 자동으로 체크해서 프로세스를 실행할 것이다.
file 과 log 는 기본 App 을 등록하고, parsing 는 필자가 구현한 애플리케이션이다. parsing 애플리케이션은 org.springframework.cloud:spring-cloud-starter-stream-rabbit 디펜던시를 포함하며, 아래와 같이 간단하게 구현하면 된다.
@SpringBootApplication
@EnableBinding(Processor.class)
@Slf4j
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public String transform(byte[] payLoad) {
log.info("Processor", payLoad);
//Byte 를 String 타입 및 소문자로 변환해서 리턴
String byteToString = new String(payLoad,0,payLoad.length);
return byteToString.toLowerCase();
}
}
디렉토리에 간단한 텍스트 파일을 넣으면 log 애플리케이션에서 메시지를 출력하는 것을 확인할 수 있다.
Spring Cloud DataFlow 는 Rest API 를 제공한다. 추가로, DataFlowOperation 도 제공하니 함께 사용하는 것이 좋을 것 같다. org.springframework.cloud.dataflow.rest.client 패키지를 디펜던시 추가하고, DataFlowOperations를 사용할수 있고, 아래와 같이 다양한 인터페이스를 활용할 수 있다.
StreamOperations : REST client for stream operations
CounterOperations : REST client for counter operations
FieldValueCounterOperations : REST client for field value counter operations
AggregateCounterOperations : REST client for aggregate counter operations
TaskOperations : REST client for task operations
JobOperations : REST client for job operations
AppRegistryOperations : REST client for app registry operations
CompletionOperations : REST client for completion operations
RuntimeOperations : REST Client for runtime operations
Spring Cloud DataFlow 에 대해서 간단하게 정리를 해봤다. 근데, 솔직히 Spring Cloud DataFlow 를 어떤 용도로 사용하는지 정확히 이해가 되지 않는다. 대략적으로는, 마이크로서비스 환경에서의 데이터 처리 또는 분석 등의 기능으로 사용할 수 있을 것 같지만, 솔직히 아직은 잘 모르겠다. 혹시라도, Spring Cloud DataFlow 의 용도? 및 활용 범위에 대해서 자세히 알고 있거나, 사용 사례가 있다면 피드백을 부탁한다.
제발!!! ㅠㅠ