2014년 11월 20일 목요일

Apache Camel을 이용한 대출 모집인 구현


이 글은 팁코 액티브엔터프라이즈(TIBCO ActiveEnterpise) 기반 통합 솔루션을 Apache Camel 기반 통합 솔루션으로 대체하는 방법을 설명합니다.

1. 들어가며

기업 통합 패턴(Enterprise Integration Patterns)의 "9장 사잇장: 복합 메시징"에서는 대출 모집인을 세가지 통합 도구를 각각 이용해 실질적인 통합 솔루션을 구현하는 예들을 설명한다. 첫째 예는 SOAP 프레임워크인 Apache Axis를 이용하고, 둘째 예는 마이크로소프트 MSMQ를 이용하고, 셋째 예는 상용 EAI 제품인 팁코 액티브엔터프라이즈(TIBCO ActiveEnterprise)를 이용한다. 이 책 9장에 등장하는 예들의 특징을 표로 보이면 다음과 같다.

구현
실행 방식
주소 지정
수집 전략
채널 형식
기술
1
동기
수신자 목록
채널
웹 서비스/SOAP
자바/아파치 액시스
2
비동기
수신자 목록
상관관계 식별자
메시지 큐
C#/마이크로소프트 MSMQ
3
동기,비동기
게시 구독 채널
상관관계 식별자
게시 구독
팁코 액티브엔터프라이즈

위 구현 예들은 중 "팁코 액티브엔터프라이즈를 이용한 구현"은 앞의 다른 예들과 달리 동기 요청과 비동기 메시징이 결합됐다는 점에서 차이가 있다. 즉 첫째 예는 SOAP을 이용한 동기 호출 기반의 솔루션이고, 둘째 예는 마이크로소프트 MSMQ를 이용한 비동기 메시징 솔루션인데, 셋째 예는 팁코 액티브엔터프라이즈를 이용해 요청은 동기로 수신하고 후속 처리는 비동기 메시징을 이용한다. 셋째 예의 메커니즘을 좀더 구체적으로 설명하면, "팁코 액티브엔터프라이즈를 이용한 구현" 예의 대출 모집인은 대출 클라이언트로부터 대출 견적을 동기로 요청 받아, 동기 호출로 신용 평가 기관에서 대출 클라이언트의 신용 점수를 얻고, 은행들에게 비동기 게시 구독 채널로 견적 요청을 브로드캐스트하고, 각 은행들로부터 대출 견적 응답을 비동기 메시지 큐(서브젝트)로 수집해, 최상 대출 견적을 대출 클라이언트에게 동기 응답으로 반환한다. 여기서 중요한 점은 상용 EAI 제품을 이용했다는 점이다.

그런데 기업 통합 패턴에서는 이런 메커니즘에 대한 해결책이 의도적이든 의도적이지 않든 부실하다. ("팁코 액티브엔터프라이즈를 이용한 구현"에서만 동기, 비동기의 결합에 대한 전체적인 예를 살펴볼 수 있다.) 기업 통합 패턴은, 비동기 메시징을 전제로 해결책들을 제시하는 책이므로, 비동기 인프라에서 동기 인프라에 접근하기 위한 패턴으로 서비스 액티베이터 패턴[EIP]을 설명하고, 애플리케이션이 비동기 인프라에 접근하기 위한 패턴으로는 메시징 게이트웨이 패턴[EIP]을 설명한다. 이와 같이 "팁코 액티브엔터프라이즈를 이용한 구현" 예를 벗어난 곳에서는 동기 인프라와 비동기 인프라가 결합된 종합적인 해결책을 비중 있게 다루지는 않는다. 상관관계 식별자 패턴[EIP]을 활용할 수도 있지만, 상관관계 식별자 패턴은 주로 비동기 요청의 응답을 상관시키기 위한 패턴이다.

이에 반해 팁코 액티브엔터프라이즈 같은 상용 EAI 제품들은 동기 호출과 비동기 응답을 상관시키는 종합적인 메커니즘을 내장한다. 이 기술은 간단한 것처럼 보이지만 실상은 그렇지 않다. 동기 호출은 응답을 반환할 때까지 동기 프로세스(스레드)가 (중간) 처리 결과와 처리 상태를 유지하는 반면, 비동기 메시징에서는 (중간) 처리 결과는 메시지와 필터 프로세스(스레드)들에 유지되고 처리 상태는 메시지가 위치한 채널로 관리한다. 즉 동기 호출과 비동기 메시징의 처리 결과와 상태 관리는 완전히 다른 방식이다.

