서비스 디자인 패턴

서비스 디자인 패턴 - 8점
로버트 다이뇨 지음, 윤창석.조성배 옮김/에이콘출판


웹서비스란

한때 SOAP/WSDL 기반의 웹서비스(WebServices)와 웹 기반의 서비스(WebService) 구분하기도 했었는데, 이제는 다양한 기반의 통합 기술과 서비스들이 HTTP 기반의 웹서비스라는 개념으로 정리된 같다. 선견지명일까. 책에서는 웹서비스를 다음과 같이 정의한다
데이터를 운반하는 단순 전송 수단으로 HTTP를 활용하거나 서비스 행위의 의미를 정의하는 완전한 애플리케이션 프로토콜로 HTTP를 사용하기 위해 호출하는 소프트웨어 기능을 나타낸다.

상위 수준의 통합 디자인 패턴

분산 기술이든, 요즘의 웹서비스 기술이든 분산 환경에서 통합을 구현하는데 필요한 개념들을 명료하게 정리해서 보기 좋았다. 덕분에 여기저기서 주워들었던 개념들을 나름대로 정리할 수 있었다. EIP(Enterprise Integration Pattern)보다는 좀 더 상위 수준의 개념과 통합 패턴이라고 하겠다.

MSA 다음은?

패러다임 전환이라고 해야할까? 분산 환경에서 이기종 시스템 간의 통합을 위한 노하우가 EIP로 정리되었다면, 이제는 통짜 시스템을 마이크로 서비스로 분할하여 구성하는 아키텍처가 대세인 시대가 되었다. 그간 꽤 많은 레퍼런스들이 회자된 걸 보면, 어느 정도 무르익은 시점이 아닐까. 다음은 무엇일까? AI와의 결합이 될까? 궁금하다.


5
(요약)
애플리케이션은 홀로 존재할 수 없다. 직접 모든 데이터와 프로세싱을 관리할 수 없기 때문이다. 그래서 내외부의 애플리케이션과 데이터, 프로세싱의 교환이 필요하다. 그러나 서로 다른 애플리케이션과의 통신은 쉽지 않다. 다양한 애플리케이션들의 환경(OS, 언어, 플랫폼 등)을 고려해야 하기 때문이다. 현재 웹은 이런 문제의 해결책으로 가장 활발히 사용되고 있다. - 마틴 파울러

22
이 책은 SOAP/WSDL을 활용하거나 REST 아키텍처 스타일을 따르는 웹 서비스 디자인 솔루션을 정리한 카탈로그이며, 웹 서비스 디자인 개념의 기반을 체계화하는 잘 요약된 참조 카탈로그를 만드는데 목적을 뒀다. 각 패턴은 반복적으로 발생하는 디자인 문제의 잘 알려진 검증된 솔루션을 설명한다. 

23
서비스는 다양한 기술을 사용해 구현할 수 있다. 
… (생략) (SOA, CORBA, DCOM, REST, SOAP/WSDL)
이 책은 오직 웹 서비스에만 초점을 맞춘다. 안타깝게도 웹 서비스라는 용어 역시 매우 다양한 뜻을 담고 있다. WSDL을 사용하는 모든 호출 가능 함수를 가리키는 데 웹 서비스라는 용어를 사용하기도 하며, RESTful 서비스를 설명하기 위해서도 사용된다. 이 책에서 '웹 서비스'라는 용어는 데이터를 운반하는 단순 전송 수단으로 HTTP를 활용하거나 서비스 행위의 의미를 정의하는 완전한 애플리케이션 프로토콜로 HTTP를 사용하기 위해 호출하는 소프트웨어 기능을 나타낸다. 

33
웹 서비스는 이종 시스템을 통합하고 HTTP를 통해 재사용 가능한 비즈니스 기능 공개 방법을 제공한다. 웹 서비스는 데이터를 운반하는 간편한 수단으로 HTTP를 이용하기도 하고(예: SOAP/WS이 서비스), 서비스 행동에 관한 시맨틱을 정의하는 완전한 애플리케이션 프로토콜오서 HTTP를 사용하기도 한다(예: RESTful 서비스). 

