[스프링캠프 2015] Spring Integration을 통해 살펴본 메시징 세계 발표자료 입니다.
예제 소스 저장소는 프리젠테이션 안에 링크 걸어놨습니다.
감사합니다.
-------------------------------------------------------------------
우리는 늘 누군가와 소통(Communication)을 합니다. 소통을 통하여 누군가에게 일을 시키기도 하고 내가 일을 받기도 합니다. 애플리케이션도 마찬가지로 이기종간의 애플리케이션끼리 데이터로 소통을 하며 할 일을 서로 분산 처리할 상황이 발생하기도 합니다.
이런 분산 처리 이전에는 소통이 전제되어야 합니다. 애플리케이션 간 소통에 대한 고민은 선구자들에 의해 Enterprise Integration Patterns로 탄생되었으며 Spring에서도 그 패턴화의 추상화 일원으로 Spring Integration을 탄생시켰습니다.
이 강연에서는 Spring Integration을 통해 애플리케이션 간에 어떻게 쉽고 편하게(?) 소통을 할 수 있게 되었는지 살펴보며 예제와 사례를 통해 Spring Integration 입문에 도움을 주고자 합니다.
2. 이 완 근
2011.02 ~ 2014.07
NHN Technology Service
2014.07 ~
SK planet
네이버 프로모션 이벤트 개발
네이버지도 파노라마 이미지
구축 웹 플랫폼 개발
Data Service 개발팀
발표자 소개
https://www.facebook.com/wangeunl
3. 이번 세션에서 하고자 하는 것
2.
어떻게 쓰는건지?
3.
예제와 사례
1.
Spring
Integration?
뭐고 왜 쓰는건지?
4. 1.
What is Spring Integration?
Spring Integration? 스프링 통합?
Spring Integration이 뭔지, 왜 쓰는건지 살펴봅시다.
9. 마일리지 통합 조회 시스템
마일리지
통합 조회 서버
뿅이카페에 내 포인트가 얼마나 있죠?
맛나는 빵집에 내 포인트는요?
잘난다 항공에 내 마일리지는?
10. 이렇게 하진 안잖아요?
마일리지
통합 조회 서버
뿅이카페에 내 포인트가 얼마나 있죠?
뿅이카페
마일리지 서버
저 쪽가서 알아보세요
뿅이카페에 내 포인트가 얼마나 있죠?
결과 응답 (JSON)
11. 뿅이카페에 내 포인트가 얼마나 있죠?
맛나는 빵집에 내 포인트는요?
잘난다 항공에 쌓인 내 마일리지는?
이렇게 할 겁니다.
마일리지
통합 조회 서버
뿅이카페
마일리지 서버
맛나는 빵집
마일리지 서버
잘난다 항공
마일리지 서버
12. 서버마다 통신기법은 다를 수 있습니다.
마일리지
통합 조회 서버
REST API
TCP
JMS JMS
13. RESTful API 통신 구현 1
마일리지
통합 조회 서버
[GET] 마일리지 조회 REST API
Jakarta HTTP Client를 이용
http://hc.apache.org/
JSON
14. String url = "http://example.com/point/1";
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
byte[] responseBody = method.getResponseBody();
// responseBody를 통해 byte[] to Object 변환
method.releaseConnection();
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) { … }
준비
실행
결과 반환
15. RESTful API 통신 구현 2
마일리지
통합 조회 서버
[GET] 마일리지 조회 REST API
Spring Framework의 RestTemplate를 이용
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#rest-resttemplate
JSON
16. RestTemplate restTemplate = new RestTemplate();
String uri = "http://example.com/point/{id}";
UriComponents uriComponents =
UriComponentsBuilder.fromUriString(uri)
.build()
.expand("41")
.encode();
URI url = uriComponents.toUri();
Point point = restTemplate.getForObject(url, Point.class);
이대로 끝?
준비
실행 & 결과 반환
17. RESTful API 통신 구현 3
마일리지
통합 조회 서버
[GET] 마일리지 조회 REST API
Spring Integration Framework을 이용
http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/http.html#http-outbound
JSON
18. <int:channel id="requestChannel" />
<int:gateway
id="requestGateway"
service-interface="integration.PointRequestGateway"
default-request-channel="requestChannel" />
<int-http:outbound-gateway
request-channel="requestChannel"
url="http://example.com/point/"
http-method="GET"
expected-response-type="java.lang.String" />
@Autowired
PointRequestGateway gateway;
Point point = gateway.getPoint("41");
<int:gateway
id="requestGateway"
service-interface="integration.PointRequestGateway"
default-request-channel="requestChannel" />
<int-http:outbound-gateway
request-channel="requestChannel"
url="http://example.com/point/"
http-method="GET"
expected-response-type="java.lang.String" />
public interface PointRequestGateway {
Point getPoint(String id);
}
Point point = gateway.getPoint("41");
19. 비즈니스 로직과 통신 로직을 분리할 수 있습니다.
무슨 차이죠?
Spring Framework
RestTemplate
Spring Integration Framework
HTTP-outbound-gateway
@Autowired
PointRequestGateway gateway;
Point point = gateway.getPoint("41");
20. HTTP 말고도 다른 Connectivity도 제공 하는데
Messaging 기반으로 통신 구현을 했습니다.
게다가 Spring Integration에서는
21. 많은 개발자들은 시스템 통합에 대해
이렇게 해결해 왔습니다.
File Transfer
Shared Database
Remote Procedure Invocation
Messaging ?
잠깐 Spring Integration을 이야기 하기 전에...
26. 그 중에서 왜 하필 Spring Integration 인가?
다양한 통신 기술에 대한 Adapter 및 Infrastructure 제공
XML / Java DSL을 이용한 간편한 Infrastructure 구축
Spring Framework의 IoC, DI 사용
간편한 설정
익숙한 환경
다양한 Connectivity
32. Spring Integration History
2007.11.13 - Spring Integration First commit
2008.01.23 - Spring Integration 1.0.0.M1
2008.11.26 - Spring Integration 1.0.0
2010.11.22 - Spring Integration 2.0.0
2013.12.15 - Spring Integration 3.0
2015.04.03 - Spring Integration 4.1.3
…
36. Message Endpoints
Message Channel
Business Logic
Message Endpoints
Message Channel
Business Logic
Send Server Receive Server
Spring Integration의 3대 메인 컴포넌트
Business Layer
Integration Layer
Message
Business Layer
Integration Layer
37. Spring Integration의 3대 메인 컴포넌트
Channel Adapter
Gateway
Business Layer
Send Server
Message Channel
Filter
Transfomer
Router
Service Activator
Message
39. Message is
목적지로 발신 / 수신할 데이터의 Wrapper Class
Channel Adapter
Gateway
Business Layer
Message Channel
Filter
Transfomer
Router
Service Activator
Message
40. Message 구조
전송하고자 할 데이터
메시지의 메타 데이터
ex) id, expiredDate
ex) POJO, Serialized Data
41. 1. 직접 메시지 인스턴스화 진행
2. 메시지 빌더를 사용하여 메시지 오브젝트 생성
Message<String> message1 =
MessageBuilder.withPayload("Hello").build();
Message<User> message2 =
MessageBuilder.withPayload(user).build();
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
Message<String> message1 = new GenericMessage<>("Hello");
Message<User> message2 = new GenericMessage<>(user);
Message 생성 방법
43. Message Channel is
비지니스 로직과 엔드포인 사이에서 메시지를 보내거나 받는 통로 역할
Channel Adapter
Gateway
Business Layer
Message Channel
Filter
Transfomer
Router
Service Activator
Message
45. Message Channel 분류
Publish/Subscribe ChannelPoint-to-Point Channel
Channel
1:1 전송 용도
Channel
1:N 전송 용도
DirectChannel
QueueChannel
PublishSubscribeChannel
…
…
46. Message Channel 단독 사용 예
<int:publish-subscribe-channel id="messageChannel"/>
org.springframework.integration.config.xml.PublishSubscribeChannelParser에 의해
PublishSubscribeChannel로 Bean 타입 결정 & 채널 Bean 인스턴스화
https://github.com/crazybnn/SpringCamp2015_Spring_Integration_Sample_Basic/tree/feature/Chapter02-channel
CoffeeOrder
Manager
Message
Channel
send(커피이름);
Maker 1
Maker 2
Maker 3
subscribe();
47. Makter 1에서는 아메리카노 메시지만 받게 하려면?
CoffeeOrder
Manager
Message
Channel
send(커피이름);
Maker 1
Maker 2
Maker 3
subscribe();
Makter 1, 2, 3이 외부 서버에 있는 경우에는?
위 궁금증을 해소하기 위한 컴포넌트가 바로
Message Endpoints
49. Message Endpoints is
메시지 채널을 통해 메시지 송수신 등과 같은 처리를 돕는 모듈
Channel Adapter
Gateway
Business Layer
Message Channel
Filter
Transfomer
Router
Service Activator
Message
50. <int:channel id="helloChannel"/>
XML에 Direct Channel 선언한 다음
@Autowired
private DirectChannel helloChannel;
채널을 DI 받아서
Message<String> message =
MessageBuilder.withPayload("Hello World!").build();
helloChannel.send(message);
전송할 Message 생성 후
채널을 이용해서 send!
메시지를 보내려면….
이 과정은 메시징 프레임워크에 상당히 Coupling 한 작업들….
51. XML에 Direct Channel 선언하고
<int:gateway id="helloGateway"
service-interface="samples.gateway.HelloMessageGateway">
<int:method name="sendMessage" request-channel="helloChannel"/>
</int:gateway>
Gateway를 선언한 뒤
helloGateway.sendMessage("Hello World!");
Message 오브젝트가 아닌 POJO를 send 할 수 있다!
이를 해소하기 위해 태어난게 Gateway!
@Autowired
private HelloMessageGateway helloGateway;
Gateway를 DI 받으면
<int:channel id="helloChannel"/>
public interface HelloMessageGateway {
void sendMessage(String messageContent);
}
52. 이를 해소하기 위해 태어난게 Gateway!
메시지 생성 / 채널을 이용한 전송과 같은
메시징 프레임워크에 종속된 개발 과정이 제거됨
Gateway를 쓰면 개발자가 정의한 interface으로
Proxy Bean을 제공
helloGateway.sendMessage("Hello World!");
Message 오브젝트가 아닌 POJO를 send 할 수 있다!
53. Gateway로 해결이 안되는 상황
그럼 Message를 받고 싶을 때는?
<int:channel id="helloChannel">
<int:queue capacity="10"/>
</int:channel>
<int:gateway id="helloGateway"
service-interface="samples.helloworld.HelloGateway">
</int:gateway>
public interface HelloMessageGateway {
String receiveMessage();
}
문제는 reply-channel이 SubscribableChannel 계열일 경우에는 사용 불가
Future<String> receiveMessage();
<int:method name="receiveMessage" reply-channel="helloChannel"/>
54. 이를 해소하기 위해 태어난게 Service Activator!
<int:publish-subscribe-channel id="inputChannel"/>
<int:service-activator id="helloActivator"
input-channel="inputChannel"
ref="helloService"
method="sayHello"/>
<bean id="helloService"
class="integration.samples.HelloService"/>
input-channel에는 Gateway는 달리
PollableChannel, SubscribableChannel 계열 모두 가능
59. Message Endpoints 정리
Gateway 비즈니스 로직에서 메시지 송수신을 쉽게 도와주는 컴포넌트
Service Activator 메시지가 입력 채널에 도착했을 때 특정 빈의 메소드를
호출해주는 컴포넌트
Channel Adapter 외부 시스템과 메시지 송수신 하기 위한 컴포넌트
Transformer 인풋 채널로 들어온 페이로드를 특정 목적에 맞게 변환하여 아웃
풋 채널로 전달하는 엔드포인트
Filter 특정 채널로 어떤 메시지는 전달하지 말아야 할지를 걸러내는
컴포넌트
Router 메시지를 한 개 이상의 채널로 보내는 컴포넌트
Splitter 채널로 들어온 메시지를 여러 조각으로 나눌 때 사용
Aggregator 여러 메시지를 조합하여 하나의 메시지로 통합하는 컴포넌트
Message Bridge 다른 종류의 메시징 채널이나 어댑터를 연결하는 컴포넌트
Message Enricher 수신 메시지에 추가적인 정보를 더하여 확장, 업데이트 된 객체를
하위 소비자에게 전송
61. Spring Integration 예제
Simple Integration Exercise
https://github.com/crazybnn/SpringCamp2015_Simple_Integration_Exercise
62. Simple Integration Exercise 데이터 흐름
/send/jms
/send/nodejs
JMS
ActiveMQ
HTTP
Spring 생산자
서버
Spring 소비자
서버
Nodejs 생산자
서버
https://github.com/crazybnn/SpringCamp2015_Simple_Integration_Exercise
63. Spring Integration 적용 사례
Spring Integration 적용 전
파노라마 이미지 처리 Batch
이미지 번호
파일 입력
이미지 번호
파일 입력
이미지 번호
파일 입력
이미지 번호
파일 입력
이미지 번호
파일 입력
64. Spring Integration 적용 사례
Spring Integration 적용 후
파노라마 이미지 처리 Batch
Master Reader
Slave Writer
1
JMS
JMS JMS
…Slave Writer
2
Slave Writer
3
Slave Writer
N
이미지 번호 DB
ActiveMQ
65. Spring Integration 적용 사례
Spring Integration과 Spring Batch의 결합
파노라마 이미지 처리 Batch
http://docs.spring.io/spring-batch/trunk/reference/html/scalability.html#remoteChunking
66. Spring Integration 적용 사례
Asynchronous Design with Spring and RTI: 1M Events Per Second
http://www.slideshare.net/SpringCentral/williams-1m-events
67. Spring Integration 한 번 써볼까?
출처: https://subokim.wordpress.com/2015/04/11/current_and_future_of_software_developers/
68. 멈추지 말고 공부합시다.
기업 통합 패턴 소개
http://www.slideshare.net/barunmo/20141021-40528971
Choosing the Right ESB for Your Integration Needs
http://www.infoq.com/articles/ESB-Integration
Introduction to Spring Integration and Spring Batch
http://www.infoq.com/presentations/Spring-Integration-Batch
Managing and Monitoring Spring Integration Applications
http://www.infoq.com/presentations/Managing-Spring-Integration