The Required Standard
(필수 표준)

사례를 통해 작업하고 trade-pffs(장단점)에 대해서 생각할 때, 발견해야할 핵심 균형 중 하나는 시스템에 얼마나 많은 가변성을 허용할 것인가입니다. 서비스에서 서비스까지 일정해야 하는 것이 무엇인지를 식별하는 핵심 방법 중 하나는 잘 동작하고, 좋은 서비스가 어떻게 보일지를 정의하는 것입니다.

시스템에서 "훌륭한 시민" 서비스는 무엇일까요?

시스템이 관리 가능하고, 하나의 나쁜 서비스가 전체 시스템을 중단시키지 않도록 하기 위해 필요한 기능은 무엇입니까?

그리고 사람들과 마찬가지로, 하나의 맥락에서 훌륭한 시민이 다른 곳에서 좋게 보이는 것이 무엇인지를 반영하지는 않습니다.

그럼에도 불구하고, 잘 동작하는 서비스는 관찰하는 것이 매우 중요하다고 생각하는 공통적인 특징을 가지고 있습니다.
이것은 너무 많은 발산을 허용하게 되면, 꽤나 심각한 시간을 야기시킬 수 있는 몇 안 되는 주요 핵심 영역입니다.

Netflix의 Ben Christensen은 더 큰 그림을 생각할 때, "자율적인 수명주기(lifecycle)을 가지고 있지만, 모든 것이 함께 잘 어울리는  많은 작은 부분으로 이루어진 응집력 있는 시스템이 되어야 한다"고 말했습니다.

따라서, 큰 크림에 대한 시각을 잃어버리지 않고, 개별적인 마이크로서비스의 자율성을 최적화하는 것의 균형을 찾아야만 합니다.

각 서비스가 가져야 하는 명확한 속성(attribute)을 정의하는 것은 균형이 어디에 있는지를 분명하게 하는 한 가지 방법입니다.

Monitoring
(모니터링)

시스템의 건강에 대한일관성 있는 서비스 전반에 걸친 뷰(Cross-Service View)를 작성할 수 있어야 합니다.

이것은 서비스별 관점이 아닌, 시스템 전체적인 관점이어야 합니다.
8장에서 논의하겠지만, 개별 서비스의 상태를 아는 것은 유용하지만, 종종 더 낣은 문제를 진단하거나 더 커다란 트렌드를 이해하려고 하는 경우에만 유용합니다.

가능한 한 이것을 쉽게 하기 위해서 모든 서비스가 동일한 방식으로 상태(health)와 일반적인 모니터링 관련 메트릭을 내보내도록 하는 것이 좋습니다.

각 서비스가 중앙 위치로 이러한 데이터를 Push해야 하는 Push 메커니즘을 채택할 수 있습니다.
메트릭의 경우에는 Graphite를, Health를 위해서는 Nagios를 사용할 수 있습니다.

또는 노드 자체에서 데이터를 긁어서 보내는(Scrape) 폴링 시스템(Polling System)을 사용하도록 결정할 수도 있습니다.

박스 내부를 불투명하게 하고, 모니터링 시스템이 그것을 지원하기 위해 변경되지 않도록 하십시오.
로깅(logging)도 같은 범주에 속합니다. 모두 한 곳에서 필요합니다.

Interfaces
(인터페이스)

작은 수의 정의된 인터페이스 기술을 도입하는 것은 새로운 인터페이스 호출 서비스(Consumer)를 통합하는데 도움이 됩니다.
하나의 표준을 가지는 것이 좋습니다. 2개도 나쁘지 않습니다.
20개의 다른 스타일의 통합은 나쁩니다.

이것은 단지 기술과 프로토콜 선택에 대한 것이 아닙니다.

예를 들면, 만약 HTTP/REST를 선택한다면, 동사나 명사를 사용합니까?
자원에 대한 페이지화(pagenation)는 어떻게 처리합니까?
End-point의 버전관리는 어떻게 하나요?

Architectural Safety
(아키텍처적인 안전성)

나쁘게 동작하는 하나의 서비스가 파티의 모든 사람에게 손해를 끼치게 할 수 없습니다.

우리는 우리 서비스가 건강하지 않은(unhealthy) 다운스트림 호출(downstream call:외부에서 내려오는 호출)로부터 스스로를 보호할 수 있도록 보장해야 합니다.
다운스트림 호출의 잠재적인 실패를 적절하게 처리하지 못하는 서비스가 더 많을 수록, 시스템은 더 취약해질 것입니다.

적어도 각 다운스트림 서비스가 자체 Connection Pool을 가지도록 요구하고, 또한, 각 서비스가 Circuit Breaker를 사용하도록 말할 수 있을지도 모릅니다.

11장에서 마이크로서비스 확장(Microservices at scale)에 대해서 논의할 때, 더 깊이 있게 다룰 것입니다.

응답 코드에 대해서도 또한 규칙을 적용하는 것이 중요합니다.
만약 Circuit Breaker가 HTTP 코드를 사용하고, 하나의 서비스가 에러에 대해서 2XX 코드를 보내거나 4XX 코드를 5XX 코드로 혼동하여 보내는 경우에는 이러한 안전 조치가 분리될 수 있습니다.

유사한 문제가 HTTP를 사용하지 않는 경우에도 발생할 수 있습니다.
OK 및 올바르게 처리된 요청과 나쁘고 서비스가 수행되지 못하게 하는 요청, OK이지만 서버가 다운되어 확인할 수 없는 요청 사이의 차이를 아는 것은 빠르게 실패하고 이슈를 추적할 수 있는 것을 보장하는 핵심입니다.

만약 우리 서비스가 이러한 규칙에 대해 불성실하게 되면, 결국 더 취약한 시스템을 가지게 됩니다.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/814

지금까지 본 것처럼, 마이크로서비스는 우리에게 많은 선택권을 주고, 그에 따라서 많은 결정을 내릴 수 있었습니다.

예를 들면, 얼마나 많은 다른 기술들을 사용해야만 했고, 다른 팀에서 다른 프로그래밍 관용구를 사용하게 했으며, 서비스를 분할하거나 통합해야만 했는가?

어떻게 이런 결정을 내릴 수 있을까요? 변화의 속도가 더 빨라지고, 이러한 아키텍처가 허용하는 더 유동적인 환경에서 아키텍트의 역할도 또한 변해야 합니다.

이 장에서는 아키텍트의 역할이 무엇인지에 대해서 상당히 개인적인 뷰를 가지고, 바라건데 상아탑에 대한 하나의 최종 공격을 시작하겠습니다.


Inaccurate Comparisons
(부정확한 비교)


당신은 계속해서 그 단어를 사용하고 있습니다. 나는 그 단어가 당신이 생각하는 것을 의미한다고 생각하지 않습니다.
   ----- Inigo Montoya, from The Princess Bride

아키텍트는 중요한 직업을 가지고 있습니다. 아키텍트는 고객이 필요로 하는 시스템을 제공하는데 도움이 되는 기술적 비전을 모아서 확보할 책임을 가지고 있습니다.

일부 지역에서, 아키텍트는 아키텍트의 역할과 기술적인 주역이 동일한 경우인, 단지 하나의 팀과 작업을 해야만 할 수 있습니다.
다른 지역에서는, 아키텍트가 전 세계의 여러 팀이나 심지어 전체 조직을 조율하며 전체 작업 프로그램에 대한 비전을 정의할 수도 있습니다.

아키텍트가 어떤 수준에서 작업을 하든, 그 역할을 고정하는 것은 까다롭습니다.

그리고 엔터프라이즈 조직에서 개발자가 분명한 직업상 진로를 종종 (아키텍트로) 보이고 있음에도 불구하고, 사실상 다른 어떤 것보다 더 많은 비판을 받는 역할을 합니다.
다른 어떤 역할보다 더 많이, 아키텍트는 구축된 시스템의 품질, 동료의 근무 조건, 변화에 대응하는 조직의 능력에 직접적인 영향을 미칠 수 있습니다. 그러나 우리는 종종 이 역할을 잘못하는 것처럼 보입니다.

왜 그럴까요?

이 산업계는 아직 어린 분야입니다.

우리가 잊어버린 것처럼 보이는 어떤 것이지만, 단지 약 70년 동안 컴퓨터로 인식하는 실행 프로그램을 만들었을 뿐입니다.
그러므로, 우리가 무엇을 하는지 설명하려고 시도하기 위해 지속적으로 다른 직업을 찾고 있습니다.
우리는 의사나 엔지니어가 아니지만, 배관공이나 전기 기술자도 아닙니다.

대신에, 우리는 사회가 우리를 이해하기 어렵게 만들거나 우리가 어디에 적합한지 이해하기 어렵게 만드는 어느 중간 영역에 빠지게 됩니다.

그래서 우리는 다른 직업에서 빌려왔습니다.
우리는 스스로를 소프트웨어 "엔지니어" 혹은 "아키텍트"로 부릅니다. 하지만, 우리는 그렇지 않습니다. 아닌가요?

아키텍트(건축가)와 엔지니어(기술자)는 우리가 단지 꿈꿀 수 있는 엄격함과 규율을 가지고 있습니다. 그리고 사회에서의 중요성을 잘 이해하고 있습니다.

나는 내 친구가 자격을 갖춘 아키텍트(건축가)가 되기 전 어느 날, 이야기 한 것을 기억합니다.

"내일 만약 내가 무엇인가를 만드는 방법을 술집에서 조언하고, 그것이 잘못되었다면, 설명하려고 할 것이다. 나는 법률 관점에서 자격을 갖춘 아키텍트(건축가)이고, 내가 잘못했다면 그에 대한 책임을 저야 하기 때문에 고소를 당해야 한다."라고 그 친구는 말했습니다.

사회에서 이러한 직업의 중요성은 사람들이 충족시켜야만 하는 자격 요건이 있음을 의미합니다. 예를 들면, UK(영국)에서는 아키텍트(건축가)로 불릴 수 있게 되려면 최소한 7년간의 학습이 필요합니다. 그러나 이러한 직업들은 또한 수천년 전의 지식 체계를 기반으로 합니다.

