조대협 (http://bcho.tistory.com)
서문
예전 BEA나 오라클 시절에, EAI, ESB 등을 가지고 시스템간의 연계 업무를 많이 해왔던 나로써는 오픈 소스 기반의 EAI 프레임웍인 Apache Camel의 경우 상당히 흥미로운 주제였다. 과연 상용 제품 대비 얼마나 현실성있는 integration 기능을 제공할 것인가? 가 가장 큰 궁금증이었다.
BEA WebLogic EAI나, Oracle Service Bus, AIA 등 여러 제품을 이용해서 직접 시스템간의 연계 시나리오도 구현해보고, BMT에서 타社의 솔루션을 테스트도 해봤지만, 먼저 상용 솔루션의 약점은, 솔루션에서 제공하는 시스템간의 연계에 있어서 성능적인 제약이 매우 많이 따른 다는 것이다. 대부분 Message Queue 구조의 비동기 구조를 통해서, 양단간에 데이타 연계를 하는 시나리오가 많은데, 이 경우 비주얼하게 각 단계에 대해서 모니터링은 가능 하지만, 대규모 처리에 있어서 비동기의 약점 때문에 성능적인 제약이 따르고 특히 대규모 메세지 처리에 있어서 그리 매끄럽지 못했던 경험이 있다. BPEL과 같은 제품의 경우 양단간의 연동 시나리오중, 개개별 메세지를 콘솔을 통해서 트레이스할 수 있는데, 하루에 수백,수천건을 연계하는 거래의 경우에는 GUI 콘솔을 통해서 메세지를 전달 내용이나 에러 내용을 추적한다는 것은 애초 부터 불가능한 일이다.
그래서 실제 프로젝트 때에는 송수신 시스템을 연동하는 양쪽의 아답터 (JMS, 메인프레임, TP 모니터, ERP, CRM 등 다양한 시스템과 연동이 필요하기 때문에, 상용 제품에서 지원되는 아답터는 매우 중요하다)와 기본적인 메세지 플로우 이외의 부분은 대부분 직접 구현하였다. 그래서, EAI와 같은 제품에서 필요한 구조와 이런 것을 요구 사항에 맞게 빠르게 만들었으면 하는 프레임웍이 있었으면 했는데, Apache Camel을 보니, EAI와 같은 연계 업무성 프레임웍으로 적합해 보인다.
Apache Camel의 특징을 보면
Message Integration Framework
Camel은 기본적으로 Message Integration Framework이다. Framework임을 강조하는 것은, ESB나 EAI 제품과 같은 솔루션이라기 보다는 이를 개발하기 위한 Framework으로 보는 것이 적절하다고 판단된다.
이유는 ESB나 EAI는 메세지 연동 기능을 수행하기 위한 컨테이너가 있다. (즉 서버가 있다) 아무런 연동 인터페이스가 없더라도, 연동 인터페이스를 수용할 수 있는 컨테이너가 있고, 이 컨테이너들은 모니터링, 로깅등의 관리 기능을 제공한다. 그러나 Camel은 Library이다. 자체적으로 Container를 가지고 있지 않다. 다만, OSGI 컨테이너나 WAS, Spring등에 탑재 되서 돌아갈 수 있다. 쉽게 이야기 하면, EAI나 ESB와 같은 솔루션 제품은 서버를 설치해야 하고, 서버 관리를 위한 관리 콘솔 UI를 제공한다. Camel은 Jar로 된 라이브러리 이다.
상용 제품 연계에는 적절하지 않다.
Camel을 보면, 타 솔루션을 연동하기 위한 아답터, (Camel에서는 Component라고 부른다)가 있다. 약 50여개의 아답터가 있기는 하지만, 기업에서 많이 사용되는 솔루션의 아답터는 턱없이 부족하다. 예를 들어 SAP ERP, Sieble CRM, Tuxedo, AS/400 과 같은 애플리케이션에 대한 아답터 지원이 없다. 상용 제품의 경우 이런 아답터 지원이 강력하다.
반면, DB,FTP,HTTP,JMS와 같이 일반적인 애플리케이션 개발에 사용되는 기술에 대한 아답터는 많이 제공된다.
Apache Camel의 컨셉
Apache Camel의 컨셉을 대략적으로 도식화 해보면 다음과 같다.
Route
먼저 Route 라는 개념을 이해해야 하는데, Route는 “하나의 시스템간의 연동 인터페이스”를 정의한다. 예를 들어 시스템 A에서 B로 웹서비스를 이용해서 연동을 했다면 이것이 하나의 Route가 된다. Route는 1:1 관계뿐만 아니라 1:N의 관계도 지원 하는데, A 시스템에서 B 시스템으로 JMS로 메세지를 보내고, 그후에 C 시스템으로 FTP 파일 전송하는 인터페이스가 있다면, 이 역시 하나의 Route로 정의할 수 있다.
Component
각 Route는 크게 Component와 Processor로 정의 된다. 연계 하고자 하는 송신 시스템과 수신 시스템이 있을때, 각 송신,수신 시스템의 주소(IP등)을 end point라고 정의하며, Component는 일종의 아답터의 개념으로, 송수신 시스템의 프로토콜에 맞는 컴포넌트를 선택해야 한다. 예를 들어 송신 시스템을 FTP로 연동하고 싶다면, FTP 컴포넌트를 , JDBC로 연동하고 싶다면, JDBC 컴포넌트를 사용해야 한다. 컴포넌트는 송신 시스템으로 부터 메세지를 읽어드리고, 수신 시스템으로 메세지를 전송하는 역할을 한다.
Processor
메세지를 읽고 그냥 보내기만 한다면 별 문제가 없겠지만, 시스템간의 연동에는 메세지를 받은 후에 수신 시스템으로 보내기전에 하다못해 로깅을 남기더라도 무엇인가 항상 처리를 한다. 이렇게 송신 시스템으로 부터 받은 메세지를 수신 시스템에 보내기전에 무엇인가 처리를 하는 부분을 Processor라고 하는데, 이 Processor는 그 특징에 따라서 몇가지로 나뉘어 질 수 있다.
1. Message Transformation
Message Format Transformation
메세지의 포맷을 변경하는 작업을 수행한다. 예를 들어 JSON으로 들어온 데이타를 XML로 변경하는 것들이 이에 해당한다.
Message Type Transformation
메세지의 데이타 타입을 변경한다. String으로 들어온 메세지를 jms:TextMessageType으로 변경하는 등의 작업을 수행한다.
이러한 메세지 변환은 Java Class를 정의해서할 수 있으며, 이외에도 Camel에서 미리 제공되는 Converter나, XSLT를 이용한 변환 Apache Velocity의 같은 Template 엔진등 다양한 방법을 이용해서 변환이 가능하다.
2. Routing
메세지 라우팅은 들어온 메세지를 다수의 수신 시스템에 조건에 따라서 라우팅할 수 있는 기능이다.
Processor 단계는 쉽게 생각하면, 메세지를 받은 후, 보내기전에 무엇인가.. 를 하는 곳이다. 앞서 설명한것처럼, 메세지를 변환하거나, 라우팅할 수 도 있고, 로깅을 할 수도 있다. 들어온 메세지에 대해서 유효성 검증을 할 수 도 있다. 이러한 Processor는 자주 사용되는 메세지 변환등의 패턴은 Camel에 의해서 제공되지만, Java 클래스를 구현하면, 무엇이든지 가능하기 때문에 메세지에 대한 거의 모든 처리를 구현할 수 있는 단계이다.
이렇게, “송신 Component à Processor à 수신 Component”로 하나의 Route가 정의되는데, 이렇게 Route를 정의하여 객체화 시키는 것이 RouteBuilder이다. 이렇게 RouteBuilder에 의해서 생성된 Route는 CamelContext에 바인딩이 된다. CamelContext는 SpringContext와 유사한 개념으로 생각하면 된다. Route에 대한 집합이며, Route에 대한 라이플 사이클 (Start up,Stop)등을 관리한다.
간단한 개발 예제
이쯤에서 간단한 예제를 하나 보자. 다음은 FTP로 원격지 디렉토리의 파일을 읽어서 Local Directory에 쓰는 Camel Application이다.
먼저 Maven을 이용해서 다음과 같이 Camel Project를 만든 후에,
mvn archetype:create -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-java -DarchetypeVersion=2.5.0 -DgroupId=camelinaction -DartifactId=order-router
다음과 같은 코드를 구현한다.
public class MyRouteBuilder extends RouteBuilder {
public static void main(String... args) throws Exception {
Main.main(args);
}
public void configure() {
from("ftp://userid@168.1.2.3/camel/src/?password=password&stepwise=false")
.to("file:c:/temp/");
}
}
위의 코드는 RouteBuilder를 구현한 코드로 configure 메서드에서 FTP로 파일을 읽어와서 Local에 저장하는 route를 정의한 예이다.
DSL
눈치가 빠른 사람이라면, 위의 코드가 몬가 이상하다는 것을 느꼈을지도 모르겠다. configure 메서드안에 from(“….”).to(“….”).??
함수().함수() 호출? Java에서 이런 문법이 있었던가?
정확히 이야기 하면 이건 일반적인 Java Coding이 아니라 DSL (Domain Specific Language)이다. DSL은 특수목적으로 정의된 언어를 이야기 하는데, 여기서 사용된 Java DSL은 Route를 효율적으로 정의하기 위해서 Camel에 정의된 내장 스크립트 언어이다.
이 JavaDSL을 이용하면 상당히 쉽게 Route를 구성할 수 있는데, Camel은 이 Java DSL 뿐만 아니라, 다음과 같이 상당히 다양한 DSL을 제공한다.
Spring XML : XML 기반으로 정의된 DSL로 , Spring xml configuration 파일에 정의
Groovy,Scala DSL : Groovy 언어, Scala 언어 기반의 DSL
Annotation DSL : Java Annotation 기반의 DSL
기타 (Kotlin DSL, Bluprint XML etc)
(참고: http://camel.apache.org/dsl.html)
DSL은 Route의 Processor 부분을 정의하는데 주로 사용되는데, 송수신, Component만 정의되면, 사실상 시스템 연계에서 구현해야 되는 부분은 거의 Processor이며, Processor의 로직 대부분은 메세지 처리, 변환,라우팅에 해당하는 내용이기 때문에 특수목적의 DSL을 사용할 수 있으며, 또한 DSL 사용을 통해서 개발 생산성이나 코드양을 획기적으로 줄일 수 있다.
예를 메세지를 스트링으로 받아서 reverse하여, 화면에 출력하는 경우 Java DSL을 이용하면
from("direct:test")
.transform(new Expression() {
@Override
public Object evaluate(Exchange e) {
return new StringBuffer(e.getIn().getBody().toString()).reverse().toString();
}
})
.process(new Processor() {
@Override
public void process(Exchange e) {
System.out.println(e.getIn().getBody());
}
});
인데 반해서, Groovy DSL을 사용하면
from('direct:test')
.transform { it.in.body.reverse() }
.process { println it.in.body }
같이 단지 3줄이면 간단하게 끝난다.
Camel과 EIP
시스템 연동에는 사실 많은 패턴들이 있다. 메세지 변환, 라우팅, 로그 추적을 위한 글로벌 트렌젝션 ID, 장애시 재처리등등 여러가지 방법이 있는데, 이를 패턴화 시켜놓은 것이 Enterprise Integration Pattern (EIP)이다. EIP는
책에 잘 정의 되어 있으니 참고하기 바란다.
사실 Camel에서 반영 및 설계되어 있는 EIP도 이 책에 있는 내용을 대부분 바탕으로 하여 구현되어 있다. (Camel을 쓸려면 이책은 꼭 한번 읽어봐야 하지 않을까 싶다.)
참고 : http://camel.apache.org/enterprise-integration-patterns.html 에 간단하게 대표적인 EIP 들이 정리되어 있다.
상용 지원
오픈소스가 무료이라서 저 비용의 장점을 가지고 있지만, 반대로, 오픈소스는 기술지원이나 교육 부분에서 매우 취약하다. 그래서 RedHat과 같이 오픈소스 제품에 대해서 subscription base로 기술 지원이나 교육 및 컨설팅을 제공하는 회사들이 존재하는데, Apache Camel 역시 http://fusesource.com/ 는 곳에서 상용 기술 지원을 받을 수 있다. (얼마전에 Redhat에 인수되었다.) Fuse Source의 경우, Camel을 이용하여 제품을 만들어서 판매하고 있으며, Camel 프로젝트에 참여하고 있는 Commiter 들을 많이 보유하고 있다고 한다.
http://fusesource.com/products/enterprise-camel/ 들어가면 Fuse Source에서 개발 및 판매하는 상용 Camel을 다운로드 받을 수 있으며, 개발 관련 및 트레이닝 자료들을 살펴볼 수 있다.
결론
짧은 시간내에 살펴본 제품이라서 아직 완벽한 특성은 파악하지는 못했다. 그러나 EAI나, ESB와 같이 메세지 기반의 연동 처리를 하기 위한 시스템을 개발한다면, 개발 프레임웍으로 충분히 활용할만 하다. 특히 엔터프라이즈의 특정 애플리케이션 (ERP,CRM)등이 아니라 일반적인 프로토콜 (HTTP,JMS,TCP)등을 사용하여 그리 복잡하지 않으면서 고속의 연동 처리를 필요로 한다면 아주 유용하게 사용할 수 있을 것이라 판단된다.
시간 관계상 에러처리, 모니터링, 배포 및 확장성등 운영 관점에 대한 부분은 깊게 살펴보지 못했지만, 그냥 개발 프레임웍으로 본다면, 어짜피 운영 관련 부분은 직접 구현해야 하니까는 괜찮지 않을까 싶다.
다만 단순히 프레임웍이기 때문에, 클러스터링 기반의 HA나 부하 분산등의 기능을 제공하지 않는 것이 아쉬운 점이다.
시스템간의 연동의 중요성과 편이성을 경험한 나한테는, Apache Camel은 “물건은 물건이다.” 라는 결론이 적절하다고나 할까?
ErrorHandling - http://bcho.tistory.com/716
참고:ErrorHandling에 대한 관련글 -
http://www.consulting-notes.com/2010/08/camel-exception-handling-overview.html
정리가 잘되어 있네...
'아키텍쳐 > EAI' 카테고리의 다른 글
Apache Camel Error Handling (0) | 2013.02.20 |
---|---|
EAI (Enterprise Application Integration) 추진 전략 (2) | 2009.07.16 |
ETL vs EAI (0) | 2009.06.16 |
EAI 도입 전략 (0) | 2007.08.21 |