소비자 주도 계약(consumer driven contracts)은 서비스에 대한 소비자의 기대 사항을 정의한다. 소비자의 기대 사항을 테스트할 수 있도록 코드로 표현한다. 해당 테스트는 생산자가 수행한다. 소비자 주도 계약이 완벽하게 수행되도록 생산자의 지속적 통합 서버 빌드의 일부분으로 수행되야 한다.



특히 테스트의 독립성을 보장해야 한다. 


마이크로 서비스 또는 레거시 시스템을 시뮬레이션하는 스텁(stub)이 테스트 목적에 유용하다.




실제 카카오 스토리에서 Functional 테스트를 진행할 때 바로 소비자/생산자를 독립시켜 테스트를 하도록 배웠고 docker를 이용한 병렬화 테스팅을 진행했다. Functional 테스팅의 정말 나에게는 정말 도움이 되었다. (멀린 땡큐!)


https://www.slideshare.net/knight1128/hancom-mds-conference-kakao-devops-practice-devops





간이 지나고 보고 이 Functional 테스트가 바로 소비자 주도 계약 테스트 중의 하나였다고 생각한다. (용어를 뭉뜨그리고 해도 개념은 동일했던 것 같다.)





개념에 대한 자세한 내용은 다음을 참조한다.


https://martinfowler.com/articles/consumerDrivenContracts.html



Posted by '김용환'
,


모노리식이든 마이크로 서비스이든 요구사항에 따라 계속 아키텍처 변화는 필요하다.


빅 데이터를 다루는 모노리식 아키텍처(SNS, Talk)에서는 요구에 따른 Nosql로 인한 아키텍처 변화가 상당히 크다..


상황에 따라 DB의 일부를 cassandra 또는 Hbase로 사용하기도 하고. redis 대신 memcached를 적절히 사용해야 하는 이슈들이 늘 산재되어 있다. 


migration 및 아키텍처 변화에 가장 큰 힘은 테스트 코드이다.




반면, 레거시 시스템 또는 마이크로 서비스에서는 점진적으로 서비스 아키텍처로 코드를 분리해 나가는 디자인 패턴을 strangler 패턴이라 한다. 


분위기 상 마이크로 서비스에서 얘기하는 내용으로서 마틴 파울러가 내용을 쓰면서 유명해 졌다..


https://www.martinfowler.com/bliki/StranglerApplication.html



(덧 붙이자면.. 이미 우리의 많은 선배들은 리팩토링, 구조 개선이라는 이름으로 진행해왔었다..


strangler 패턴은 마이크로 서비스의 신조어 단어이다.)


Posted by '김용환'
,

http://isa-principles.org 독립적 시스템 아키텍처에 대한 설명이 있어서 번역해둔다. 




1. 시스템은 인터페이스(interface)를 제공하는 모듈(module)로 분할되야 한다. 해당 인터페이스를 통해서만 모듈에 접근할 수 있어야 한다. 따라서 모듈은 데이터베이스의 데이터 모델과 같은 다른 모듈의 구현 세부 사항에 직접 의존하지 않을 수도 있다.



2. 모듈은 독립성을 최대화하기 위해 별도의 프로세스, 컨테이너 또는 가상 시스템이 되야 한다.



3. 시스템은 두 가지 명확하게 분리된 레벨의 아키텍처를 결정해야 한다.


 - 매크로(macro) 아키텍처는 모든 모듈에 관련된 결정으로 구성된다. 추가될 모든 원칙은 매크로 아키텍처의 일부이다.


- 마이크로(micro) 아키텍처는 개별 모듈마다 다르게 정해질 수 있는 결정을 포함한다.



4. 통합(integration)을 선택하는 것은 제한되야 하고 시스템에서 표준화되야 한다. 통합은 동기식 및 비동기식 통신 또는 프론트 엔드에서 수행될 수 있다.



5. 통신은 REST 또는 메시징과 같은 작은 수의 프로토콜로 제한되야 한다. 인증과 같은 메타 데이터도 표준화되야 한다.




6. 각 모듈마다 지속적인 배포 파이프 라인이 존재해야 한다. 테스트는 모듈의 테스트가 독립적이야 하므로 지속적인 배포 파이프 라인의 일부이다.




7. 운영은 표준화되야 한다. 운영에는 설정, 배포, 로그 분석, 추적, 모니터링, 경보가 포함된다. 모듈에 매우 상세한 요구 사항이 있을 때는 표준에서 예외로 처리할 수 있다.




8. 운영, 통합, 통신 표준은 인터페이스 레벨에서 정의되야 한다. 예를 들어 프로토콜은 REST로 표준화될 수 있고 데이터 구조도 표준화될 수 있다. 그러나 각 모듈에서 다른 REST 라이브러리를 자유롭게 사용하는 것을 추천한다.




9. 모듈은 복원력이 있어야 한다. 다른 모듈을 사용할 수 없거나 통신 문제가 발생하면 오류가 발생하지 않을 것이다. 그들은 데이터나 상태를 잃지 않고 종료할 수 있어야 한다. 모듈을 실패하지 않고도 다른 환경(서버, 네트워크, 설정 등)으로 이동할 수 있어야 한다.