우리는 어떤가요? 그다지 좋지 않습니다.

어떤 이유로 좋아 보이는 것에 대해 거의 알지 못하는 것처럼, 대부분의 IT Certification(IT 자격증)이 가치가 없는 것처럼 보입니다.
우리 중의 일부는 인정받기 원하므로, 이미 업계의 갈망으로 인정받은 다른 직업에서 이름을 빌려왔습니다.

그러나 이것은 이중으로 해로울 수 있습니다.

첫째, 우리가 분명하게 하지 않을 때, 우리가 하고 있는 것을 안다는 것을 의미합니다.
빌딩과 다리가 결코 쓰러지지 않는다고 말하지는 않겠지만, 우리의 프로그램이 충돌할 횟수보다 훨씬 더 적게 쓰러져서 엔지니어(기술자)로서 비교하기에는 불공평합니다.

둘째, 유추는 매우 빠르게 심지어 매우 대충 흘낏 보는 것만으로도 실패하게 됩니다. 일이 잘 풀어지기 위해서, 만약 다리를 건설하는 것이 프로그래밍과 같았다면, 50미터 더 멀리 떨어진 반경에, 실제로는 화강암보다 진흙이 있었음을 우리는 발견했을 것입니다. 그리고 도로가 지나가는 다리를 건설하는 대신에 걸어다니는 다리를 건설했을 것입니다.

우리의 소프트웨어는 실제 아키텍트(건축가)나 엔지니어(기술자)가 처리해야 하는 것과 동일한 물리적인 규칙에 의해 제한받지 않습니다. 그리고 우리가 만든 것은 사용자의 요구사항에 유연하게 적응하고 진화하도록 설계되었습니다.

아마도 아키텍트(건축가)라는 용어는 가장 많은 해를 입었을 것입니다. 다른 사람들이 해석할 수 있도록 상세한 계획을 세운 사람들의 아이디어는 이것이 실행될 것이라고 기대했습니다.
일부 예술가, 일부 엔지니어(기술자), 일반적으로 단일 비전 생성을 감독하는 것의 균형(balance)은 물리학적인 법칙을 고려한 구조 공학자(Structural Engineer)의 간헐적인 반대를 제외하고, 다른 모든 관점은 보조적입니다.

우리 업계에서, 이러한 아키텍트에 대한 관점은 다음과 같은 몇 가지 무시무시한 업무로 이어집니다.
근본적으로 알 수 없는 미래에 대한 고려 없이, 다이어그램 이후 다이어그램, 문서의 페이지 이후의 페이지, 완벽한 시스템 구조를 알리기 위해 만들어진 뷰(view).

구현할 것이 얼마나 어려운 것인지, 혹은 실제로 동작할 것인지 아닌지에 대한 이해가 완전히 결여되어 있고, 우리가 더 많이 배울수록 변화하기 위해 어떤 능력도 가지지 못하게 합니다.
우리가 스스로를 엔지니어(기술자)나 아키텍트(건축가)와 비교해 볼 때, 모든 사람들에게 위해를 줄 위험이 있습니다. 불행하게도, 우리는 지금 아키텍트라는 단어에 매료되어 있습니다.
따라서, 우리가 할 수 있는 최선은 우리의 맥락에서 아키텍트가 무엇을 의미하는지를 재정의 하는 것입니다.


An Evolutionary Vision for the Architect
(아키텍트에 대한 진화(성장) 비전)


우리의 요구사항은 건물을 설계하고 건설하는 사람들보다 더 빠르게 변화하고 있습니다 - 우리가 처분하는 도구와 기술처럼. 우리가 만든 것들은 고정된 시점이 아닙니다. 한번 상용화되면, 우리의 소프트웨어는 사용되는 방법이 변경됨에 따라 지속적으로 발전할 것입니다. 우리가 만든 대부분의 것들에 대해서 한번 고객들의 손에 들어간 소프트웨어가 절대로 변경되지 않는 아티팩트(인공물)라기 보다는 반응하고 적응(react and adapt)해야 한다는 것을 받아들어야 합니다.

이처럼, 우리 아키텍트들은 완벽한 최종 제품을 만다는 것에서 생각을 바꾸고, 대신에 올바른 시스템이 등장할 수 있는 프레임워크를 만드는데 도움이 되도록 집중하고 더 많이 배우면서 계속적으로 성장해야만 합니다.

비록 다른 직업과 너무 많이 비교해 보라는 경고로 많은 부분을 썼지만, IT 아키텍트의 역할에 대해서 좋아하는 한가지 비유가 있습니다. 그리고 이 비유가 우리가 이 역할을 하기를 원하는 것을 더 잘 캡슐화한다고 생각합니다.

Erik Doernenburg는 처음에 우리의 역할을 환경을 건설하는 아키텍트보다 도시건설 계획자(town planner)로 생각해야 한다는 아이디어를 공유했습니다.
도시 건설 계획자의 역할은 전에 SimCity 게임을 해본 사람들 중 누구에게나 익숙해야 합니다. 도시 건설 계획자의 역할은 다양한 정보 소스를 살펴보고, 미래의 용도를 고려하여 오늘날 시민들의 요구사항에 가장 적합한  도시 배치를 최적화하는 것입니다.

도시가 어떻게 진화하는지에 대해 영향을 미치는 방식은 흥미롭습니다.
"특별한 건물을 여기에 세워라."라고 말하지 않고, 대신에 도시를 구역화합니다.

따라서 SimCity에서처럼, 도시의 일부를 산업 구역(industial zone)으로 나타내고, 다른 부분은 거주 지역으로 지정할 수 있습니다.
정확히 무슨 건물이 세워질지에 대한 의사 결정은 다른 사람들에게 달려 있지만, 제한이 있습니다. 만약 공장을 세우고 싶다면, 산업 구역에 있어야만 할 것입니다.
하나의 구역에서 무슨 일이 일어날지에 대해서 너무 많은 걱정없이, 도시 건설 계획자는 어떻게 사람들과 시설들이 하나의 구역에서 다른 구역으로 이동할 것인지에 대해 더 많은 시간을 보낼 것입니다.

한 명 이상의 사람이 도시를 생물(living creature)로 비유했습니다. 도시는 시간이 지나면서 변화합니다. 거주자가 다른 방식으로 사용하거나 외부의 힘이 도시를 사용함에 따라서 변화하고 진화합니다.
도시 건설 계획자는 이러한 변화를 예상하기 위해서 최선을 다하지만, 무엇이 일어날지에 대해 모든 측면에서 직접적으로 컨트롤하려고 하는 것이 쓸모 없는 일임을 받아들입니다.

소프트웨어와의 비교는 분명해야 합니다.
사용자가 우리의 소프트웨어를 사용하기 때문에, 우리는 반응하고 변화해야 합니다.

우리는 앞으로 일어날 모든 일을 예견할 수 없습니다. 그리고 모든 우발적인 상황(eventuality)에 대한 계획을 수립하기보다 모든 마지막 일을 지나치게 지정하는 충동을 피함으로써 변화를 허용하는 계획을 세워야만 합니다. 우리의 도시-시스템-는 사용하는 모든 사람에게 좋고 행복한 장소가 되어야만 합니다.

사람들이 자주 잊어버리는 한 가지는 우리 시스템이 단지 사용자만을 수용하는 것이 아니라, 거기서 일해야 하는 개발자와 운영자도 또한 수용하고, 필요 시 변경할 수 있는지 확인하는 사람들까지도 수용한다는 것입니다.

Frank Buschmann의 용어를 빌리자면, 아키텍트는 시스템이 개발자들도 거주할 수 있도록 보장하는 의무를 가집니다. 아키텍트처럼 도시 건설 계획자도 그 계획이 뒤따르지 않을 때도 알아야 합니다.

처방전이 적기 때문에, 올바른 방향으로 바꾸는 것을 최소화해야겠지만, 만약 누군가가 거주 지역에 하수 처리장을 세우기로 결정했다면, 그것을 막을 수 있어야 합니다. 도시 건설 계획자와 같은 아키텍트는 광범위한 행정 분야에서 방향을 결정할 필요가 있고, 제한된 경우에만 구현 세부 사항에 대해 매우 구체적으로 관여해야 합니다. 시스템에 목적에 맞도록 보장해야 하지만, 또한 시스템은 미래를 위한 플랫폼이기도 합니다. 또한 사용자와 개발자를 동등하게 행복하게 하는 시스템이 되도록 보장해야만 합니다.

이것은 꽤 큰 순서처럼 들립니다. 우리는 어디에서 시작해야 할까요?


Zoning
(영역 설정)


그래서 잠시 동안만 계속해서 도시 건설 계획자로서 아키텍트를 은유해보자면, 우리 영역은 무엇일까요?

이것은 우리의 서비스 경계나 낮은 수준(coarse-grained)의 서비스 그룹입니다. 아키텍트로서 영역 간에 무엇이 발생할지 보다 영역 내에서 발생하는 일들에 대해 훨씬 덜 걱정할 필요가 있습니다. 그것은 우리 서비스들이 서로 어떻게 이야기하는지에 대해서 생각하거나, 혹은 어떻게 우리 시스템 전체에 대한 상태를 적절하게 모니터링할 수 있는지에 대해서 보장하는데 시간을 보낼 필요가 있습니다.

영역 내에서 어떻게 들어가는가에 대한 방법은 다소 다릅니다.

많은 조직들은 팀의 자율성을 극대화하기 위해서 마이크로서비스를 채택했습니다. 10장에서 확대하여 살펴볼 것입니다.

만약 여러분이 그런 조직에 있다면, 올바른 지역적인 결정을 내리기 위해서 더 많이 팀에 의존할 것입니다.

그러나, 영역 사이, 혹은 전통적인 아키텍처 다이어그램에서 박스 사이에서 우리는 주의를 기울여야 합니다. 여기서 잘못되면, 모든 종류의 문제가 발생하고, 바로잡기 매우 어려울 수 있습니다.
각 서비스내에서, 영역을 소유한 팀이 다른 기술 스택이나 데이터 저장소를 선택하면 문제가 없을 수 있습니다. 물론, 다른 관심사가 여기에 끼어들 수도 있습니다.