그렇다면 동기 호출과 비동기 메시징을 결합하기 위해서는 상용 EAI 제품만 사용해야 하는 것일까? 그렇지 않다. 통합 프레임워크를 이용한다면 얼마든지 상용 EAI 제품처럼 동기 호출과 비동기 메시징을 결합할 수 있다. 그러므로 이 기능 때문에 상용 EAI 제품을 선택해야 한다는 기준은 전제하지 않아도 될 것이다.


2. 대출 모집인 솔루션 아키텍처 비교

기업 통합 패턴 9장의 "팁코 액티브엔터프라이즈를 이용한 구현" 예의 팁코 대출 모집인 솔루션 아키텍처는 다음과 같다.

위 아키텍처 그림에서 테스트 대출 클라이언트와 대출 모집인 사이와 대출 모집인과 신용 평가 기관 사이는 팁코의 동기 랑데부 전송을 사용하고, 대출 모집인과 은행들 사이는 비동기 랑데부 전송을 사용한다. 중간의 프로세스 관리자는 팁코의 시각적 도구와 스크립트와 메타 저장소 등을 이용하여 메시지 송수신 흐름과 처리 상태를 관리한다. 보다시피 동기 메커니즘과 비동기 메커니즘이 결합되어 있다. (이 솔루션 아키텍처는 기업 통합 패턴의 복합 메시징의 예를 보여주기 위해 모든 통신 인프라를 팁코 랑데부 통신으로 구성한 것이다. 실무적을 보면 대출 클라이언트는 원격지에서 인터넷으로 대출 모집인에 접속할 것이고, 신용 평가 기관이나 은행들도 원격지에 위치해 전용선이나 인터넷으로 대출 모집인을 연결할 것이다.)

위 솔루션 아키텍처에 대응되는 "Apache Camel을 이용한 대출 모집인 솔루션 아키텍처"는 다음과 같다.

"팁코 액티브엔터프라이즈를 이용한 구현"에서 달라진 점은 Apache Camel을 이용한 대출 모집인 솔루션은 팁코 동기 랑데부 전송을 좀더 범용적인 SOAP/HTTP 전송으로 대체하고, 팁코 비동기 랑데부 전송을 내부 메시징과 Apache ActiveMQ의 JMS Topic으로 대체하고, 프로세스 관리자를 프로세스 관리자(웹 서비스 빈) 라우팅과 응답 관리자 라우팅으로 대체한다는 점이다.


3. 대출 클라이언트 인터페이스


3.1. 대출 모집인

앞서도 간단히 언급했듯이 "Apache Camel를 이용한 구현"은 "팁코 액티브엔터프라이즈를 이용한 구현"의 팁코 동기 랑데부 전송을 SOAP/HTTP 동기 웹 서비스로 대체한다. 이를 위해 대출 모집인은 대출 견적 요청 서비스를 스프링 설정 파일에 SOAP 웹 서비스 인터페이스 빈으로 다음과 같이 노출한다.

brokerQouteServiceEndpoint 빈은 웹 서비스 인터페이스 객체고, brokerQouteServiceImp 빈은 웹 서비스 객체다. BrokerQouteServiceImp 빈 클래스가 웹 서비스를 실제 수행한다. 그러므로 BrokerQouteServiceImp 클래스가 실제 프로세스 관리자[EIP]다. 여기서는 서비스 우선 개발(service first development) 방법에 따라 웹 서비스 인터페이스를 먼저 정의했다. 이 설정으로 대출 클라이언트에 대한 대출 모집인의 SOAP 웹 서비스 노출을 완성된다. 서비스 우선 개발 방법의 자세한 설명은 "Apache Camel을 이용한 마이크로 웹 서비스 개발" 글을 참고하기 바란다.

BrokerQouteService 인터페이스는 다음과 같다.

BrokerQouteService 는 평범한 자바 인터페이스다. 이 인터페이스를 상속한 BrokerQouteServiceImp 빈 클래스는 프로세스 관리자 절에서 설명한다.


