Exception Handling
(예외 처리)

원칙과(principle) 실행 절차(사례:practice)는 어떻게 시스템을 구축해야 하는지 가이드합니다.
그러나 시스템이 이것을 벗어날 경우 무슨 일이 발생할까요?
때때로, 규칙에 예외가 되는 결정을 하게 되는 경우도 있습니다.

이러한 경우, 나중에 참조할 수 있도록 로그로 그러한 결정을 캡쳐할 가치가 있을 수도 있습니다.
충분한 예외가 발견된다면, 결국 세계에 대한 새로운 이해를 반영하기 위하여 원칙이나 실행절차를 변경해야 할 수도 있습니다.

예를 들면, 데이터 스토리지로 MySQL을 항상 사용할 것이라는 사례가 있을 수 있습니다.

그러나 "카산드라를 사용하는 경우에, 볼륨이 크게 증가하지 않는다면, 대부분의 스토리지 요구사항에 MySQL을 사용하십시오."라고 말하지만, 실행 절차를 변경하여 확장성이 뛰어난 스토리지를 위해서 카산드라(Cassandra)를 사용해야만 하는 강제적인 이유가 있을 수 있습니다.

그러나, 모든 조직이 다르다는 것을 되풀이할 가치가 있습니다.
나는 개발팀이 높은 신뢰와 자율성을 가지고 원칙이 가벼운 (분명한 예외 처리의 필요성이 제거되지 않으면, 크게 감소합니다.) 몇 개의 회사와 작업을 한 적이 있습니다.

개발자들이 덜 자유로운 더 구조화된 조직에서는 예외를 추적하는 것이 사람들이 직면한 과제들을 적절하에 반영하기 위해서 규칙들이 필수적일 수 있습니다.

언급된 이 모든 것들과 함께, 나는 가능한 훨씬 자유롭게 손에 있는 문제를 해결하는, 팀의 자율성을 최적화하기 위한 방법으로 마이크로서비스의 팬입니다.

만약 개발자들이 수행하는 방법에 많은 제약을 가하는 조직에서 일을 한다면, 마이크로서비스가 여러분에게 도움이 되지 않을 수 있습니다.
받은 트랙백이 없고, 댓글이 없습니다.

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

Technical Debt
(기술적인 부채)

종종 기술 비전에 대한 레터(letter : 편지)를 통해 따라갈 수 없는 상황에 놓이게 됩니다.
어떤 긴급한 기능을 얻기 위해서 몇 가지 모서리를 자르는 선택을 해야 할 때도 자주 있습니다.
이것은 우리가 알아야 하는 하나 이상의 trade-off(장단점) 입니다.
우리의 기술적 비전은 이유가 있습니다.

만약 우리가 이러한 이유에서 빗나가게 되면, 단기적으로는 이익을 얻을 수 있지만, 장기적으로는 비용이 들게 됩니다.

이러한 trade-off(장단점)을 이해하는데 도움이 되는 개념이 바로 기술적 부채(technical debt)입니다.
기술적인 부채가 생기게 되면, 실제 세상에서의 부채와 마찬가지로 지속적인 비용이 들게 됩니다.
그리고 우리가 지불하고자 하는 어떤 것이 있게 됩니다.

때때로 기술적 부채는 지름길을 취해서 야기되는 어떤 것만 있는 것은 아닙니다.
만약 우리 시스템이 바뀌지만, 시스템의 모든 것이 일치하지 않는다면 무슨 일이 발생할까요?
이러한 상황에서도, 기술적 부채의 새로운 소스가 만들어지게 됩니다.

아키텍트의 임무는 더 큰 그림을 보고 이 균형을 이해하는 것입니다.
부채의 수준에 대한 뷰를 가지고, 어디에 참여하게 되는지가 중요합니다.

조직에 따라 적절한 가이드를 제공할 수는 있지만, 팀 자체적으로 어떻게 채무를 추적하고 지불하는지 결정하게 해야 합니다.

다른 조직의 경우에는 정기적으로 검토되는 채무 기록을 유지하는 것처럼, 더 구조화되어야할 수도 있습니다.
받은 트랙백이 없고, 댓글이 없습니다.

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