10가지의 지원할 수 있는 다른 기술 스택을 가지고 있는 경우, 작업을 위한 올바른 도구를 팀이 선택하도록 하는 경향은 사람을 임대하거나 팀 사이에 사람들이 이동하기에 더 어렵게 된다는 사실에 의해 완화될 수 있습니다. 마찬가지로, 만약 각 팀이 완전히 다른 데이터 저장소를 선택한다면,팀의 규모에서 실행하기에는 충분히 경험하지 못했음을 알게 될 수도 있습니다.

예를 들면, 넷플릭스(Netflix)는 대부분의 데이터 저장소 기술로 카산드라(Cassandra)로 표준화되어 있습니다.

비록, 모든 경우에 적합한 것은 아니지만, 넷플릭스는 카산드라에 대한 도구화와 전문 지식을 구축하여 얻은 가치는 특정 작업에 더 좋을 수 있는 다른 여러 플랫폼을 지원하고 운영하는 것보다 더 중요하다고 생각합니다.

넷플릭스는 규모가 가장 강력한 최우선 요소일 수 있는 극단적인 경우이지만, 아이디어를 얻을 수 있습니다.

그러나, 서비스 사이에서는 사태가 어지러울 수 있습니다. 만약, 하나의 서비스가 HTTP REST를 노출하기로 결정했고, 또다른 서비스는 프로토콜 버퍼(protocol buffer)를 사용하고, 세번째 서비스는 Java RMI를 사용하기로 결정했다면, 소모하는 서비스(호출하는 서비스 : consuming service)가 다양한 스타일의 상호 교환을 이해하고 지원해야 하므로 통합은 악몽이 될 수 있습니다.

이것이 "박스 사이에서 어떤 일이 일어날지에 대해서 걱정해야 하고, 내부에서 무슨 일이 일어날지에 대해서는 자유로워야 한다"는 가이드라인을 준수하려고 노력하는 이유입니다.


THE CODING ARCHITECT
(코딩하는 아키텍트)

우리가 만든 시스템에 개발자들이 거주할 수 있도록 한다면, 아키텍트는 의사 결정의 경향에 대해서 이해를 해야 합니다.
최소한 이것은 팀과 함께 시간을 보내는 것을 의미합니다. 이상적으로는 개발자들이 팀에서 또한 실제로 코딩을 하면서 보낸다는 것을 의미합니다.

페어 프로그래밍(둘이서 짝을 지어 프로그램을 짜는 것 : pair programming)을 연습하는 사람들에 대해서, 아키텍트가 페어의 멤버 중 한명으로 짧은 기간 동안 팀에 참여하는 것은 간단한 일이 됩니다.

이상적으로는, 일반적인 일이 무엇인지를 정말로 이해하기 위해서 일반적인 스토리로 일을 해야 합니다.
아키텍트가 팀에 실제로 앉아 있는 것이 얼마나 중요한 것인지 강조할 수 없습니다. 이것은 전화를 걸거나 단지 코드를 보는 것보다 훨씬 더 효과적입니다.

얼마나 자주 이런 일을 해야 하는지는, 여러분이 일하는 팀의 크기에 굉장히 밀접하게 달려 있습니다. 하지만, 키(key)는 그것이 일상적인 활동(routine activity)이어야 한다는 것입니다.

예를 들면, 여러분이 4개의 팀과 함께 일을 한다면, 매 4주마다 각 팀과 함께 하루 중 절반을 보내는 것이 함께 일하는 팀과의 인식을 함께 하고 커뮤니케이션을 향상시킬 수 있습니다.



A Principled Approach
(주의 접근법 : 원칙에 입각한 접근법)


규칙은 어리석은 자의 순종과 현명한 자의 인도를 위한 것입니다.
( Rules are for the obedience of fools and the guidance of wise men.)
 ----- Generally attributed to Douglas Bader

시스템 설계에서 의사 결정하는 것은 모두 장단점(trade-offs)이 있습니다. 그리고 마이크로서비스 아키텍처는 많은 장단점을 제공합니다. 데이터스토어를 선택할 때, 경험이 적은 플랫폼을 선택하지만, 더 좋은 확장성을 제공하나요?

2개의 다른 기술 스택이 우리 시스템에 있는 것이 좋습니까? 3개는 어떻습니까?

어떤 의사 결정은 우리가 이용할 수 있는 정보로 현장을 완전하게 할 수 있고, 이러한 경우가 가장 쉬운 의사 결정입니다.
그러나 불완전한 정보로 의사 결정을 해야만 하는 사항은 무엇이 있을까요?

의사 결정에 프레임(frame)을 적용하는 것이 도움이 될 수 있습니다. 의사 결정의 틀을 만드는데 도움이 되는 훌륭한 방법은 우리가 달성하고자 하는 목표에 기반하여 일련의 원칙(principles)과 실행 절차(practice)를 정의하는 것입니다.

순서대로 살펴봅시다.

Strategic Goals
(전략적인 목표)

아키텍트의 역할은 이미 충분히 위압적입니다. 따라서 다행스럽게도 우리는 일반적으로 전략적인 목표를 정의할 필요가 없습니다.

전략적인 목표는 회사가 어디로 가고 있는지, 고객을 행복하게 하는 최선의 방법을 어떻게 보여줄 것인지를 이야기해야만 합니다.

이것들은 고수준(high-level)의 목표가 될 것입니다. 그리고 기술은 전혀 포함되어 있지 않을 수도 있습니다.
그것들은 회사 수준이나 부서 수준에서 정의될 수 있습니다.

그 전략 목표들은 "새로운 시장을 개척하기 위한 동남 아시아로의 확장"이거나 "셀프 서비스를 통해 고객이 가능한 한 많은 것을 성취하게 하자"와 같은 것들이 될 수 있습니다.

핵심(key)은 여러분의 조직이 지향하는 곳이 어디인지, 따라서 기술이 거기에 정렬되어 있는지를 확인해야 하는 것입니다.
만약 여러분이 회사에서 기술적인 비전을 정의하는 사람이라면, 여러분 조직의 비기술적인 파트(또는 종종 우리가 비즈니스라고 부르는)와 더 많은 시간을 보내야 할 수도 있습니다.

비즈니스를 추진하는 비전은 무엇입니까? 그리고 그것이 어떻게 변화하나요?

Principles
(원칙)

원칙(principles)은 조금 더 큰 목표에 자신이 하는 일을 부합시키기 위해서 만든 규칙이고, 때때로 변화할 것입니다. 예를 들면, 만약 조직으로서 여러분의 전략적 목표 중 하나가 새로운 기능을 시장에 출시하기 위한 시간을 줄이는 것이라면, delivery team은 다른 팀과 독립적으로 준비되었을 때 언제라도 소프트웨어의 수명 주기(lifecycle)을 온전히 통제하는 원칙을 정의할 수 있습니다.

만약 또다른 목표가 여러분의 조직이 다른 나라에서 적극적으로 성장하는 것이라면, 데이터의 주권을 존중하기 위해서 전체 시스템을 로컬에서 배포할 수 있도록 이식성이 있어야 한다(portable)는 원칙을 구현하도록 결정할 수 있습니다.

여러분은 아마도 이것들을 짊어짐을 원하지는 않을 것입니다.

10보다 작은 숫자는 사람들이 기억할 수 있을만큼 충분히 작거나 작은 포스터에 적합한 좋은 숫자입니다. 더 많은 원칙을 가지고 있을수록, 서로 겹치거나 모순될 위험이 더 커집니다.

Heroku의 12가지 팩터는 Heroku 플랫폼에서 잘 동작하는 어플리케이션을 만들 수 있도록 도와주는 목표를 중심으로 구조화된 일련의 디자인 원칙들입니다. 그것들은 또한 다른 맥락에서 의미가 있을 수 있습니다.

원칙들 중 일부는 실제로 어플리케이션이 Heroku 상에서 동작하기 위해 필요한 동작에 근거한 제약 조건들입니다. 제약 조건은 실제로 변경하기 매우 어렵지만 (혹은 사실상 불가능), 반면에 원칙들은 선택하기로 결정한 것들입니다.

제약조건과 비교하여 정말로 변경할 수 없는 그러한 것들을 가리키도록 도와주기 위한 원칙들을 명시적으로 호출하도록 결정할 수 있습니다.
개인적으로, 때때로 도전적인 제약 사항들을 장려하고, 정말로 움직일 수 없는지를 보기 위해서 제약사항들을 같은 목록에 유지할 만한 가치가 있다고 생각합니다.

Practices
(실행 절차)

실행 절차(practice)들은 우리의 원칙이 어떻게 이행되고 있는지를 확인하는 것입니다.
작업 수행을 위한 상세하고 실용적인 지침 세트라고 할 수 있습니다.

종종 기술 중심적이고, 어떤 개발자도 이해할 수 있을 정도로 충분히 낮은 수준이어야 합니다. 실행 절차에는 코딩 가이드라인, 모든 로그 데이터가 중앙 집중식으로 보존되어야 할 필요가 있는지, 혹은 HTTP/REST가 표준 통합 스타일(standard integration style)인지 여부가 포함될 수 있습니다. 기술적인 특성으로 인해, 실행 절차는 원칙보다 더 자주 변경됩니다.

원칙(principles)과 마찬가지로, 가끔 실행 절차들도 조직의 제약 사항들을 반영합니다. 예를 들면, 단지 CentOS만 지원한다면, 실행 절차에 반영되어야 합니다.
실행 절차는 원칙을 뒷받침해야 합니다. Delivery Team이 시스템의 전체 수명주기(lifecycle)를 통제한다는 원칙은 모든 서비스가 격리된 AWS 계정에 배포되고, 리소스에 대한 셀프 서비스 관리(self-service management)와 다른 팀으로부터의 격리를 제공한다는 것을 의미합니다.

Combining Principles and Practices
(원칙과 실행절차의 결합)

