DHH는 "Citadel"이라는 용어를 만들었습니다. 이 용어는 마침내 우리가 AppSignal에서 기술에 접근하는 방법을 참조할 수 있는 훌륭한 방법을 제공합니다. 우리는 "이것이 바로 우리다! 이제 우리 물건에 이름이 생겼다"고 말했습니다.
Majestic Monolith 외에도 누군가 The Citadel:A single Majestic의 패턴을 작성해야 합니다. Monolith는 고도로 전문화되고 다양한 요구 사항을 위한 몇 가지 보조 전초 기지 앱과 함께 앱의 대부분을 캡처합니다.
— DHH(@dhh) 2020년 4월 7일
AppSignal이 Citadel 패턴을 사용하는 방법을 설명하기 위해 시스템 작동 방식에 대해 조금 공유하겠습니다. AppSignal은 모니터링 에이전트가 데이터를 보내는 API와 사용자 대면 애플리케이션이 있는 모니터링 제품입니다. 그런 다음 이 데이터가 처리되어 그래프와 통찰력으로 바뀝니다.
모노리스
고객이 상호 작용하는 애플리케이션은 프론트 엔드의 일부가 React로 작성된 모놀리식 Rails 앱입니다. 백엔드는 전적으로 Ruby로 작성되었으며 몇 개의 데이터베이스와 통신합니다(확장상의 이유로 서로 다른 고객의 데이터를 별도의 클러스터로 분할). 이 Rails 앱은 외부 서비스에 경고를 보내는 것과 같은 많은 다른 작업도 처리합니다.
이 Rails 앱을 시작했을 때 모니터링 에이전트에서 들어오는 데이터도 처리했기 때문에 데이터 수집이 병목 현상이 될 것이라고 예상했습니다. 그래서 데이터를 수집하고 Rails 앱에서 처리하는 Sidekiq 작업을 생성하는 하위 도메인에서 실행되는 Sinatra 앱을 사용했습니다.
성장통
이 아키텍처는 수년간 잘 작동했습니다. 비즈니스가 성장함에 따라 에이전트로부터 들어오는 데이터를 처리하는 특정 작업에 특별한 처리가 필요하다는 것이 분명해졌습니다. 수십억 개의 요청을 모니터링할 때 엄격한 제한에 부딪힙니다. 주요 제한 요인은 Ruby가 느리다는 것이 아니라(우리 모두는 그렇지 않다는 것을 알고 있습니다.) 하지만 우리가 설계한 방식으로 인해 데이터베이스가 너무 많이 잠겼습니다.
전초기지
우리는 몇 가지 가능성을 살펴본 다음 Kafka가 우리 상황에 가장 적합하다고 결정했습니다. 우리는 Rust에 대한 약간의 경험이 있었고 그 속도와 안정성이 이 시스템에 매우 적합할 것이라고 생각했습니다. 우리는 Kafka를 대기열과 저장 시스템의 조합으로 사용하여 Rust에서 데이터 수집 및 처리 시스템을 다시 작성했습니다.
Rails 앱의 수신 데이터 처리 부분만 이 전초 기지 서비스로 옮겼습니다. 나머지 시스템은 모놀리식 앱 형태로 잘 작동합니다. 우리는 그것을 깊이 이해하고 있으며 일을 단순하게 유지하는 것을 좋아합니다. 모노리스는 여전히 대부분의 논리를 처리하고 Kafka와 크게 상호 작용합니다. 모놀리스를 유지하고자 하는 바람에 메인 앱이 전초 기지와 쉽게 통신할 수 있도록 Kafka gem을 작성하게 되었습니다.
AppSignal에서 Kafka가 작동하는 방식에 대해 자세히 알고 싶다면 이에 대해 제가 한 Railsconf 강연을 확인하세요.
성채에서의 생활
이것은 우리가 요새에서 매우 행복한 현재 상황으로 우리를 이끕니다. DHH가 말했듯이:
<블록 인용>단일 Majestic Monolith는 고도로 전문화되고 다양한 요구 사항을 위한 몇 가지 보조 전초 기지 앱으로 대부분의 앱을 캡처합니다.
우리의 경우 고도로 전문화된 요구 사항에 대한 단일 전초 기지 서비스가 있습니다. 올해 RailsConf가 있었다면 DHH에 이름을 지어준 것에 대한 감사의 표시로 추가 stroopwafels를 줬을 것입니다. 🍪