Medium

7가지 아키텍처 디자인 패턴 - 면접전에 알았으면 좋았을 것들

ppthejake 2023. 11. 6. 17:29

해당 포스트는 미디엄의 아티클을 번역한 내용이다.

 

이 블로그에 방문하셨다면 모던 아키텍처 디자인 패턴이 무엇인지 알고 있을거라 생각됩니다. 그러나 경험이 부족한 몇몇 친구들을 위해 아키텍처 디자인 패턴을 어플리케이션을 확장할 수 있도록 설계하는 방식이라고 생각하면 됩니다.

아키텍처 디자인 패턴은 간단히 말해 High Level Design 을 위한 디자인 패턴입니다.

 

현대의 문제에는 현대적인 해결책이 필요합니다. 어플리케이션이 기업 혹은 인터넷 수준의 사용자를 대상으로 하려면 확장성, 가용성, 보안성, 복원력을 갖춰야 합니다. 의심할 여지 없이 모든 메이저 리그 기업들은 이러한 어려움을 파악하고 해결할 수 있는 개발자를 찾고 있습니다.

 

이제 문제는 개발자가 이러한 문제를 어떻게 해결할 수 있을까요? 한 가지 방법은 좋은 아키텍처 디자인 패턴을 따르는 것입니다. 여기 7가지 패턴을 소개합니다.

Circuit Breaker Pattern

마이클 니가드(Michael Nygard)의 책 "Release It!" 은 Circuit Breaker 패턴을 인기있게 만들었는데, 이 패턴은 실패할 가능성이 높은 작업을 계속 시도하지 않고, 문제가 수정될 때를 기다리지 않거나 장애의 지속 시간을 판별하는 동안 CPU 사이클을 소모하지 않도록 어플리케이션을 보호할 수 있는 패턴입니다.

 

Circuit Breaker 패턴은 또한 어플리케이션이 문제가 해결되었는지 여부를 판단할 수 있게 해줍니다. 문제가 해결된 것으로 보이면 프로그램에서 작업을 수행하려고 시도할 수 있습니다.

Circuit Breaker 패턴은 Retry 패턴과 다른 용도로 사용됩니다. Retry 패턴은 어플리케이션이 다음 시도에 성공할 수 있기를 희망하며 작업들 다시 시도합니다. 

 

Circuit Breaker 는 어플리케이션이 위험한 활동을 수행하는 것을 금지하도록 디자인 되었습니다. 어플리케이션은 Circuit Breaker 를 통해 동작을 트리거하는 Retry 패턴을 사용할 수 있습니다. 반면에, Retry 로직은 Circuit Breaker 가 제공하는 모든 예외를 주의 깊게 검사하고 장애가 일시적이 아님을 나타내면 반복 시도를 중단해야 합니다.

Event Sourcing Pattern

대부분의 앱은 데이터로 작동하며, 일반적인 방법은 사용자가 데이터와 상호작용할 때 프로그램이 데이터를 업데이트하여 현재 상태를 유지하는 것입니다. 예를 들어, 고전적인 CRUD 아키텍처에서 일반적인 데이터 작업은 스토어에서 데이터를 수신하여 일부 변경한 다음 데이터를 잠그는 트랜잭션을 활용하여 데이터의 현재 상태를 새로운 값으로 업데이트 하는 것입니다.

 

Event Sourcing 디자인은 일련의 이벤트에 의해 트리거된 데이터 활동을 처리하는 방법을 정의하며, 각 이벤트는 추가만 허용하는 저장소에 기록됩니다. 어플리케이션 코드는 이벤트 저장소에 일련의 이벤트를 전달하고, 이 이벤트들은 각각 데이터에 발생한 동작을 설명해야 합니다. 각 이벤트는 데이터 변경사항을 설명합니다. (예 : "AddedItemToOrder")

 