38
웹 서비스 고려사항과 대안
- 대기시간
○ 서비스 호출 비용이 높음
§ 네트워크, 직렬화, 역직렬화 등
- 분산통신 -> 부분적 실패를 대비
○ 네트워크는 본질적으로 신뢰도가 낮으며, 클라이언트, 또는 서비스의 오류 발생 가능
○ 부분적 실패를 탐지하고 처리하기 위한 다양한 전략이 필요

웹 서비스 API 스타일
- RPC API(48)
○ 실행할 원격 프로시저를 식별하고 원격 프로시저의 매개변수와 직접 연결되는 고정 요소 집합을 담은 메시지를 정의한다. 
○ 클라이언트는 프로시저에 지정된 URI로 메시지를 발송한다. 
- 메시지 API(59)
○ 원격 프로시저의 시그너처로부터 파생되지 않은 메시지를 정의한다. 
○ 이 메시지는 구체적인 토픽과 실행할 태스크, 이벤트 등의 정보를 전달한다. 그 다음에 클라이언트가 지정된 URI로 메시지를 보내게 한다. 
○ 일단 서버가 메시지를 수신하면, 실행할 올바른 프로시저를 결정하기 위해 메시지의 내용을 검사한다. 
- 리소스 API(71)
○ 모든 프로시저와 도메인 데이터 인스턴스, 파일에 URI를 할당한다. 
○ 표준 서비스 행동을 정의하는 완전한 애플리케이션 프로토콜로 HTTP를 활용한다. 
○ 표준화한 미디어 타입과 상태 코드의 장점을 가능한 활용해 정보를 교환한다. 