원문은 다음과 같다. 


  1. The system must be divided into modules that provide interfaces. Access to other modules is only possible through these interfaces. Therefore modules must not directly depend on implementation details of other modules, e.g. the internal data representation in a database. The rest of the principles define how modules might be implemented, and how ISA differs from other modularization approaches.

  2. Modules must be implemented as separate processes, containers, or virtual machines to maximize independence.

  3. The system must have two clearly separated levels of architectural decisions:
    • The Macro Architecture comprises decisions that cover all modules. All further principles are part of the Macro Architecture.
    • The Micro Architecture considers decisions which may be taken individually for each module.
  4. The choice of integration options must be limited and standardized for the system. The integration might be done with synchronous or asynchronous communication, and/or on the UI level.

  5. Communication must use a limited set of protocols like RESTful HTTP or messaging. Also metadata, e.g. for authorization, must be standardized. It might make sense to use just one protocol for each integration option.

  6. Each module must have its own independent Continuous Delivery pipeline. Tests are part of the Continuous Delivery pipeline so the modules must be tested independently.

  7. Operations should be standardized. This includes configuration, deployment, log analysis, tracing, monitoring, and alerting. There might be exceptions from the standard if a module has very specific requirements.

  8. Standards for operations, integration, or communication should be enforced on the interface level. For example, the communication protocol and data structures could be standardized to a specific JSON payload format exchanged using HTTP, but every module should be free to use a different REST library/implementation.

  9. Modules must be resilient. They must compensate unavailable modules or communication problems. They must be able to cope with unexpected shutdowns without losing data or state. It must be possible to move them to other runtime environments (hosts, networks, config etc).



첫 번째 ISA 원칙은 시스템이 모듈을 기반으로 개발되야 한다고 말한다. 이는 일반적인 내용이다.

두 번째 원칙은 매크로 아키텍처와 마이크로 아키텍처의 두 개의 아키텍처 레벨을 정의한다.

배포 모노리스에서 대부분의 결정은 매크로 아키텍처 레벨에서 이루어진다. 예를 들어 배포 모노리스에서는 하나의 프로그래밍 언어로 작성되기에 프로그래밍 언어는 매크로 아키텍처 레벨에 대한 결정이어야 한다. 프레임워크와 대부분의 다른 기술에서도 마찬가지이다. 실제로 마이크로 아키텍처에서 더 많은 결정을 내리기 위해 의미 있는 기회를 결정하려면 각 모듈은 원칙적으로 세 번째 원칙 상태를 기반으로 별도의 컨테이너에 구현되야 한다.

따라서 ISA에서는 마이크로 서비스가 컨테이너에서 동작하는 이유는 배포 모노리스에서 달성할 수 없는 기술적 자유이다. 따라서 마이크로 서비스는 아키텍처에 독립성과 낮은 결합도를 제공한다. 각 마이크로 서비스가 WAR이고 특정 애플리케이션 서버에서 함께 실행되는 접근 방식은 이 원칙에 맞지 않는다. 사실 자유로운 기술 선택과 견고성에 관한 절충안을 찾기가 매우 높기 때문에 실제로 해당 접근 방식은 일반적으로 별로 의미가 없다. 낮은 결합도가 중요하기 때문에 ISA와 마이크로 서비스는 실제로 모듈화에 근본적인 개선을 제공한다.

ISA의 목표는 최소한의 매크로 아키텍처를 결정하는 것이지만 어떤 결정은 여전히 매크로 수준에서 이루어져야 한다. 이는 나머지 원칙들을 설명하는 것이기 때문이다. 시작할 때 네 번째 원칙은 통합과 통신 방식을 표준화해야 한다고 명시한다.

통합과 통신에 특정 기술에 사용하기로 결정한다면 모든 모듈에 영향을 미치기에 매크로 아키텍처 레벨에서 수행해야 한다. 따라서 마이크로 서비스 시스템에서 매우 중요한 결정이다. 일반적인 통합 접근 방식과 통신 기술이 없는 시스템에 대해 시스템이라 말하기 어렵고 실제로 서로 통신할 수 없는 일부 서비스만 고려해야 한다.

다섯번째 원칙은 추적과 인증을 위한 메타 데이터가 표준화되야 한다고 명시한다. 해당 메타 데이터는 마이크로 서비스 간에 전송되야 하므로 매크로 아키텍처의 일부여야 한다.

여섯번째 원칙(독립 배포 파이프 라인)은 독립 배포 개념이 있다.

일곱번째 원칙은 마이크로 서비스의 운영이 표준화되야 한다고 말한다. 모든 운영 작업을 표준화 해야 한다는 의미가 아니다. 별도의 운영 부서에서 다수의 마이크로 서비스를 처리하는 유일한 방법은 표준화이다. 그러나 "우리가 따로 빌드하고 운영한다"라는 신념을 가진 조직이라면 마이크로 서비스 운영에 대한 표준은 필요치 않다.

실제로 표준화된 운영 방식은 모든 마이크로 서비스에 적합하지 않을 수 있다. 이 경우 팀은 자체 운영 기술을 제안해야 한다. 표준은 거의 의미가 없다.

여덟번째 원칙은 표준이 인터페이스 레벨에서만 정의되어야 한다고 명시한다. 일반적으로 사용되는 모든 프로그래밍 언어에서는 인터페이스와 클라이언트 라이브러리를 제공한다.

아홉번째 원칙은 탄력성을 설명한다.

Posted by '김용환'
,