이벤트는 데이터의 현재 상태에 대한 기록을 시스템 레코드(공식 데이터소스) 역할을 하는 이벤트 스토어에 저장됩니다. 이러한 이벤트는 종종 이벤트 리테일러에 의해 발행되어 컨슈머가 인식하고 필요한 경우 처리할 수 있도록 합니다. 예를 들어, 컨슈머는 이벤트의 작업을 다른 시스템에 적용하는 작업을 시작하거나 프로세스를 완료하는 데 필요한 다른 관련 작업을 실행 할 수 있습니다. 이벤트를 생성하는 어플리케이션 코드와 이벤트를 구독하는 시스템은 별도로 존재함을 언급하는 것이 중요합니다.  

SideCar Pattern

모니터링, 로깅, 설정 및 네트워킹 서비스는 어플리케이션과 서비스에서 자주 요구되는 기능입니다. 이러한 부가적인 작업은 독립된 구성요소 또는 서비스로 수행될 수 있습니다.

 

사이드카 서비스는 항상 어플리케이션의 일부인 것은 아니지만, 어플리케이션과 연결되어 있습니다. 이것은 부모 어플리케이션을 어디든 ㄸ라다닙니다. 사이드카는 주요 어플리케이션과 함께 제공되는 프로시저 또는 서비스입니다. 오토바이의 사이드카는 한 대의 오토바이에 결합되며 가각의 오토바이는 자체 사이드카를 가질 수 있습니다. 마찬가지로 사이드카 서비스는 부모 어플리케이션의 운명을 반영합니다. 사이드카 인스턴스는 각 어플리케이션 인스턴스 옆에 배치되고 호스팅됩니다.

 

이러한 구성 요소는 긴밀하게 통합된 경우 어플리케이션과 동일한 프로세스에서 실행되어 공유 리소스를 최적으로 활용할 수 있습니다. 그러나 이는 적절하게 분리되지 않았음을 의미하며 이러한 컴포넌트 중 하나의 장애가 다른 컴포너느나 전체 어플리케이션에 영향을 미칠 수 있다는 것을 의미합니다. 또한, 일반적으로 부모 프로그램과 동일한 언어로 작성되어야 합니다. 이로 인해 컴포넌트와 어플리케이션은 서로 강하게 의존하게 됩니다. 

CQRS

CQRS 는 Command and Query Responsibility Segregation 의 약자로, 데이터 저장소 읽기와 업데이트 프로세스를 분리하는 패턴입니다. 어플리케이션에 CQRS를 구현하면 성능, 확장성 및 보안을 개선할 수 있습니다. CQRS로 전환하여 얻은 유연성은 시간이 지남에 따라 시스템을 더욱 효과적으로 발전시키고 도메인 수준에서 업데이트 명령이 병합 충돌을 유발시키는 것을 방지합니다.

 

Query 와 업데이트 모델을 분리하면 설계와 구현이 더 쉬워집니다. 그러나 CQRS 코드는 ORM 도구와 같은 스캐폴딩 기술을 사용하여 데이터베이스 스키마에서 자동으로 생성할 수 없습니다. (단, 생성된 코드 위에 사용자 정의 항목을 추가할 수 있음)

 

더 높은 격리수준을 위해, 읽기 데이터와 쓰기 데이터를 물리적으로 분할할 수 있습니다. 이 경우, 읽기 데이터베이스는 자체 쿼리에 최적화된 데이터 스키마를 활용할 수 있습니다. 예를 들어, 데이터의 materialised view 를 저장하여 복잡한 조인이나 ORM 매핑을 회피할 수 있습니다. 심지어 다른 종류의 데이터 저장소를 사용할 수도 있습니다. 예를 들어, 쓰기 데이터베이스는 관계형이고, 읽기 데이터베이스는 document 데이터베이스 일 수 있습니다.

Rate Limiting Pattern