Governance Through Code
(코드를 통한 거버넌스)

함께 모여서 어떻게 일을 할지에 대해서 동의하는 것은 좋은 아이디어입니다.

그러나 사람들이 이러한 가이드라인을 따르도록 하는데 시간을 낭비하는 것은 각 서비스에서 기대하는 모든 이러한 표준들을 구현하는 것이 개발자들에게는 부담이 되므로 더 재미가 없습니다.

나는 올바른 일을 더 쉽게 하도록 하는 위대한 신봉자입니다.

내가 여기서 잘 보여주는 2가지 기법은 예제를 사용하고, 서비스 템플릿을 제공하는 것입니다.

Exemplars
(예제)

문서화를 하는 것은 좋고, 유용합니다.
그 가치를 분명하게 보았고, 결국 나는 이 책을 쓰게 되었습니다.
그러나 개발자는 코드, 즉 실행할 수 있고, 탐구할 수 있는 코드를 좋아합니다.

만약 여러분이 장려하고 싶은 표준이나 모범 사례(Best Practice)를 가지고 있다면, 사람들에게 가리킬 수 있는 예제를 갖고 있는 것이 유용합니다.

아이디어는 사람들이 시스템의 더 좋은 부분의 일부를 모방하는 것만으로는 잘못될 수 없다는 것입니다.

이상적으로는, 방금 구현된 격리된 서비스(isolated service)가 아니라 완벽한 예제가 되도록 올바르게 동작하는 실제 서비스(real-world service)를 제공해야만 합니다.
예제가 실제로 사용되고 있음을 보장함으로써, 모든 원칙들이 실제로 의미가 있음을 보장할 수 있습니다.

Tailored Service Template
(맞춤형 서비스 템플릿)

여러분이 매우 적은 업무로 가지고 있는 대부분의 가이드라인을  따르는 것이 모든 개발자가 정말로 쉽게 일하게 할 수 있는 것이라면, 대단하지 않을까요?

만약, 특별히, 개발자들이 각 서비스에서 필요로 하는 핵심 속성들을 구현할 수 있는 대부분의 코드를 가지고 있다면 어떨까요?

Dropwizard와 Karyon은 2개의 JVM 기반 마이크로 컨테이너 오픈소스입니다.

그것들은 Health-Checking, HTTP 제공, 메트릭 노출과 같은 기능을 제공하는 라이브러리 세트를 함께 사용하여 유사한 방식으로 동작합니다.

따라서, 특별히, 명령줄(command line)에서 실행될 수 있는 임베디드 서블릿 컨테이너(embeded servlet container)를 가진 완전한 서비스를 제공할 수 있습니다.

이것은 시작하기 좋은 방법이지만, 거기서 멈추는 이유는 무엇일까요?

하는 김에(while we are at it), 왜 Dropwizard나 Karyon과 같은 어떤 것을 사용하지 않을까요?
그리고 왜 맥락(context)에 적합해지도록 더 많은 기능을 추가하지 않을까요?

예를 들면, Circuit breaker를 필수적으로 사용하도록 할 수 있습니다.
이 경우, Hystrix와 같은 Circuit Breaker 라이브러리를 통합할 수 있습니다.

또는 모든 메트릭을 중앙의 Graphite 서버로 보내야 할 수도 있기 때문에 Dropwizard 메트릭과 같은 오픈소스 라이브러리를 가져와서 설정하여 알려진 위치로 응답 시간과 오류율(error rate)을 자동으로 Push할 수 있습니다.

자신만의 개발 사례 세트에 대한 그러한 맞춤형 서비스 템플릿으로 인해 팀이 더 빠르게 시작할 수 있고, 또한 개발자들이 서비스가 안 좋게 동작하도록 하는 방법에서 떠나도록 할 수 있습니다.

물론, 만약 다른 여러 가지 기술 스택을 포용한다면, 각각의 경우에 맞는 서비스 템플릿이 필요합니다.
이것은 미묘하게도 여러분의 팀에서 언어 선택 제약 사항이 될지도 모릅니다.