클라이언트와 서비스의 상호작용 스타일
- 요청/응답(90)
○ 요청을 수신하면 이를 처리해서 동일한 클라이언트 연결로 결과를 반환한다. 
- 요청(확인(95)
○ 서비스가 요청을 수신했을 때, 백그라운드 프로세스에게 요청을 전달하고 유일한 요청 식별자를 포함한 확인을 반환한다. 
○ 확인 후 폴링/콜백 처리 가능
- 미디어 타입 협상(108)
○ 클라이언트가 하나 이상의 미디어 타입 선호 설정을 HTTP 요청 헤더에 나타낼 수 있게 한다. 
○ 원하는 포맷으로 응답을 만들 수 있는 서비스로 요청을 보낸다. 
- 링크된 서비스(115)
○ 몇몇 루트 웹 서비스의 주소만을 발행한다. 
○ 그리고 각 응답과 관련된 서비스의 주소를 포함한다. 
○ 클라이언트가 응답을 파싱해 서비스 URI를 발견하게 한다. 


요청과 응답의 관리
- 서비스 컨트롤러(125)
○ 관련 서비스의 집합을 식별하는 클래스를 생성한다. 
○ 각 클래스의 메소드에 프론트 컨트롤러가 해석할 수 있는 라우팅 표현식을 담은 애노테이션을 추가한다. 
- 데이터 전송 객체(135)
○ 요청과 응답의 데이터 구조에 따라 별도의 클래스를 생성한다. 
○ 이런 구조를 읽고 쓰는 매핑 로직을 통합한다. 
- 요청 매퍼(153)
○ 구조별 API를 활용한 특화된 클래스를 생성한다. 
○ 이 API는 요청의 지정 부분을 도메인 계층의 엔터티나 해당 엔터티의 입력 인수로 사용할 수 있는 중간 객체의 공통집합으로 직접 연결해 이동시킨다. 
○ 요청의 핵심 내용에 기반을 두고 특정 매퍼를 불러온다. 
- 응답 매퍼(168)
○ 데이터 매핑과 응답을 생성하는 데 사용하는 전송 로직을 통합한 클래스를 생성한다. 


웹 서비스 구현 스타일
- 트랜잭션 스크립트(182)
○ 데이터베이스 접근이나 파일 조작을 비롯한 기타 사용자 지정 로직을 웹 서비스 메소드 내부에 직접 작성한다. 
- 데이터소스 어댑터(186)
○ 특수화 된 데이터소스 제공자를 사용하는 웹 서비스를 생성한다. 
○ 개발자 도구를 활용해 데이터소스 메타데이터와 컨트롤러를 생성한다. 
○ 이는 요청 처리 규칙을 캡슐화하고 해석할 뿐만 아니라, 데이터소스 제공자와 메시지 포매터의 동작도 관리한다. 
- 오퍼레이션 스크립트(194)
○ 공통 비즈니스 로직을 웹 서비스의 외부에 존재하는 도메인 계층 엔터티에 캡슐화한다. 
○ 웹 서비스 내부 로직은 이런 도메인 계층 엔터티의 활동을 관리하는 알고리즘으로 국한한다. 
- 커맨드 호출자(199)
○ 요청을 처리하는 공통 로직을 완전히 캡슐화하는 커맨드 객체를 생성한다. 
○ 웹 서비스 내부로부터 커맨드 객체를 인스턴스화해 호출하거나, 비동기식 백그라운드 프로세스에게 커맨드 객체를 전달한다. 
- 워크플로우 커넥터(207)
○ 워크플로우 엔진을 사용해 수명 주기를 관리하고, 복잡하거나 오랫동안 실행되는 비즈니스 프로세스의 내부 태스크를 실행한다. 
○ 각각의 논리적 비즈니스 프로세스를 트리거 할 웹 서비스를 식별한다. 
○ 오랫동안 실행되는 프로세스로부터 추가적인 데이터를 수신하기 위해 콜백 서비스를 사용하고, 콜백 서비스에서 워크플로우 엔진으로 메시지를 전달한다. 


웹 서비스 인프라
- 서비스 커넥터(220)
○ 관련 서비스 그룹을 사용하기 위해 클라이언트가 구현해야 하는 로직을 캡슐화 해 라이브러리나 클래스의 집합으로 만든다. 
○ 이 로직을 추상화 한 상위 수준 인터페이스를 만들어 클래스를 쉽게 사용할 수 있도록 한다. 
- 서비스 설명자(228)
○ 관련 서비스의 URI와 논리적 오퍼레이션, 메시지, 서버 메소드, 사용 정책 등을 밝히는, 표준화되고 기계가 읽을 수 있는 설명을 만든다. 
○ IDL 
§ WSDL, WADL 등
- 비동기식 응답 핸들러(237)
○ 주 클라이언트 스레드와는 다른, 별도의 실행 스레드로 요청을 디스패치 한다. 
○ 주 스레드에서는 그 밖의 문제를 처리하며 이 스레드의 응답을 기다린다. 
- 서비스 인터셉터(249)
○ 각 클래스 안의 횡단 행동을 캡슐화 한다. 
○ 이 클래스를 클라이언트나 서비스 프레임워크가 관리하는 파이프 라인으로 불러온다. 
○ 인증, 캐싱, 로깅, 예외 처리, 유효성 검사 등의 공통 행동을 구현
- 멱등 재시도(262)
○ 클라이언트가 공통 연결 예외를 잡도록 디자인 한다. 
○ 연결 오류가 발생하면 서비스로 재연결하고 요청을 다시 보낸다. 
○ 이런 시도가 이뤄지는 횟수를 제한한다. 
○ 요청마다 고유 식별자를 넣어서 서비스가 중복 요청을 식별하 수 있게 한다. 
○ 대안으로는 요청에 따라 지정된 고유 URI로 요청을 보내는 방법이 있다. 


웹 서비스의 진화
- 단일 메시지 인수(293)
○ 각 서비스 오퍼레이션이 요청에 관한 모든 데이터를 담고 있는 단 하나의 메시지 매개변수만을 받도록 디자인 한다. 
- 데이터 집합 수정(296)
○ 기존 요청과 응답의 데이터 구조에 옵션 데이터를 추가한다. 
- 톨러런트 리더(303)
○ 클라이언트와 서비스가 필요한 것만 추출하고 알려지지 않은 내용은 무시하며, 다양한 데이터 구조를 예측하도록 디자인 한다. 
- 컨슈머 중심 계약(311)
○ 클라이언트 개발자는 클라이언트의 서비스 API에 기대되는 사항을 반영한 통합 테스트를 작성한다. 
○ 서비스 소유자에게 이 테스트를 전달하고, 서비스 소유자는 이 테스트를 서비스의 테스트 스위트에 포함한다. 

287
파괴적 변경(breaking change)이란 클라이언트 개발자가 코드를 업데이트하거나 구성을 변경토록 강제하는 모든 변경을 의미한다. 

327
패턴은 어떻게 서비스의 진화를 촉진하거나 방해하는가?

댓글 쓰기

0 댓글