과도한 리소스 사용을 방지하기 위해 일부 서비스에서는 다른 어플리케이션이나 서비스가 자원을 사용하는 속도에 제한을 둡니다. 이를 쓰로틀링(Throttlign) 이라고 합니다. Rate Limiting 패턴을 사용하면 이러한 제한으로 인한 쓰로틀링 오류를 줄이거나 방지하고 처리량을 보다 정확하게 예측할 수 있습니다.

 

Rate Limiting 패턴은 여러 상황에서 유용하게 쓰이지만, 특히 배치 처리와 같은 대규모 반복 자동화 작업에 유용합니다.

특정 시간 동안 서비스에 제공되는 레코드의 양을 제한함으로써 Rate Limiting을 트래픽을 줄이고 처리량을 늘릴 수 있습니다.

 

시간이 지남에 따라 서비스를 제한하기 위해 다음을 포함한 다양한 조치를 취할 수 있습니다 :

- 작업 수량 (예 : 요청 60개)

- 데이터 볼륨(예 : 분당 50GB)

- 상대적인 작업 비용(예 : 초당 42,000RU)

 

쓰로틀링에 사용되는 지표와 관계없이, 선택한 Rate Limiting 접근 방식은 쓰로틀링 한도를 초과하지 않고 정해진 시간동안 서비스에 전달되는 작업의 양 또는 크기를 조절하는 것을 포함합니다.

Strangler Fig

특정 기능을 새로운 앱과 서비스로 점진적으로 대체하여 레거시 시스템을 점진적으로 마이그레이션 하세요. 기존 시스템은 결국 새로운 시스템으로 대체하여 해당 시스템을 폐기할 수 있게 됩니다.

 

특정 기능을 단계적으로 새로운 소프트웨어와 서비스로 대체합니다. 레거시 백엔드 시스템으로 향하는 요청을 잡아내는 파사드를 만듭니다. 이러한 요청은 파사드에 의해 새로운 서비스 또는 레거시 어플리케이션으로 전달됩니다. 기존의 기능이 새 시스템으로 점진적으로 이동하는 동안 고객은 동일한 인터페이스를 사용할 수 있으므로 전환에 대해 전혀 알지 못합니다.

 

 

이 방법을 사용하면 개발 작업을 여러 시간에 걸쳐 분산하고 마이그레이션 위험을 줄일 수 있습니다. 파사드가 사용자를 적절한 어플리케이션으로 안전하게 리다이렉션하기 때문에 기존 어플리케이션이 계속 작동하도록 하면서 원하는대로 새 시스템에 기능을 추가할 수 있습니다. 기존 시스템은 새로운 시스템으로 기능이 이전되면서 점진적으로 더 이상 필요하지 않게 됩니다. 이 절차를 마치면 레거시 시스템을 안전하게 폐기할 수 있습니다.

Health Endpoint Monitoring Pattern

Health Endpoint Monitoring 패턴은 프로그램과 서비스가 올바르게 작동하는지 확인하는데 사용될 수 있습니다. 이 패턴은 어플리케이션에서 기능 검사를 사용하는 방법을 간략하게 설명합니다. 개방된 엔드포인트 를 통하여 외부 도구를 이용하여 정기적으로 접근하여 체크할 수 있습니다. 

 

어플리케이션 엔드포인트로 요청을 보내면 상태 모니터링이 가능합니다. 모든 필수 테스트를 실행한 후 프로그램에서 상태를 표시해야 합니다.

 

일반적으로, 상태 모니터링 검사는 두가지 요소를 결합하여 수행합니다.:

 

상태 확인 엔드포인트 요청이 이루어지면 어플리케이션 또는 서비스에서 검사를 실행합니다. 상태 확인 검사를 수행하는 시스템 또는 도구가 결과를 평가합니다. 응답 코드는 어플리케이션의 상태를 나타냅니다. 앱의 구성 요소 및 서비스 상태는 응답코드에 선택적으로 포함될 수 있습니다. 지연시간 또는 반응 시간 체크는 모니터링 도구나 프레임워크에 의해 수행됩니다.

 

패넡은 다음 그림에서 확인 할 수 있습니다.