프론트엔드

모놀리틱 시스템에서 MSA로 전환

CyberI 2015. 12. 12. 00:33


SW산업은 그 어느 산업보다 빠른 속도로 변하고 있다고 느낄지 모르겠지만, Software 개발자로서 IT밒 소프트웨어 개발 트랜드를 면면히 살펴 본다면 사실 하나 하나 계단을 밟아가는 듯이 점진적으로 발전을 해왔다 그 동안 계속   필자가 다루고 있는 Micro Service Architecture(이하 MSA)도 지금 개발 패러다임에서 급진적으로 보일지 모르겠지만,   그 동안으로 개발역사를 살펴 본다면 하나씩 하나씩 점진적으로 발전되어 나온 하나의 결과물이다



MSA는 기본 사상은 Service Oriented Architecture (SOA) 사상에서 출발하여 발전 하고 있다. SOA도 기존에 있었던, 1990년대 CORBA( Common Object Request Broker Architecture) 및 RPC( Remote Procedure Call)등 개념을 확장하여 점진적으로 발전하여 나온 사상이다. 이 모든 것이 급변하는 실 세계를 보다 빠른 속도로 반영하고, SW를 개발하기 위한 목적이며, 각각의 이론에는 그 이론을 뒷받침 하기 위한 여러 구현체들이 존재하였다

SOA 환경에서는 ESB (Enterprise Service Bus) 관련 제품이 주를 이루면  SOA 관련 업체들이 많이 장점을 강조하며 새로운 변화를 이끌려고 하였지만 실제 개발자가 느끼기에는 ESB도 기본 EAI 솔루션과 크게 틀리지 않고 XML 및 SOAP이라는 무거운 Protocol로 인해 성능 문제 및 구현이 대단한 어려운 문제점을 내포하고 있었다.

또한 Java 진영에서는 SOAP과 WSDL ,UDDI등 다양한 Web Services 스펙을 지원하기 위한 여러 API 들이 나왔지만, 객체지향적인 정보를 XML 로 표현하기에는 너무 무겁고 변환방식으로 매끄럽지 못한 문제점을 가지고 있었다.

그 후로 REST방식 웹 개발이 보편화 되면서 기존 XML/SOAP 기반으로 서비스 시장의 대부분을 잠식하면서 모든 Platform에서 표준 API 통신 protocol로 자리 잡고 있으며, 여러 분야에서 IT 기술을 발전시키고 있다 .  

사실 처음부터 MSA 사상으로 설계하고 시작하기 매우 어렵다 . 기존 모놀리틱 기반의 시스템이 존재하는 경우가 대부분이고, 이를 바탕으로 Service 개념을 도입하고자 하는 고객이 대부분이다
오늘은 이런 기존 고객이 가지고 있는 모놀리틱 기반 시스템에서 어떻게 Service 를 나누면 좋을지, 그리고 그렇게 나누기 위해 고려되어야 할 사항들이 어떤 게 있는지 알아보자


좋은 서비스(Good Service)란?

우선 각각의 서비스로 분리하기 위해서는 좋은 서비스에 대한 정의가 필요하다.
좋은 서비스는 다음 2가지 사항만 만족시키면 된다.
  • Loose Coupling
  • High Cohesion
즉 서비스들 간에는 서로 연관관계가 적어야 하면, 서비스 내적으로는 높은 응집력을 가지고 있어야 한다. 아래 설명하는 내용은 loose coupling 조건을 갖추기 위해 필요한 모델관의 연관관계를 최소화 하기 위한 방법들을 설명하겠다.


FK 관계 연결 끊기
첫 번째 조건으로 loose coupling이 되기 위해서는 데이터 관계부터 서비스간의 종속관계를 끊어야 한다. 첫번째 모델간 서비스간 연결관계를 제거하기 가장 어려운 첫번째 문제는 DBMS 테이블간의 Foreign key에 의한 연관 관계이다. 하지만 Foreign Key 연결 관계를 끊기는 DBMS 환경에 익숙한 개발자에게서는 매우 어려운 일이다.

Building  Microservices 책에 의하면 이러한 부분은 DB 및 서비스를 분리하고 서로 필요한 데이터에 대해서는 API call을 통해 처리하라고 말하고 있다. 올바른 MSA 서비스 구축을 위해 약간의 성능을 희생할 수 있다고 하지만, 과연 고객이 이 부분을 수용할 지는 미지수다