한 사람의 원칙은 다른 사람의 실행 절차가 됩니다. 예를 들면, HTTP/REST의 사용을 실행 절차보다 원칙으로 부르기로 결정할 수 있습니다. 그리고 그것은 괜찮을 것입니다.
요점(key point)은 시스템이 어떻게 진화하는지를 가이드하는 포괄적인 아이디어를 가지고 있고, 그러한 아이디어를 어떻게 구현할지에 대해 사람들이 알 수 있도록 충분한 세부사항들을 가지고 있는 것에 대해서 가치가 있다는 것입니다.

아마도 단일 팀과 같이 충분히 작은 그룹에 대해서, 원칙과 실행 절차를 결합하는 것은 좋을 것입니다.
그러나 기술과 업무 실행 절차가 다를 수 있는 더 큰 조직에서는 공통된 일련의 원칙에 매핑되는 한, 다른 곳에서 다른 실행 절차를 원할 수도 있습니다.

예를 들면, .NET 팀은 일련의 실행 절차 중 하나를 가지고 있을 수 있고, Java 팀은 양쪽에 공통된 일련의 실행 절차를 가지고 있을 수 있습니다.
하지만, 원칙은 둘 모두 동일할 수 있습니다.

A Real-World Example
(실 세상의 예)

동료 Evan Bottcher는 고객 중 한명과 작업하는 과정에서 그림 2-1에서 보이는 다이어그램을 개발했습니다.

이 그림은 목표, 원칙, 실행 절차의 상호작용을 매우 분명한 형식으로 보여줍니다. 2년여 과정 동안, 맨 오른쪽에 있는 실행 절차는 상당히 규칙적으로 바뀌지만, 반면에 원칙은 꽤 고정적으로 유지됩니다.

이와같은 다이어그램은 한장의 종이에 멋지게 인쇄하여 공유할 수 있습니다. 그리고 각 아이디어는 일반적인 개발자가 기억하기에 충분히 간단합니다.
물론, 여기에는 각 요점 뒤에 더 세부 사항이 있지만, 요약된 형식으로 이것을 표현할 수 있다는 것은 매우 유용합니다.

사용자 삽입 이미지
<2-1. A Real-world example of principles and practices>

이러한 항목들 중 일부를 지원하는 문서를 가지고 있는 것이 좋습니다.

비록, 대체로 그러한 아이디어를 구체화하는 직접 볼 수 있고, 점검할 수 있고, 실행할 수 있는 예제 코드를 가진 아이디어를 좋아합니다.
더 나아가서 박스 밖에서 옳은 일을 하는 도구를 만들 수 있습니다. 즉시 그에 대해 더 깊이 논의할 것입니다.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/813

[Author : Sam Newman]

수년 동안 우리는 시스템을 구축할 수 있는 더 좋은 방법을 찾고 있습니다. 이전에 무엇을 했는지, 새로운 기술을 채택하고, 기술 회사의 새로운 물결이 어떻게 고객과 개발자들이 모두 행복하게 하는 IT시스템을 만들기 위한 다양한 방법을 운영하는지를 관찰했습니다.

 

Eric Evans의 책 Domain-Driven Design(Addison-Wesley)은 우리 코드에서 실제 세계를 표현하는 중요성을 이해하고, 우리 시스템을 더 좋은 방법으로 모델링하는 것을 보여주었습니다. 지속적인 배포(continuous delivery) 개념은 소프트웨어를 보다 효과적이고 효율적으로 상용 환경에 가져오는 방법을 보여주었고, 모든 체크인을 릴리즈 후보로 다루어야 한다는 아이디어를 우리가 가지게 했습니다. 웹이 어떻게 동작하는지에 대한 이해는 기계와 기계 사이에서 대화하는 더 좋은 방법을 개발하게 했습니다. Alistair Cockburn 6각형 아키텍처 개념은 비즈니스 로직이 숨어 있는 Layered Architecture에서 우리가 멀어지게 했습니다. 가상화 플랫폼은 인프라 자동화를 통해 머신의 규모를 다루는 방법을 우리에게 제공하여 프로비저닝과 리사이즈를 가능하게 했습니다.

 

아마존과 구글과 같은 일부 대규모의 성공적인 조직들은 서비스의 전체 수명 주기를 소유한 소규모 팀의 견해를 지지했습니다. 그리고 더 최근에, Netflix는 불과 10년 전만 해도 이해하기 힘든 거대한 규모의 단단한 시스템을 구축하는 방법을 공유했습니다.

 

- Domain-Driven Design

- Continuous Delivery

- On-Demand Virtualization (주문형 가상화)

- Infrastructure automation

- Small autonomous teams

- Systems at scale

 

마이크로서비스가 이 세상에 등장했습니다.

 

사실 마이크로서비스는 전에 발명되거나 설명된 것은 아닙니다. 실제 세상에서 사용함으로써 트렌드나 패턴으로 등정했습니다. 그러나 마이크로서비스는 이전에 있었던 모든 것들 때문에 존재합니다.

 

이 책을 통해서 마이크로서비스를 구축, 관리, 발전시키는 방법에 대한 그림을 그리는데 도움을 주어 이러한 최우선 업무에서 뛰어나게 할 것입니다.

 

많은 조직에서 잘 나누어진 마이크로서비스 아키텍처를 채택함으로써 소프트웨어를 빠르게 제공하고 새로운 기술들을 채택할 수 있었습니다.

 

마이크로서비스는 우리에게 더 자유롭게 반응하고 다른 의사 결정을 내려서 우리 모두에게 영향을 미치는 피할 수 없는 변화에 더 빠르게 대응할 수 있게 합니다.

 

What Are Micoservices?

 

마이크로서비스는 함께 동작하는 작고, 자율적인 서비스입니다. 이 정의를 좀 더 세분화하고 마이크로서비스를 다르게 하는 특성들에 대해서 고려해 보겠습니다.

 

Small, and Focused on Doing One Thing Well

(작고, 한가지를 잘하는 것에 집중)

 

코드베이스는 우리가 새로운 기능들을 추가하는 코드를 작성할 때 커집니다.  시간이 지남에 따라, 코드베이스가 커지기 때문에 어디를 변경해야 하는지 알기 어려워질 수 있습니다. 명확하고, 모듈화된 단단히 짜여 하나로 된(monolithic) 코드베이스 추진에도 불구하고, 이러한 제멋대로인 프로세스 내 경계가 너무 자주 파괴됩니다. 유사한 함수와 관계된 코드가 널리 퍼지기 시작하고, 버그 수정이나 프로그램 구현이 더 어려워집니다.

 

모놀리스 시스템에서 우리는 종종 추상화를 하거나 모듈화를 하여 코드가 더 응집되어 있는지를 확인하려고 노력함으로써 이러한 세력에 대항하여 싸웁니다.

 

관련 코드를 그룹으로 묶는 응집(Cohesion)은 마이크로서비스에서 중요한 개념입니다. 이것은 Robert C. Martin '단일 책임 원칙의 정의(Definition of the Single Responsibility Principle)'에 의해 강화되었습니다. "동일한 이유로 변경되는 것들을 함께 모아서 다른 이유로 변경되는 것들을 분리하라"라고 말하고 있습니다.

 

마이크로서비스는 독립적인 서비스에도 동일한 접근방식을 사용합니다.

우리는 주어진 기능 조각에 대한 살아있는 코드가 어디에 있는지를 명확하게 함으로 서비스 경계를 비즈니스 경계에 초점을 맞춥니다. 그리고 이 서비스가 분명한 경계에 초점을 유지함으로써, 서비스가 너무 커지는 유혹을 피할 수 있습니다. 이것이 소개할 수 있는 연관된 모든 어려움입니다.

 

제가 자주 묻는 질문은 작은 것이 얼마나 작습니까?라는 것입니다.

코드 라인수가 문제라면, 일부 언어는 다른 언어보다 더 표현력이 우수하므로 더 적은 라인에서 더 많은 일을 수행할 수 있습니다. 또한, 많은 코드 라인은 여러 의존성을 끌어낼 수 있다는 사실도 고려해야만 합니다. 더욱이, 도메인 중 일부는 당연히 복잡해서 더 많은 코드가 필요할 수 있습니다.

 

호주 RealEstate.com Jon Eaves는 특별한 맥락에서 의미가 있는 경험과 상식에 입각하여 마이크로서비스는 2주만에 다시 작성할 수 있는 어떤 것으로 특징지었습니다. 제가 드릴 수 있는 흔한 또다른 대답은 충분히 작고, 더 작아질 수 없다는 것입니다.

 

컨퍼런스에서 발표할 때, 너무 크고 쪼개고 싶어하는 시스템을 가진 사람이 누구냐고 거의 항상 묻습니다. 거의 모든 사람들이 손을 듭니다. 우리는 너무 큰 것이 무엇인지 잘 알고 있는 것처럼 보이기 때문에 코드 한 조각이 너무 크다고 더 이상 느껴지지 않을 때, 그것은 충분히 작다고 주장할 수 있습니다.

 

얼마나 작은가에 대해 대답하는데 도움이 되는 강력한 요소는 얼마나 서비스가 팀 구조와 맞춰져 있는가 입니다. 만약 코드베이스가 작은 팀이 관리하기에는 너무 크다면, 부수는 것을 생각해 보는 것이 매우 현명합니다. 나중에 조직 조정에 대해서 더 이야기할 것입니다.

 

작은 것이 충분히 작아졌을 때, 이런 측면에서 생각하고 싶습니다. : 서비스가 더 작아질수록 마이크로서비스의 장점과 단점을 극대화할 수 있다.

 

서비스가 더 작아질수록, 독립성 관점에서 장점이 증가합니다.

하지만, 점점 더 많은 가동부(moving parts)를 가지고 있음으로 드러나는 복잡성도 또한 커지는데 이 책을 통해서 탐구할 것입니다. 이러한 복잡성을 더 잘 처리할수록, 점점 더 작은 서비스를 위해 노력할 수 있습니다.

 

Autonomous

(자율적인?)

 