3.2. 대출 클라이언트

대출 클라이언트는 대출 모집인이 노출한 웹 서비스를 호출한다. 그런데 이 예는 대출 모집인과 대출 클라이언트가 하나의 스프링 설정 파일을 공유하므로, 대출 클라이언트는 위한 (호출 측) 웹 서비스 빈은 따로 설정하지 않는다. (대출 클라이언트는 (호출 측) 웹 서비스 빈으로 대출 모집인의 (서버 측) 웹 서비스 빈을 사용한다.)

웹 서비스를 호출하는 대출 클라이언트의 Camel 라우팅 설정은 다음과 같다.

대출 클라이언트 라우팅은 5초마다 bean:client 엔드포인트를 실행한다. 그러면 대출 클라이언트 빈은 대출 모집인의 웹 서비스를 호출한다.

LoanQouteClient 빈 클래스는 다음과 같다.

LoanQouteClient는 client 생산자 템플릿 객체를 이용해, 대출 모집인 웹 서비스로 동기 호출을 수행하고 반환된 결과를 화면에 출력한다.


4. 신용 평가 기관 인터페이스


4.1. 신용 평가 기관

신용 평가 기관도 동기 웹 서비스를 노출하므로, 신용 평가 기관은 신용 평가 서비스를 스프링 설정 파일에 SOAP 웹 서비스 인터페이스 빈으로 다음과 같이 노출한다.

creditScoreServiceEndpoint 빈은 웹 서비스 인터페이스 객체고, creditScoreServiceImp 빈은 웹 서비스 객체다. CreditScoreServiceImp 빈 클래스가 웹 서비스를 실제 수행한다. 여기서도 웹 서비스 개발에 서비스 우선 개발(service first development) 방법을 사용한다.

CreditScoreService 인터페이스는 다음과 같다.

CreditScoreService 는 평범한 자바 인터페이스다.

CreditScoreServiceImp 빈 클래스는 다음과 같다.

신용 평가 기관의 신용 점수 계산을 시뮬레이션 하기 위해 랜덤 메소드를 사용한다.


4.2. 대출 모집인

대출 모집인은 위에서 설명한 creditScoreServiceEndpoint 빈 설정을 그대로 사용해 신용 평가 기관에게 웹 서비스를 요청한다. 대출 모집인은 BrokerQouteServiceImp 빈에서 다음과 같이 creditBurea 생산자 템플릿을 이용해 신용 평가 기관에게 (동기) 웹 서비스를 호출한다. (BrokerQouteServiceImp의 전체 소스는 프로세스 관리자 절에 있다.)


5. 은행 인터페이스


5.1. 은행

이 예에서 각 은행들은 게시 구독 채널인 ActiveMQ의 JMS Topic에 가입한다. 그러므로 각 은행들은 스프링 설정 파일에 다음과 같은 JMS 수신자(가입자) Camel 라우팅 설정을 갖는다.

각 은행은 bank.loan.request 게시 구독 채널로부터 견적 요청을 수신해, bank? 빈 엔드포인트를 수행하고, 수행 결과 메시지를 bank.loan.relpy 채널로 응답한다.

BankQouteService 인터페이스는 다음과 같다.

BankQouteService 는 평범한 자바 인터페이스다.

BankQouteServiceImp 빈 클래스는 다음과 같다.

BankQouteServiceImp는 기업 통합 패턴 9장의 "MSMQ를 이용한 비동기 구현"을 참조했다. 요청마다 다른 견적을 응답하기 위해 랜덤 메소드를 사용한다.


5.2. 대출 모집인

대출 모집인은 BrokerQouteServiceImp 빈에서 다음과 같이 auction 생산자 템플릿을 이용해 bank.loan.request 게시 구독 채널로 견적 요청 메시지를 게시한다. (BrokerQouteServiceImp의 전체 소스는 프로세스 관리자 절에 있다.)


6. 대출 모집인 프로세스 개요

팁코 예의 대출 모집인 프로세스 정의는 다음과 같다.