만약, 사내(in-house) 서비스 템플릿이 단지 자바만 지원한다면, 사람들은 대체 스택을 선택하면 많은 일을 해야만 하는 경우, 대체 스택을 선택하는 것에 대해서 낙심하게 될지도 모릅니다.

예를 들어, Netflix는 시스템의 한 부분의 작동 중지로 모든 것이 다운되지 않을 수 있도록 보장하기 위해서 내결함성(fault tolerance)와 같은 측면에 특히 관심을 가지고 있습니다.

이것을 처리하기 위해서, JVM 클라이언트 라이브러리가 있는 팀에 서비스가 잘 동작하도록 유지하는데 필요한 도구를 제공하기 위해 엄청난 노력을 하고 있습니다.

새로운 기술 스택을 소개받은 사람은 누구나 이 모든 노력을 재현해야함을 의미합니다.
Netflix의 주요 관심사는 중복된 노력을 덜하는 것보다 잘못되는 것이 너무 쉽다는 사실에 있습니다.

새롭게 구현된 내결함성(fault tolerance) 오류를 가진 서비스의 위험은 그 서비스가 시스템에 더 많은 영향을 줄 수 있을 때 높습니다.

Netflix는 적절한 라이브러리를 사용하는 JVM과 로컬로 통신하는 사이드카 서비스(sidecar service : 효력을 정지하는 서비스)를 사용하여 이 위험을 완화합니다.

여러분은 서비스 템플릿의 생성이 코드를 통해 일을 해야만 하는 방법을 지시하는 중앙 도구나 아키텍처 팀의 일이 되지 않도록 주의를 기울여야 합니다.

여러분이 사용하는 사례를 정의하는 것은 집합적인 활동이어야 합니다. 따라서, 이상적으로는 여러분의 팀이 이 템플릿을 업데이트하는 책임을 져야 합니다. (내부 오픈소스 접근 방식이 여기에서는 적합함).

또한, 그들이 신뢰하는 필수적인 프레임워크로 인해 많은 팀의 사기와 생산성이 파괴된 것을 보았습니다.

코드 재사용성을 향상시키기 위해서, 압도적인 괴물이 될 때까지 점점 더 많은 작업이 중앙집중화된 프레임워크에 위치하게 됩니다.

만약 여러분이 맞춤형 서비스 템플릿을 사용하기로 결정한다면, 그 일이 무엇인지에 대해서 매우 주의깊게 생각하십시오.

이상적으로, 그 템플릿의 사용은 순전히 선택적이어야 하지만, 만약 여러분이 그것의 취사 선택에서 더 강력하게 되는 경우, 개발자들을 위한 사용 용이성이 주요한 안내력(guiding force)이 되어야 한다는 것을 이해해야만 합니다.

또한, 코드 공유의 위험에 대해서 알고 있어야만 합니다.

재사용 가능한 코드를 만들기 위한 우리의 욕망으로 인해 서비스간 커플링 소스(밀접하게 엮여 있는 소스)를 만들 수 있습니다.

최소한 내가 말했던 조직 중 하나는 실제로 각 서비스에 수동으로 서비스 템플릿 코드를 복사하는 것에 대해 걱정하고 있습니다.

핵심 서비스 템플릿으로 업그레이드하는 것이 시스템 전반에 걸쳐 적용되는데 더 오래 걸리지만, 커플링 위험보다 덜 중요하다는 것을 의미합니다.

내가 말한 다른 팀들은 지나치게 결합된 시스템에서 DRY(스스로 반복하지 않음 : don't repeat yourself) 결과에 대한 경향이 되지 않도록 매우 부지런해야함에도 불구하고, 서비스 템플릿을 공유 바이너리 종속성(shared binary dependency)처럼 간단하게 취급합니다.
(DRY 결과로 인한 경향이 지나치게 결합된 시스템이 되지 않도록 매우 부지런해야함에도 불구하고, 단순히 서비스 템플릿을 공유 바이너리 종속성으로 취급합니다.)

이것은 미묘한 주제이므로, 4장에서 더 자세히 살펴보겠습니다.
받은 트랙백이 없고, 댓글이 없습니다.

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

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