마이크로서비스는 분리된 개체입니다. PAAS(Platform As A Service)에 격리된 서비스로 배포되거나 그 자체로 OS(Operating System) 프로세스일 수 있습니다. 비록 오늘날 머신의 정의가 꽤나 흐릿하지만 동일한 머신에 여러 개의 서비스를 패키지하는 것을 피하려고 합니다. 나중에 논의하겠지만, 비록 이러한 격리로 인해 약간의 오버헤드가 추가될 수 있지만, 단순성의 결과는 분산 시스템의 추론을 훨씬 더 쉽게 하고, 더 새로운 기술들이 이러한 형태의 배포와 관련된 많은 문제들을 완화할 수 있습니다.

 

서비스 간의 모든 커뮤니케이션은 서비스 간의 분리를 강화하고 긴밀한 결합의 위험을 피하기 위해서 네트워크 호출을 통해 이루어집니다.

 

이러한 서비스는 서로 독립적으로 변경될 수 있어야 합니다. 그리고 소비자의 변경 요구 없이 스스로 배포되어야 합니다. 우리의 서비스가 무엇을 노출해야 하고, 무엇을 숨겨야 하는지를 생각할 필요가 있습니다. 너무 많이 공유하면 소비하는 서비스가 내부 표현과 연결되게 됩니다. 이것은 자율성을 감소시켜서 변경 사항이 발생할 때, 소비자와의 추가적인 조정이 필요하게 됩니다.

 

서비스는 API(application programming interface)를 노출하며, 협업 서비스들은 이러한 API를 통해 우리 서비스와 통신합니다. 우리는 또한 어떤 기술이 소비자와 연결되지 않도록 하는데 적합한지에 대해 생각할 필요가 있습니다. 이것은 기술 선택에 제약을 주지 않기 위해서 기술과 무관한 API를 선택하는 것을 의미할 수 있습니다. 이 책에서 좋은, 연결되어 있지 않은 API의 중요성에 대해서 몇 번이나 다시 돌아올 것입니다.

 

디커플링(decoupling)이 없으면-분리되지 않으면, 모든 것이 무너집니다. 황금률 : 다른 것은 변경 없이 서비스 그 자체만을 변경하고 배포할 수 있는가? 대답이 'no'라면 우리가 이 책을 통해서 논의하고자 하는 많은 장점들이 달성하기 어렵게 될 것입니다.

 

디커플링을 잘 하기 위해서는 서비스를 올바르게 모델링하고 API를 올바르게 얻어야 합니다. 그 부분에 대해서 많은 이야기를 할 것입니다.

 

Key Benefits

(주요 이점들)

 

마이크로서비스의 이점은 많고 다양합니다. 이러한 많은 장점들은 분산 시스템의 문에 놓여질 수 있습니다. 그러나 마이크로서비스는 첫째로 분산 시스템과 SOA 개념을 얼마나 멀리 가지고 가는지에 따라 이러한 장점들을 더 많이 달성하는 경향이 있습니다.

 

Technology Heterogeneity

(기술 이질성)

 

여러 개의 협업하는 서비스들로 구성된 시스템에서 각각의 내부에 서로 다른 기술을 사용하기로 결정할 수 있습니다. 이것은 더 표준화되고, 종종 마지막에 최하위의 공통분모가 되도록 하는 널리 적용되도록 만든(one-size-fits-all) 접근방법을 선택하는 것보다 각각의 작업에 적합한 올바른 툴을 정할 수 있게 합니다.

 

시스템의 일부가 성능을 개선할 필요가 있다면, 필요한 성능 수준을 더 잘 달성할 수 있는 다른 기술 스택을 사용하기로 결정할 수 있습니다. 또한 시스템의 다른 부분의 변경에 필요한 데이터를 어떻게 저장할지를 결정할 수 있습니다. 예를 들면, 소셜 네트워크의 경우, 소셜 그래프의 상호 연관성을 높게 반영하기 위해 사용자의 상호작용을 그래프 기반 데이터베이스에 저장할 수 있습니다. 그러나 아마도 사용자가 만든 게시물은 문서 기반 데이터 저장소에 저장할 수 있으므로, 그림 1-1에 보이는 것처럼 이기종 아키텍처가 떠오르게 됩니다.

 

사용자 삽입 이미지

 

마이크로서비스를 통해 기술을 보다 빠르게 받아들일 수 있고, 새로운 발전이 어떻게 우리를 도와주는지를 이해할 수 있습니다. 새로운 기술을 시도하고 채택하는데 있어서 가장 큰 장벽 중 하나는 그와 관련된 위험입니다. 모놀리틱(monolithic) 어플리케이션에서 새로운 프로그래밍 언어, 데이터베이스, 혹은 프레임워크를 시도하고 싶다면, 그 변화는 시스템의 많은 부분에 영향을 미치게 됩니다. 여러 서비스로 이루어진 시스템에서는 새로운 기술을 시도해 볼 수 있는 여러 새로운 장소가 있습니다. 잠재적인 부정적 영향을 제한할 수 있다는 것을 알기 때문에 아마도 가장 위험이 적은 서비스를 선택해서 기술을 사용할 것입니다. 많은 조직에서는 신기술을 보다 빠르게 흡수하여 실제 이점으로 활용할 수 있는 능력을 알고 있습니다.

 

물론, 여러 기술을 채택하는 것은 오버헤드 없이 이루어지지 않습니다. 어떤 조직에서는 언어 선택에 제한을 가하기도 합니다.

 

예를 들어, Netflix Twitter에서는 시스템의 안정성과 성능을 잘 알고 있기 때문에, 대부분 JVM(Java Virtual Machine)을 플랫폼으로 사용합니다.

 

또한, 그들은 대규모 운영을 더 쉽게 하는 JVM을 위한 라이브러리와 도구들을 개발하여 사용하고 있습니다. 그러나 Java 기반이 아닌 서비스나 클라이언트는 더 어려워집니다. Twitter Netflix 모두 모든 작업에 하나의 기술 스택만을 사용하는 것은 아닙니다.

 

다른 기술을 혼합하는 것에 대해 고려하는 또 다른 대위법은 크기입니다. 실제로 2주 안에 마이크로서비스를 다시 작성할 수 있다면, 새로운 기술의 채택에 대한 위험을 완화할 수 있을 것입니다.

 

이 책에서 볼 수 있듯이, 마이크로서비스에 관련된 많은 것들처럼 올바른 균형을 찾는 것이 전부입니다. Chapter 2에서 진화적인 아키텍처에 초첨을 맞춘 기술을 어떻게 선택하는지를 논의하고, 통합(integration)을 다루는 Chapter 4에서 서비스가 어떻게 과도한 커플링(coupling) 없이 서로 독립적으로 기술을 진화시킬 수 있는지를 배우게 될 것입니다.

 

Resilience

(회복력? 복원력?)

 

탄력(resilience) 공학의 핵심 개념은 칸막이(bulkhead)입니다. 시스템의 한 구성 요소가 실패했을 경우, 그 장애가 종속되어 있지 않으면 그 문제를 격리할 수 있습니다. 그리고 시스템의 나머지는 계속 동작할 수 있습니다. 서비스의 경계는 명확한 칸막이가 됩니다. 모놀리틱(monolithic) 서비스에서는 서비스가 실패하면 모든 동작이 멈춥니다. 모놀리틱 시스템에서는 장애 가능성을 줄이기 위해 여러 시스템에서 실행할 수 있습니다. 그러나 마이크로서비스에서는 서비스의 전체 장애를 처리하고, 기능성을 적절히 떨어뜨리는 시스템을 구축할 수 있습니다.

 

그러나 조심해야할 필요가 있습니다. 마이크로서비스가 이러한 향상된 복원력을 적절하게 채택할 수 있도록 하기 위해서는 분산 시스템에서 다루어야 하는 새로운 장애 요인에 대해 이해할 필요가 있습니다. 머신처럼 네트워크에서 실패할 수 있습니다. 이것을 어떻게 다루는지를 알아야 합니다. 그리고 그 장애가 소프트웨어의 최종 사용자에게 어떤 영향을 주는지도 알아야 합니다.

 

Chapter 11에서 복원력을 더 잘 다루고, 실패 모드를 처리하는 방법에 대해서 이야기할 것입니다.

 

Scaling

(확장)

 

대규모의 모놀리틱(monolithic) 서비스에서 우리는 모든 것을 함께 확장해야 합니다.

시스템 전체 중 하나의 작은 부분은 성능에 제약이 있지만, 그러한 동작이 하나의 거대한 모놀리틱 어플리케이션에 고정되어 있다면 모든 것을 하나의 조각으로 확장하도록 처리해야 합니다. 더 작은 서비스들은 확장이 필요한 서비스만 확장할 수 있기 때문에, 그림 1-2처럼 더 작고 덜 강력한 하드웨어에서 시스템의 다른 부분들을 실행하도록 할 수 있습니다.

 

사용자 삽입 이미지

 

온라인 패션 소매업체인 Glit은 이러한 정확한 이유로 마이크로서비스를 채택했습니다. 2007년에 모놀리틱 Rails 어플리케이션으로 시작해서, 2009년에 Glit의 시스템은 부하에 대처할 수 없었습니다. 시스템의 핵심 부분을 분리함으로써 Glit은 트래픽 급증을 더 잘 처리할 수 있었고, 오늘날 450개가 넘는 마이크로서비스가 있습니다. 각각의 서비스는 여러 개의 분리된 머신에서 실행되고 있습니다.

 

아마존 웹 서비스(Amazon Web Services)에서 제공하는 것과 같은 주문형(on-demand) 프로비저닝 시스템을 채택할 때, 필요한 부분에 대한 요구에 대해 확장을 적용할 수 있습니다. 이를 통해 비용을 보다 효과적으로 제어할 수 있습니다. 하지만 종종 아키텍처적인 접근 방법이 항상 즉각적인 비용 절감과 밀접한 연관이 있는 것은 아닙니다.

 

Ease of Deployment

(쉬운 배포)

 

한 줄을 백만 라인의 모놀리틱 어플리케이션으로 변경하는 것은 변경 사항을 릴리즈(release)하기 위해서 전체 어플리케이션을 배포해야 합니다. 그것은 커다란 영향을 미치는, 고위험의 배포일 수 있습니다. 실제로, 큰 영향을 미치고 고 위험을 가지는 배포는 이해할 수 없는 공포로 인해 드물게 발생합니다. 불행하게도, 이것은 우리의 변경 사항들이 우리의 새로운 버전의 어플리케이션이 다수의 변경 사항을 가진 제품화가 될 때까지 릴리즈 사이에 쌓이면서 점점 커지는 것을 의미합니다. 릴리즈 사이에 델타(변경사항)가 더 클수록 무엇인가가 잘못된 위험이 더 높아집니다!

 