Apache Camel 예는 위 프로세스 워크플로우를 프로세스 관리자 라우팅 설정인 borkerProcessManager와 응답 관리자 라우팅 설정인 brokerReplyManager로 대체한다. borkerProcessManager는 대출 클라이언트의 동기 요청을 처리하고, brokerReplyManager는 비동기로 은행들로부터 응답을 수신해 최상의 결과를 선택한다.

프로세스 관리자 borkerProcessManager의 라우팅 설정은 다음과 같다.

borkerProcessManager는 팁코 프로세스 워크플로우의 첫 번째부터 마지막까지 직선상에 위치한 액티비티들을 대체한다. borkerProcessManager는 은행들에게 대출 견적을 게시한 후 견적 결과가 완성될 때까지 실행 스레드를 중지한다. (자세한 설명은 뒤에 나온다.)

응답 관리자 brokerReplyManager의 라우팅 설정은 다음과 같다.

brokerReplyManager는 팁코 프로세스 워크플로우에서 오른쪽에 위치한 "Process Received Quote From Bank" 액티비티를 대체한다. JMS 큐로부터 은행들의 견적 응답을 수집해 최상 견적의 선택하고 borkerProcessManager를 재시작시킨다.


7. 대출 모집인 프로세스 상세


7.1. 프로세스 관리자

프로세스 관리자는 웹 서비스를 통해 대출 클라이언트로부터 대출 견적 요청을 수신하고, 신용 평가 기관 웹 서비스를 호출하고, 은행들에게 견적 요청을 게시하고, 최상의 대출 견적을 대출 클라이언트에게 반환한다.

다음은 프로세스 관리자를 위한 빈들과 borkerProcessManager 라우팅 설정이다.

BrokerQouteServiceImp 빈 클래스의 전체 소스는 다음과 같다.

BrokerQouteServiceImp은 프로세스 관리자로서 신용 평가 기관 인터페이스와 은행 견적 요청을 위한 게시 구독 채널을 멤버 변수로 갖고, 팁코 액티브엔터프라이즈의 대출 모집인 프로세스의 대부분의 액티비티들을 구현한다. BrokerQouteServiceImp은 게시 구독 채널로 은행 견적 요청을 브로드캐스트한 후 잡 저장소와 자바의 동기 메커니즘을 이용해 스레드를 중지하고 brokerReplyManager 라우팅이 job 객체를 깨울 때까지 대기한다.


7.2. 응답 관리자

응답 관리자는 은행들로부터 견적 응답을 수신하고, 견적 응답을 수집하고, 최상의 견적을 선택하고, 프로세스 관리자를 재시작시킨다.

다음은 응답 관리자를 위한 응답 수신 빈들과 brokerReplyManager 라우팅 설정이다.

수집기는 요청마다 10초동안 은행들로부터 견적들을 수집한다. bankReplyAggregator 빈은 은행들의 견적 응답을 bids 객체에 추가한다.

BankReplyAggregator 클래스는 다음과 같다.

이 수집기는 은행으로부터 수신한 메시지로부터 상관관계 식별자를 추출하여 상관 관계 식별자로 잡 저장소에서 잡을 꺼내와 bid 객체에 은행 응답을 추가하고, 다시 잡 저장소에 잡을 저장한다. AggregationStrategy을 상속해 Apache Camel의 수집 로직 전략 메커니즘을 이용했다.

ProcessReceivedQoute 클래스는 다음과 같다.

ProcessReceivedQoute 는 잡 저장소로부터 잡을 꺼내고, 은행 응답 객체를 생성하고, 완성된 bid 목록으로부터 최상의 견적을 찾아, 응답을 채운 후, 잡 객체의 자바 동기화 메커니즘을 이용해 BrokerQouteServiceImp 빈에서 중지된 스레드를 깨운다.


7.3. 잡 저장소

동기 프로세스와 비동기 메시징을 결합하려면 세션 객체 저장소가 필요하다. 이 저장소는 스프링 설정 파일에 빈과 Camel 라우팅을 이용해 설정한다.

잡 저장소의 스프링 빈과 Camel 라우팅 설정은 다음과 같다.

JobRepository 인터페이스는 다음과 같다.

JobRepository 인터페이스를 상속한 EhCacheRepository 클래스는 다음과 같다.

JobRepository 객체는 BrokerQouteServiceImp 클래스 등에서 멤버 변수로 참조된다.


