- 도입 배경 및 아키텍처 결정
스프링 클라우드(Spring Cloud), MQ(Message Queuing) 를 연동한 서비스 도입 사례를 공유합니다.
도입 배경 및 아키텍처 결정 (현재글)
관련 연구 3 - Spring Cloud Stream, RabbitMQ 연동
도입 사례 1 - Spring Cloud Stream, RabbitMQ 실제 서비스 연동
도입 사례 2 - 예상했던, 예상하지 못했던 추가 작업
부록 A - RabbitMQ 연동하는 다양한 방법
부록 B - Spring Cloud Stream 버전 이슈
정리
사내 서비스 개선사항이기 때문에 공개하기 어려운 대외비는 내용에서 제외하였습니다. 서비스 아키텍처는 외부에 공유해도 되겠다는 판단으로 공유합니다. 개선사항 의견을 말씀해 주시면 감사드리겠습니다.
대용량 트래픽의 포털서비스에서 콘텐츠 실시간 배포시스템 구축을 위해 Spring Cloud, MQ(Message Queuing) 를 도입하였습니다.
Editor(서비스 관리자)는 콘텐츠를 CMS(Content management system) 에 편집 및 저장을 합니다. 해당 콘텐츠는 API 서버를 통해서 제공이 되며, 해당 콘텐츠를 사용하는 포털서비스는 Polling(주기적으로 API 를 검사하여 데이터를 수신하는 방식)으로 데이터를 가져옵니다. 가져온 데이터는 포털시스템 서버에 캐싱(데이터를 효과적으로 재사용할 수 있도록 메모리 등에 저장)하고 포털서비스 사용자(User) 가 웹서비스 요청 시에 해당 콘텐츠를 제공해줍니다. 일반적인 작은 웹서비스에서는 사용자의 요청이 있을 때마다 콘텐츠 DB 에 바로 액세스 해서 서비스 제공을 해도 상관없습니다. 하지만, 대용량 트래픽의 포털서비스에서는 매번 DB에서 Select 할 수 없고, 반드시 캐싱 아키텍처를 구축해야 합니다. 해당 아키텍처의 단점은, Polling 주기로 인해서 콘텐츠 서비스 업데이트 지연이 발생할 수 있습니다. 즉! 30초 주기로 Polling 한다면 최대 30초 정도 서비스 업데이트가 지연이 될 수 있는 구조입니다.
해당 아키텍처는 Polling 주기에 따라서 일정 시간이 지난 이후에 사용자에게 서비스됩니다. 사용자에게 실시간으로 서비스를 제공하려면 어떻게 해야 할까?
일반적인 방법이고 제가 예전 회사에서 자주 사용했던 방식입니다. 콘텐츠 데이터를 JSON or HTML 등의 스태틱(Static)한 파일로 포털시스템에 PUSH 해서 순차적으로 배포하는 방식입니다. 해당 방법의 단점은 포털시스템의 서버 대수가 많으면 순차적인 배포 프로세스에 따라서 서버마다 1~2초 정도는 늦게 서비스될 수는 있습니다. 즉, 콘텐츠 동기화가 안 되는 문제가 발생할 수 있습니다.
개발 스펙은 아래와 같습니다.
[PUB]콘텐츠 API로 제공해주는 방식에서 JSON , HTML 등의 스태틱한 파일 저장 기능 구현
[PUB]스태틱한 파일을 각 포털시스템에 PUSH(배포) 하는 시스템 구현
[SUB]포털시스템에서는 API 로 Polling 구조를 걷어내고 JSON, HTML 등의 스태틱 파일을 불러오는 기능 구현
콘텐츠 시스템에서 콘텐츠가 생성이 되면 MQ 브로커(두 지점을 연결하는 중재자)에 데이터를 PUB(발행)합니다. 해당 MQ 의 QUEUE 를 LISTEN(리스닝,구독) 하는 포털시스템의 LISTENER에서는 콘텐츠가 발행이 되면 실시간으로 해당 데이터를 구독(가져와서) 시스템에서 캐싱을 합니다. 사용자의 요청이 있을 경우에는 캐싱한 데이터를 바로 서비스합니다.
개발 스펙은 아래와 같습니다.
[PUB](콘텐츠 API로 제공해주는 방식에서) 데이터를 MQ 브로커의 QUEUE 에 PUBLISH 기능 구현
[SUB](포털시스템에서는 API 로 Polling 구조를 걷어내고) MQ 에 접속하여 리스너 이벤트가 발생하는 경우 콘텐츠를 캐싱하는 기능 구현
콘텐츠 시스템에서 콘텐츠가 생성이 되면 MQ 브로커에 콘텐츠가 업데이트되었다는 Message(업데이트신호)를 전달합니다. MQ의 Queue 를 구독하고 있는 포털시스템에서는 업데이트 Message를 받는 순간 콘텐츠 API를 호출합니다. 콘텐츠 생성이 되지 않으면(Message 가 전달되지 않으면) API 를 호출하지 않습니다. 즉, 기존 콘텐츠 API 시스템은 유지를 합니다. 단, 두 번째 방법과 비교하여 API 를 호출하는 1회의 Request/Response 비용이 더 필요합니다.
개발 스펙은 아래와 같습니다.
[PUB]콘텐츠 API는 유지를 하면서, 콘텐츠가 생성이 되면 업데이트 신호를 MQ 브로커의 QUEUE 에 PUBLISH 기능 구현
[SUB](포털시스템에서는 API 로 Polling 구조를 걷어내고) MQ 에 접속하여 리스너 이벤트가 발생하는 경우 API 를 호출하여 수신된 콘텐츠 데이터를 캐싱 로직 구현
콘텐츠를 Redis에 저장하고 사용자의 요청이 있으면 포털시스템에서 Redis 를 조회하여 데이터 서비스
후보 방법 중 두번 째 방법이 괜찮다고 1차로 판단하였으나, 본부 간의 협의가 필요하였습니다. (참고로 저는 포털시스템 개발 담당자입니다.) 콘텐츠API 개선하는 것이 다른 본부의 일이었고, 시스템을 한 번에 개선하기에는 RISK 가 있다는 판단이었기 때문에 API를 유지를 하면서, 업데이트 신호만 주고받는 세 번째 방식으로 진행하기로 협의하였습니다.
결과적으로, 세 번째 방법으로 진행이 좋은 판단이었습니다. 아키텍처 결정은 본부 리뷰를 통해서 결정하는 것이 좋습니다.
이번 글에서는 도입 배경 및 아키텍처 결정에 대해서 글을 작성해봤습니다. 다음 글에서는 [관련 연구 1 - 기본 개념] 라는 주제로 글을 쓸 예정입니다. [관련 연구 1 - 기본 개념]에서는 MQ, RabbitMQ, 스프링클라우드, 스프링 부트(Spring Boot), 마이크로서비스 아키텍처 등에 대해서 간략하게 정리를 할 예정입니다.
다음 포스팅
https://brunch.co.kr/@springboot/3