마이크로서비스에서는 단일 서비스를 변경할 수 있습니다. 그리고 나머지 시스템에 독립적으로 배포할 수 있습니다. 이를 통해 코드를 더 빠르게 배포할 수 있습니다. 만약 문제가 발생하면, 개별 서비스로 신속하게 격리될 수 있고, 빠른 롤백을 쉽게 달성할 수 있습니다. 그것은 고객에게 더 빠르게 새로운 기능을 제공할 수 있음을 의미합니다. Amazon Netflix같은 조직들이 왜 이러한 아키텍처를 사용하는지의 주된 이유 중 하나입니다. 마이크로서비스는 가능한 많은 방해물을 제거하여 소프트웨어가 밖으로 나갈 수 있게 합니다. 이 공간에서의 기술은 지난 2년 동안 크게 변화했습니다. 그리고 Chapter 6에서 마이크로서비스 세계에서 배포에 관한 주제를 더 깊게 살펴볼 것입니다.

 

Organizational Alignment

(조직적 조정)

 

우리중 많은 사람들이 대규모 팀과 코드베이스와 관련된 문제들을 경험했습니다. 이 문제는 팀이 분산될 때 더 심해질 수 있습니다. 우리는 또한 더 작은 코드베이스에서 작업하는 더 작은 팀이 더 생산성이 높은 경향이 있다는 것을 알고 있습니다.

 

마이크로서비스는 아키텍처를 조직에 더 잘 연계할 수 있게 합니다. 그리고, 하나의 코드베이스에서 작업하는 사람의 수를 최소화하여 팀의 크기와 생산성 측면에서 최고의 결과를 얻을 수 있게 합니다. 우리는 팀 간의 서비스 소유권을 옮겨서 하나의 서비스에 대해 일하는 사람들을 같은 곳에 있도록 할 수 있습니다. Chapter 10에서 Conway의 법칙을 논의할 때 이 주제에 대해서 훨씬 더 자세히 설명할 것입니다.

 

Composability

(결합성)

 

분산 시스템과 SOA에서의 주요 약속 중 하나는 기능을 재사용하는 기회를 열어놓는 것입니다. 마이크로서비스에서는 기능을 다른 목적에 대해서 다양한 방법으로 사용하게 합니다. 소비자가 우리 소프트웨어를 어떻게 사용하는지에 대해 생각할 때 특히 중요할 수 있습니다. 데스크톱 웹 사이트나 모바일 어플리케이션에 대해서 좁혀서 생각할 때, 시간은 흘러갑니다. 이제 우리는 웹, 네이티브 어플리케이션(스마트폰 등에 직접 설치해야 하는 어플리케이션), 모바일 웹, 티블릿 앱, 혹은 웨어러블 디바이스에 대해 서로 결합을 짜내기 위한 무수한 방법을 생각할 필요가 있습니다.

 

조직이 좁은 채널 측면에서 생각이 고객 참여의 전체론적인 개념으로 옮겨감에 따라 계속되게 할 수 있는 아키텍처가 필요합니다.

마이크로서비스로 외부 당사자가 처리할 수 있도록 우리 시스템의 경계선들을 오픈하는 것에 대해 생각해 보십시오. 상황이 바뀜에 따라 우리는 다른 방식으로 물건들을 만들 수 있습니다. 모놀리틱 어플리케이션에서는 밖에서 사용할 수 있는 하나의 거칠게 나누어진 경계가 있는 경우가 많습니다. 더 유용한 것을 얻기 위해 그것을 깨고 싶다면, 해머가 필요할 것입니다! Chapter 5에서 기존의 모놀리틱 시스템을 분해하고, 재사용 가능하게 바꾸고, 마이크로서비스로 재구성할 수 있는 방법에 대해서 논의할 것입니다.

 

Optimizing for Replaceability

(대체 가능성의 최적화)

 

만약 여러분이 중간 규모 이상의 조직에서 일하고 있다면, 구석에 있는 크고 끔직한 레거시 시스템에 대해서 알고 있을 가능성이 있습니다. 누구도 만지고 싶지 않은 것. 여러분의 회시가 어떻게 운영되는지에 대해서 필수적인 어떤 것이지만, 이상한Fortran(포트란) 변수로 작성되어 있고, 25년전에 끝난 하드웨어에서만 실행됩니다. 왜 대체되지 않았을까요? 당신은 이유를 알고 있습니다. : 너무 크고 위험한 일이기 때문입니다.

개별 서비스가 작으면, 다 나은 구현으로 대체하거나 심지어 전부 지우는데 들어가는 비용을 관리하는 것이 훨씬 더 쉽습니다. 하루에 얼마나 자주 너무 걱정하지 않고 100줄 이상의 코드를 지우고 있습니까? 크기가 유사한 마이크로서비스가 종종 있기 때문에, 서비스를 완전히 재작성하거나 삭제하기 위한 장벽은 매우 낮습니다.

마이크로서비스 접근 방법을 사용하는 팀들은 필요할 때 서비스를 완전히 다시 작성하고, 더 이상 필요 없을 때 서비스를 죽이는데 익숙합니다 코드베이스가 수 백줄에 불과하면, 사람들이 감정적으로 애착을 갖기 어렵습니다. 그리고 대체하는 비용이 매우 적습니다.

 

What About Service-Oriented Architecture?

 

SOA(Service-Oriented Architecture)는 여러 서비스가 일부 기능 집합을 제공하기 위해 협력하는 설계 접근 방법입니다. 여기서 서비스는 일반적으로 완전히 분리된 운영 체제 프로세스를 의미합니다. 이러한 서비스들 사이의 통신은 프로세스 경계 내에서의 메소드 호출보다는 네트워크 호출을 통해 이루어집니다. SOA는 대규모의 모닐리틱 어플리케이션의 문제점을 해결하기 위한 접근 방법으로 등장했습니다.

SOA는 소프트웨어의 재사용성을 촉진하기 위한 목적으로 하는 접근 방식입니다. 예를 들면, 두개 이상의 최종 사용자 어플리케이션은 모두 동일한 서비스를 사용할 수 있습니다. 서비스의 의미가 너무 많이 변하지 않는 한, 이론적으로 아무도 모르게 하나의 서비스를 다른 서비스로 대체하는 것이 가능하기 때문에 소프트웨어를 유지하거나 재작성하는 것이 더 쉽습니다.

SOA는 매우 현명한 아이디어입니다. 그러나, 많은 노력에도 불구하고, SOA를 잘 수행하는 방법에 대한 좋은 합의가 부족합니다. 개인적인 견해로는 산업계의 상당수는 문제에 대해 충분히 전체적인 관점에서 들여다보지 못했고, 이 영역에서 다양한 벤더들이 내놓은 이야기들에 대한 강력한 대안을 정하지 못했습니다.

SOA의 문앞에 놓인 많은 문제들은 통신 프로토콜(예를 들면, SOAP), 벤더들의 미들웨어, 서비스 세분화에 대한 가이드 부족, 혹은 시스템을 분할하는 장소 선택에 대한 잘못된 가이드와 같은 실제적인 문제들이었습니다. 우리는 책의 나머지 부분에서 각각에 대해서 다룰 것입니다. 냉소적인 사람은 벤더들이 SOA 운동을 더 많은 제품들을 팔기 위한 방법으로 선임(어떤 경우에는 주도)했음을 암시할지도 모릅니다. 그리고 그러한 똑같은 제품들은 종국에 SOA의 목표를 훼손시켰습니다.

 

SOA에 대한 기존 지혜의 대부분은 큰 어떤 것을 작게 나누는 방법을 이해하는데 도움이 되지 않습니다. SOA는 얼마나 큰 것이 너무 큰 것인가를 이야기하는 것이 아닙니다. SOA는 실제 세상에서, 서비스가 과도하게 결합되지 않도록 하는 실질적인 방법에 대해서 충분히 이야기하지 않습니다. 언급되지 않은 것들의 수는 대부분 SOA와 연관된 위험이 발생한 곳입니다.

 

마이크로서비스 접근 방법은 SOA를 더 잘 수행할 수 있는 시스템과 아키텍처에 대한 더 나은 이해를 바탕으로 실제 세상에서 사용함으로 드러났습니다. 따라서 XP Scrum Agile 소프트웨어 개발에 대한 특정 접근법인 것과 같은 방식으로 마이크로서비스가 SOA에 대한 특정한 접근방법으로 생각해야 합니다.

 

Other Decomposition Techniques

(기타 분해 기법)

 

여러분이 그것에 관심을 기울이기 시작할 때, 마이크로서비스 기반 아키텍처의 많은 유익한 점들은 어떻게 문제를 해결하는지 더 많은 선택의 경우를 준다는 granular nature(낱개 특성)과 사실로부터 나옵니다. 하지만, 유사한 분해 기법으로 동일한 유익을 얻을 수 있을까요?

 

Shared Libraries

(공유 라이브러리)

 

사실상 모든 언어에 내장된 매우 표준적인 분해 기법은 여러 라이브러리로 코드베이스를 분해하는 것입니다. 이러한 라이브러리들은 3rd party가 제공하거나 조직 내에서 만들 수 있습니다. 라이브러리들은 팀과 서비스들 간에 기능을 공유할 수 있는 방법을 제공합니다. 예를 들어, 제가 유용한 콜렉션 유틸리티 집합을 만들거나 재사용할 수 있는 통계 라이브러리를 만들 수 있습니다.

 

팀은 이러한 라이브러리들을 기준으로 조직할 수 있고, 라이브러리들은 재사용 할 수 있습니다. 하지만, 몇 가지 단점이 있습니다.

 