8. 실행

대출 클라이언트는 5초마다 대출 모집인 웹 서비스에게 대출 견적을 요청하고, 대출 모집인은 대출 견적 요청을 은행들에게 게시하면, 5개 은행들은 각각 자신의 대출 견적을 응답하고, 대출 모집인은 5개의 대출 견적 응답 중 최상의 대출 견적을 선택해, 대출 클라이언트에게 반환한다. 아래는 이 솔루션을 실행한 결과다.

이 시뮬레이션 솔루션은 Camel 라우팅 설정으로 실행되며, 대출 클라이언트, 대출 모집인, 신용 평가 기관, 은행들을 모두 포함한다. Apache CXF 프레임워크가 포함되어 있으며, 테스트를 위해 Apache ActiveMQ가 함께 실행된다. 실행 결과의 아래를 보면 대출 클라이언트는 각 대출 견적 요청마다 다른 은행의 견적을 최상의 견적으로 반환 받을 것을 볼 수 있다.


9. 맺음말

필자는 이 글에서 Apache Camel로도 팁코 액티브엔터프라이즈로 구축한 통합 솔루션을 충분히 대체할 수 있음을 보였다. 게다가 팁코 액티브엔터프라이즈로 구축한 솔루션 예보다 Apache Camel로 구축한 솔루션 예가 설정이나 코딩을 더 적게 사용했다. 이렇게 작업량을 줄일 수 있었던 이유는 Apache Camel의 DSL(Domain Specific Language, 도메인 특화 언어)와 이미 완성된 컴포넌트들을 이용했기 때문이다. 웹 서비스를 위해 단지 몇 십 줄의 설정과 코딩이 필요했으며, JMS 서비스를 위해서도 몇 십 줄의 설정과 코딩을 추가했다. 이점이 Apache Camel이 갖는 강력한 생산성이다.

이와 같이 오픈 소스 통합 프레임워크인 Apache Camel을 이용하면 팁코와 같은 상용 EAI 제품으로 구축한 통합 솔루션을 대체하거나 통합 솔루션을 새롭게 구축할 수도 있으나, 여기에는 전제가 따른다. 기업 통합 패턴으로 아키텍처를 분석할 수 있어야 하며, 기존 솔루션의 아키텍처에 대한 이해도 충실해야 하고, Apache Camel과 Spring 프레임워크와 통합에 포함되는 다양한 기술에 대해서도 깊은 이해가 있어야 한다. 이런 준비가 없다면 기업 애플리케이션들을 제대로 통합할 수 없을 것이다. 물론 이런 전제는 상용 EAI 제품을 도입하더라도 동일하게 적용된다. 상용 EAI 제품도 어떤 기능을 제공한다고 해서 단순히 몇 줄의 설정이나 코딩으로 기능이 동작하는 것은 아니다. 상용 EAI 제품을 제대로 활용하려고 해도 통합을 위한 각종 어댑터들을 이해해야 한다. (실제로 어떤 EAI 상용 제품은 기업 통합 패턴의 번호표 패턴[EIP]를 제공하기 위해 수십 페이지 정도의 설정 절차를 숙지해야 하는 경우도 있다.) 그럼에도 상용 EAI 제품만이 해결할 수 있는 통합은 없으며, 오픈 소스를 잘 이용한다면 그에 못지 않는 통합 품질뿐만 아니라 솔루션 구조도 단순화시킬 수 있다는 점은 고무적인 것이다.

필자는 기업 통합 패턴과 통합 프레임워크에서 많은 가능성을 전망하고 있다. 기업 통합 패턴과 Apache Camel 통합 프레임워크는 이 글의 예처럼 상용 EAI인프라를 대체해 기업을 통합시킬 뿐만 아니라, ETL, 배치, 동기화 등 통합의 각론 분야에서도 충분히 가치를 발휘한다. 또한 새롭게 등장하는 개념의 마이크로 서비스(Microservice)를 개발하는 데 있어서도 Apache Camel은 가장 적합한 도구가 되어 가고 있다. 그러므로 아키텍트와 개발자들도 기업 통합 패턴과 Apache Camel에 관심을 갖기 바란다.


참고 사이트

댓글 없음:

댓글 쓰기