우선 가장 이상적인 연결과계를 표현하는 방법은 URN(Uniform ResourceName)을 통한 표기 방법이다. 가량 데이터중 다른 회원의 아이디를 참조하는 경우라면 urn:li:member:123 과 같은 스키마 정보및 테이블 정보 아이디를 모두 포함한 URN 형태로 표기하는 것이 좋다. (LinkedIn's architecture : http://www.slideshare.net/parikhk/restli-and-deco)


Static 데이터 공유
공통 코드성 데이터를 각 서비스에 서 공유하는 경우 이런 경우까지 API 호출을 통해 데이터를 공유하는 것은 매우 불합리 하다. 대표적인 것은 증권사의 기본적으로 사용하는 종목코드 마스터 데이터이다. 이런 경우 보통 배치성으로 Master code 파일을 매일 새벽에 생성하고 이 데이터가 필요한 각 서비스에서는 이 마스터 파일을 하루에 한번 호출하여 가지고 있다가 이용하는 방식이다.
별도의 공통 코드 테이블에 대한 규칙은 없고, 각 서비스에 필요한 방식으로 구축하여 이용을 한다. 서비스 분리에 대한 문제점이 없으며, 필요한 시기 정확히 데이터를 다운받는다면 불일치 문제도 발생하지 않는다.

공유 데이터
좀더 복잡한 상황으로 들어가보면, 공유되는 데이터가 위의 예시처럼 하루에 한번만 바뀌는 데이터가 아니라, 수시로 바뀔 수 있는 데이터라고 한다면 위와 같은 방법으로 데이터 처리는 불가능 하다. 이러한 경우는 공통 Service 로 구축하여 API 호출을 통해서 이용하는 것외는 방법이 없다. 가량 재무,홍보,분석 서비스에서 각각 고객 데이터가 필요하다면 필요할때마다 고객 정보 API를 호출해서 이용해야 한다. 이렇게 구축함으로서 Data 계층에 대한 종속성도 없애고 필요 데이터 호출 및 권한 처리등 여러 이점을 누릴 수 있지만, 성능에 대한 이슈는 항상 남아 있다.


Transaction
서비스가 분리되면서 가장 첫번째 신경 써야 되는 부분이 Transaction 처리부분이다. Transaction은 기본의 시스템이 하나로 묶을 수 밖에 없었던 이유 중에 중요한 첫 번째 이유이며, 분산 환경 및 MSA 환경에서도 그 처리가 쉽지 않은  요구사항이다

사실 서비스가 분리된  분산환경에서는 Distributed Transaction 을 위해 X/Open Distributed Transaction Processing(DTP) Model (X/Open XA) 스펙이 있지만 이를 지원하기 위한 two-path commit(2PC) JDBC Driver 및 DBMS는 생각보다 많지 않으며 , 이기종간의 DB인 경우는 이런 처리가 더욱 어려운 문제점이 있다.

 Transaction 처리   및 일반적인 DB에서 가장 먼저 나오는 용어이 ACID를 집고 넘어가야 한다. ACID는 (원자성, 일관성,고립성, 지속성) 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어이다.



하지만 이 ACID는 MSA 환경에서는 구현하기 힘들며 ,  그래서 ACID에 대응돼서 나온 이론이 BASE이다.
BASE는 아래와 같은 성질을 가지고 있다.
Basically Available : 기본적으로 가용하며
Soft-state : 사용자가 보관처리 하지 않으면, 데이터가 파기 될 수 있으며,
Eventually consistency : 당장은 아니지만 언젠가는 일관성이 유지되는 것

즉 핵심은 Eventually Consistency 로서 ACID 기반의 Transaction 이 아닌 BASE 기반의 Transaction을  처리하도록 하고 있다
이런 Eventually Consistency 를 유지하기 위한 방법으로 2가지가 있다.

Try Again Later

첫 번째 방법은 2개의 DB에 업데이트를 하는 경우 첫 번째 DB입력이 성공하고 2번째 입력이 실패하더라도 전체적으로 서비스 수행으로 진행되는 것으로 본다. 2번째 DB에 입력 로직은 별도의 로그 파일이나 로그 DB를 통해 그 정보를 보관하고 있고, 추후에 그 데이터 입력을 재시도 하도록 한다.

Abort the Entire Operation
또 다른 방법은 오류 시 전체 작업 취소이다. 첫 번째 데이터 입력이 성공한 후, 두 번째 서비스를 통한 처리 작업 오류 시 첫 번째 입력 상태를 원복시키는 것이다. Compensating transaction이라고도 하며, 이전 상태로 돌아가기 위해 DB의 rollback 명령을 수행하는 게 아니라 보상로그 테이블 등을 참조하여 DELETE 문을 직접 수행해서 원상태로 돌아가는 것이다.
사실 이러한 DELETE 작업이나 원래 상태로 돌아가는 것 조차도 실패할 수 있기 때문에 compensating log 파일이나 테이블을 통해 재시도를 해야 한다

위의 2가지 방법 모두 서비스 단에서 일일이 개발자에게 맡겨서 개발하게 한다면 MSA 서비스 구축을 성공할 수 없다. 따라서 해당  분산환경 Transaction을 구현하기 위해서는 Transaction 로그 History 기반에 자동으로 Transaction 관리를 할 수 있는 MSA 환경 지원을 위한 framework 구축이 필요하다

이상 좋은 서비스 구축을 위한 기본 서비스 분리를 위한 방안 및 Transaction 처리 방안을 간단히 정리해 보았다.  다음 시간은 이러한 서비스를 어떠한 Host 환경에서 그리고 어떠한 규모단위로 분리하여 구축하면 좋을 지 설명하도록 하겠다.


참조문서

Sam Newman, Buildimg Microservices, Oreilly 2015

Eric Evans, Domain-Driven Design, Addison-Wesley Professional, 2003

https://en.wikipedia.org/wiki/ACID

https://en.wikipedia.org/wiki/Eventual_consistency