첫번째로 진정한 기술 이질성을 잃어버립니다. 라이브러리는 전형적으로 동일한 언어로 되어 있어야 하거나, 최소한 동일한 플랫폼에서 실행되어야 합니다. 두번째, 시스템의 일부를 서로 독립적으로 확장하는 용이성이 감소합니다. 다음으로는 동적으로 링크된 라이브러리를 사용하지 않으면, 전체 프로세스를 재배포하지 않고서 새로운 라이브러리를 배포할 수 없으므로, 변경 사항을 독립적으로 배포할 수 있는 능력이 줄어듭니다. 그리고 아마도 시스템의 탄력성을 보장하기 위해 구조적인 안전 조치들을 세우기 위한 분명한 솔기가 부족할 수도 있습니다.

 

공유 라이브러리들은 그들만의 장소를 가지고 있습니다. 조직 전체에서 재사용하고 싶어서 비즈니스 도메인에 특정되지 않는 일반적인 작업에 대한 코드를 스스로 만든다면, 재사용 가능한 라이브러리에 대한 분명한 후보자가 될 수 있습니다. 비록 그렇다고 할지라도, 여러분은 충분히 주의해야 합니다. 서비스간 통신에 사용되는 공유 코드는 Chapter 4에서 논의할 예정인, 연결되는 지점(point of coupling)이 될 수 있습니다.

 

서비스들은 공통 코드를 재사용하기 위해 3rd party의 라이브러리들을 매우 많이 사용할 수 있고, 그렇게 해야만 할 것입니다. 하지만, 그것들은 우리를 거기에 데려다 주지 않습니다.

 

Modules

(모듈)

 

어떤 언어들은 간단한 라이브러리들을 넘어서는 자체의 모듈식 분해 기법을 제공합니다. 실행 프로세스에 모듈을 배포할 수 있도록 모듈의 라이프사이클 관리를 허용하기 때문에 전체 프로세스를 다운시키지 않고 변경 작업을 수행할 수 있습니다. OSGI(Open Source Gateway Initiative)는 하나의 기술 특화된 모듈식 분해 접근 방식을 요구합니다.

Java 자체는 모듈에 대한 진정한 개념을 가지고 있지 않습니다. 따라서 Java 9가 언어에 추가된 것을 보여줄 때까지 적어도 기다려야만 합니다.

OSGI Eclipse Java IDE에 플러그인을 설치하기 위한 프레임워크로 나타났습니다. 지금은 라이브러리를 통해 자바에 모듈 개념을 새로 장착하는 방법으로 사용되고 있습니다. OSGI의 문제는 언어 자체에서 충분한 지원 없이는 모듈 라이프사이클 관리와 같은 것을 억지로 실행하려고 하는 것입니다. 이러한 결과로 적절한 모듈 분리를 제공하기 위해서 모듈 작성자가 더 많은 일을 해야 합니다. 프로세스 경계 내에서 모듈이 서로 지나치게 결합하는 것은 모든 종류의 문제를 야기하는 함정에 훨씬 더 쉽게 빠집니다. OSGI에 대한 경험에서 산업계 내 동료들과 어울릴 때, 아무리 좋은 팀이라도 OSGI가 보장하는 이익보다 훨씬 더 큰 복잡성의 원인이 되기 쉽다는 것입니다.

 

Erlang은 모듈이 언어 런타임 내에 구워지는 다른 접근 방법을 따릅니다. 이처럼 Erlang은 모듈식 분해에 대해 매우 성숙한 접근 법입니다. Erlang 모듈은 문제없이 중단, 재시작, 업그레이드 될 수 있습니다. Erlang은 주어진 시간 대에 두개 이상의 모듈 버전이 실행되는 것을 지원합니다. 따라서 더 우아한 모듈 업그레이드가 가능합니다.

Erlang 모듈의 능력은 실제로 인상적이지만, 이러한 기능을 갖춘 플랫폼을 사용할 만큼 충분히 운이 좋을지라도, 일반적인 공유 라이브러리와 마찬가지로 동일한 단점이 있습니다.

우리는 새로운 기술들을 사용하는 능력이 엄격히 제안되어 있으며, 독립적으로 확장할 수 있는 방법에 대해서도 제한적이고, 지나치게 커플된(coupled) 통합 기술 (integration techniques) 쪽으로 표류할 수 있고, 구조적인 안전 조치를 위한 이음새가 부족합니다.

 

공유할 만한 가치가 있는 마지막 관찰이 하나 있습니다. 단일 모놀리틱 프로세스 내에 기술적으로, 잘 정리된, 독립적인 모듈을 만드는 것이 가능해야 합니다. 하지만, 거의 이러한 일은 일어나지 않습니다. 모듈은 그 자체로 나머지 코드들과 밀접하게 결합하여 주요 장점 중 하나를 버립니다. 프로세스 경계를 분리하는 것은 이 점에 있어서 청결한 위생을 실행합니다. (혹은 최소한 잘못된 것을 더 하기 어렵게 합니다!)

 

물론, 이것이 프로세스 분리의 주요 요인이라고 제안하지는 않겠지만, 프로세스 경계 내에서 모듈 분리의 약속이 현실 세계에서는 거의 제공되지 않는 다는 점이 흥미롭습니다.

 

따라서, 프로세스 경계 내에서 모듈식 분리는 시스템을 서비스로 분해하는 것 뿐만 아니라 행하고자 하는 어떤 것일 수도 있지만, 그 자체로 모든 것을 해결하는데 도움이 되는 것은 아닙니다. 만약 순수한 Erlang Shop이라면 Erlang의 모듈 구현 품질은 당신에게 매우 먼 길을 가져다 줄 수 있습니다. 하지만, 여러분 중의 많은 사람들이 그 상황에 있지는 않을 거라고 생각합니다. 우리에게 남은 것은, 모듈이 공유 라이브러리와 동이한 유익을 가져다 주는 것으로 보아야 한다는 것입니다.

 

No Silver Bullet

(은 총알은 없다)

 

끝내기 전에, 마이크로서비스는 무료 점심이나 은 총알이 아니고, 황금 망치처럼 나쁜 선택을 해야 한다는 것을 말하고 싶습니다. 마이크로서비스는 분산 시스템과 관련된 모든 복잡성을 가지고 있습니다. 그리고 비록 우리가 분산 시스템을 어떻게 잘 관리하는지에 대해 많이 배운다고 할지라도 (이 책에서 다룰 것입니다.) 여전히 어렵습니다. 만약 여러분이 모놀리틱 시스템 관점에서 출발한다면, 배포, 테스트, 모니터링을 훨씬 더 잘 처리하여 지금까지 우리가 살펴본 장점들을 풀어서 활용해야 합니다. 또한,시스템을 어떻게 확장하는지, 복원력이 있는지 어떻게 확인하는지에 대해 다르게 생각할 필요가 있습니다. 분산 트랜잭션이나 CAP 이론이 두통을 선사해도 놀라지 마십시오.

 

모든 회사, 조직, 시스템은 다릅니다. 마이크로서비스가 여러분에게 적합한지 아닌지, 마이크로서비스를 얼마나 적극적으로 채택할 수 있는지에 여러 가지 요소들이 작용할 것입니다. 이 책의 각 장들을 통해서 꾸준한 경로를 계획하는데 도움이 되는 잠재적 함정을 강조하는 가이드를 제공하려고 노력할 것입니다.

 

Summary

 

바라건데, 이제부터 여러분은 마이크로서비스가 무엇인지, 다른 구성 기술들과 다른 점이 무엇인지, 주요 장점 중 일부가 무엇인지 알고 있습니다. 다음 각 장에서는 어떻게 이러한 장점들을 달성하는지, 일반적인 함정을 어떻게 피하는지에 대해서 더 자세히 다룰 것입니다.

 

다루어야 할 많은 주제들이 있지만, 어딘가에서부터 시작해야 합니다. 마이크로서비스가 소개하는 주요 과제 중 하나는 우리 시스템의 진화를 가이드하는 사람들 : 아키텍트들의 역할에 변화가 있다는 것입니다. 다음에 우리는 이 새로운 아키텍처를 최대한 활용할 수 있도록 이 역할에 대한 몇 가지 다른 접근 방법을 살펴볼 것입니다.

 


받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/812

Event‑Driven Architecture

많은 어플리케이션에서 솔루션은 Event Driven Architecture를 사용하는 것이다. Event Driven Architecture에서는 비즈니스 엔터티를 업데이트하는 경우와 같은 주목할 만한 어떤일이 일어날 때, 마이크로서비스가 이벤트를 발행한다. 다른 마이크로서비스는 이러한 이벤트 구독을 신청한다. 마이크로 서비스가 이벤트를 받았을 때(구독 신청한 이벤트를 수신했을 때), 자신의 비즈니스 엔터티를 업데이트할 수 있게 되므로 더 많은 이벤트를 발행할 수 있게 될 것이다.

여러 서비스에 걸쳐 있는 비즈니스 트랜잭션을 구현할 때 이벤트를 사용할 수 있다. 하나의 트랜잭션은 여러 단계로 이루어져 있다. 각 단계는 비즈니스 엔터티를 업데이트 하고, 다음 단계를 Trigger하는(작동시키는) 이벤트를 발행하는 마이크로서비스로 이루어져 있다. 다음의 순차적인 다이어그램은 주문을 생성할 때, 이용 가능한 신용 한도를 체크하기 위하여 어떻게 Event Driven 접근법이 사용되는지를 보여준다. 마이크로서비스는 Message Broker를 통해 이벤트를 교환한다.

  1. Order Service는 NEW 상태의 주문을 생성하고, Order Created 이벤트를 발행한다.

사용자 삽입 이미지

  2. Customer Service는 Order Created 이벤트를 구독하여 주문에 대한 신용 한도를 예약하고, Credit Reserved 이벤트를 발행한다.

사용자 삽입 이미지

  3. Order Service는 Credit Reserved 이벤트를 구독하여, 주문 상태를 OPEN으로 변경한다.

사용자 삽입 이미지


더 복잡한 시나리오에서는 고객의 신용한도를 체크하는 동시에 재고를 예약하는 것과 같은 추가적인 단계가 포함될 수 있다.

(a) 각 서비스가 데이터베이스를 원자적으로 업데이트하고, 이벤트를 발행한다. -- 나중에 다시 이야기하기로 하자.
(b) Message Broker는 이벤트가 최소한 한번은 전달되도록 보장하고, 그런 다음 여러 서비스에 걸쳐져 있는 비즈니스 트랜잭션을 구현할 수 있다.

이것은 ACID 트랜잭션이 아니라는 것에 주목하는 것이 중요하다. 최종 데이터 일관성과 같은 훨씬 더 약한 보장을 제공한다. (ACID에서와는 다르게 최종적으로 데이터가 일관성을 유지하기만 하면 된다는 의미.) 이러한 트랜잭션 모델을 BASE 모델이라고도 한다.

여러 마이크로서비스가 소유한 데이터를 pre-join(사전 조인)하는 실체화된 뷰를 유지 관리하기 위해 이벤트를 사용할 수도 있다. 뷰를 유지 관리하는 서비스는 관련있는 이벤트를 구독하여 뷰를 업데이트한다. 예를 들어, Customer Orders View를 유지 관리하는 Customer Order View Updater Service는 Customer Service와 Order Service에서 발행한 이벤트를 구독한다.

사용자 삽입 이미지


Customer Order View Updater Service가 Customer나 Order 이벤트를 받을 때, Customer Order View Datastore를 업데이트 한다. MongoDB와 같은 문서 기반 데이터베이스를 사용하여 Customer Order View를 구현하고, 각 Customer별로 하나의 문서로 저장할 수 있다. Customer Order View Query Service는 Customer Order View Datastore에 질의하여 고객과 고객의 최근 주문 내역을 처리한다.

Event-Driven Architecture에는 여러 가지 이점과 단점이 있다. Event-Driven Architecture는 여러 서비스에 걸쳐 있는 트랜잭션을 구현할 수 있고, 최종적인 데이터 일관성을 제공한다. 또다른 이점은 어플리케이션이 실체화된 뷰를 유지 관리할 수 있다는 것이다. 한가지 단점은 ACID 트랜잭션을 사용할 때보다 프로그래밍 모델이 훨씬 복잡하다는 것이다. 종종 어플리케이션 수준의 오류를 복구하기 위해서 보상 트랜잭션을 구현해야만 한다. 예를 들면, 신용한도 확인이 실패할 경우에는 주문을 취소해야만 한다. 또한 어플리케이션은 일관성이 없는 데이터를 처리해야 한다. 운영중인 트랜잭션으로 인해 생성된 변경 사항들을 볼 수 있기 때문이다. 어플리케이션이 아직 업데이트 되지 않은 실체화된 뷰에서 데이터를 조회했을 경우, 데이터 불일치가 발생할 수 있다. 또다른 단점은 이벤트를 구독하는 쪽에서 중복된 이벤트에 대해 감지하고 무시해야 한다는 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/773

이것은 마이크로서비스로 어플리케이션을 작성하는 시리즈 중 다섯번째 Article이다. 첫번째 Article에서는 마이크로서비스 아키텍처 패턴을 소개하고, 마이크로서비스를 사용하는 것에 대한 장단점에 대해서 논의했다. 시리즈의 두번째와 세번째 Article에서는 마이크로서비스 내에서 다양한 측면의 통신에 대해서 설명했다. 네번째 Article에서는 서비스 검색과 밀접하게 관련된 문제에 대해서 살펴보았다. 이번 Article에서는 기어를 변속하여 마이크로서비스 아키텍처에서 떠오르는 Distributed Data Management(분산 데이터 관리)에 대해서 살펴보자.

Microservices and the Problem of Distributed Data Management
(마이크로서비스와 분산 데이터 관리 문제)

Monolithic 어플리케이션은 일반적으로 단일 관계형 데이터베이스(Single Relational Database)를 가지고 있다. 관계형 데이터베이스를 사용할 때의 주요 이점은 어플리케이션이 몇가지 중요한 점들을 보장하는 ACID 트랜잭션을 사용할 수 있다는 것이다.

  - Atomicity(원자성) : 변경 사항들이 원자적으로 적용된다. (트랜잭션과 관련된 작업들이 부분적으로만 실행되고 중단되지 않는 것을 보장하는 능력. 즉, 중간 단계까지만 실행되고 나머지는 실패하는 일이 없도록 하는 것.)
  - Consistency(일관성) : 데이터베이스의 상태는 항상 일관성이 있다. (트랜잭션을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스를 유지하는 능력.)
  - Isolation(고립성) : 트랜잭션이 동시에 실행되는 경우라도, 순차적으로 실행된다. (트랜잭션 수행 시, 동시에 실행되더라도 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 능력.)
  - Durability(지속성) : 한번 커밋된 트랜잭션은 실행취소 되지 않는다. (성공적으로 수행된 트랜잭션은 영원히 반영되어야 함.)

결과적으로 어플리케이션은 트랜잭션을 간단히 시작하고, 여러 행을 변경(삽입, 업데이트, 삭제)하고, 트랜잭션을 커밋할 수 있다.

관계형 데이터베이스를 사용하는 또 다른 큰 이점은 풍부하고, 선언적이며, 표준화된 Query Language인 SQL을 제공한다는 것이다. 여러 테이블에서 데이터를 결합하는 쿼리를 쉽게 작성할 수 있다. RDBMS Query Planner는 쿼리를 실행하기 위해 가장 적합한 방법을 결정한다. 어떻게 데이터베이스에 접근하는 지와 같은 저수준(low-level)의 세부 사항에 대해서 걱정할 필요 없다. 그리고 어플리케이션의 모든 데이터(어플리케이션이 필요로 하는 모든 데이터)가 하나의 데이터베이스에 있기 때문에 질의하기도 쉽다.

안타깝게도, 마이크로서비스 아키텍처로 전환하게 된다면 Data Access가 훨씬 더 복잡해진다. 그것은 각 마이크로서비스가 소유한 데이터가 개별 마이크로서비스 전용이고, API를 통해서만 접근할 수 있기 때문이다. 데이터를 캡슐화하는 것은 마이크로서비스가 서로 느슨하게 결합되고, 서로 독립적으로 진화하는 것을 보장한다. 만약 여러 서비스가 동일한 데이터에 접근한다면, 스키마 업데이트에는 시간이 오래 걸리고, 모든 서비스에 업데이트하기까지 조정이 필요하다.

설상가상으로, 다른 마이크로서비스는 종종 다른 종류의 데이터베이스를 사용한다. 최신 어플리케이션은 다양한 종류의 데이터를 저장 및 처리하고, 그에 따라 관계형 데이터베이스가 언제나 최고의 선택은 아니다. 어떤 Use Case에서는 특정 NoSQL 데이터베이스가 더 편리한 데이터 모델과 더 좋은 성능, 확장성을 가지고 있을 수 있다. 예를 들면, 텍스트를 저장하고, 질의하는 서비스는 ElasticSearch와 같은 텍스트 검색 엔진을 사용하는 것이 의미가 있다. 이와 유사하게, Social Graph 데이터를 저장하는 서비스는 Neo4j와 같은 Graph Database를 사용해야 한다. 결과적으로, 마이크로서비스 기반 어플리케이션은 종종 SQL과 NoSQL이 혼합된 형태, 소위 Polyglot Persistence(데이터를 저장할 때, 여러 가지 데이터 저장 기술을 사용하여 최고의 해결책을 찾는 것) 접근법을 사용한다.

데이터 스토리지에 대한 파티션된 Polyglot Persistence Architecture는 느슨하게 결합된 서비스와 더 좋은 성능, 확장성을 포함하여 많은 이점이 있다. 그러나, 일부 분산 데이터 관리 문제가 발생한다.

첫번째 문제는 여러 서비스간의 데이터 일관성을 유지하기 위해 비즈니스 트랜잭션을 어떻게 구현하는가이다. 왜 이것이 문제인지 알아보려면, 온라인 B2B Store 예제를 살펴보자. Customer Service는 신용 한도를 포함하여 고객 정보를 유지 관리한다. Order Service는 주문을 관리하고, 신규 주문이 고객의 신용 한도를 초과하지는 않는지를 검증해야 한다. Monolithic Application에서는 Order Service가 ACID 트랜잭션을 사용하여 간단히 사용 가능한 신용한도를 확인하고 주문을 생성할 수 있다.

반대로, 다음 다이어그램에서 보는 것처럼, 마이크로서비스 아키텍처에서는 ORDER와 CUSTOMER 테이블이 각각의 서비스 전용이다.

사용자 삽입 이미지


Order Service는 CUSTOMER 테이블에 직접적으로 접근이 불가능하다. Customer Service가 제공하는 API만 사용할 수 있다. Order Service는 잠재적으로 two-phase commit(2PC)라고 알려진 분산 트랜잭션을 사용해야만 한다. 그러나 2PC는 일반적으로 최근 어플리케이션에서 실행가능한 옵션이 아니다. CAP Theorem에서는 가용성과 ACID-Style의 일관성 중에서 선택할 필요가 있다. 그리고 가용성이 일반적으로 더 나은 선택이다. 더우기, 대부분의 NoSQL 데이터베이스와 같은 많은 현대 기술은 2PC를 지원하지 않는다. 서비스와 데이터베이스 간에 데이터 일관성을 유지하는 것이 필수적이기 때문에, 다른 솔루션이 필요하다.

두번째 문제는 여러 서비스에서 데이터를 조회하는 쿼리를 어떻게 구현하느냐이다. 예를 들면, 어플리케이션에서 고객과 고객의 최근 주문 내역을 표시하는 경우를 생각해 보자. Order Service는 고객의 주문 내역을 조회하는 API를 제공하고, 어플리케이션 측면의 Join을 사용하여 데이터를 조회할 수 있다. 어플리케이션은 Customer Service에서 고객을 조회하고, Order Service에서 고객의 주문 내역을 조회할 수 있다. 그러나, Order Service가 단지 Primary Key로 주문 내역을 조회할 수 있다고 가정해 보자.(아마도 단지 Primary Key기반 조회만 지원하는 NoSQL데이터베이스를 사용한다고 가정해 보자.) 이와 같은 상황에서는, 필요한 데이터를 조회하는 확실한 방법이 없다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/772