안녕하세요 rabbitMQ 관련하여 질문하나 드려도 될까요?

1,790 views
Skip to first unread message

애너벨리

unread,
Mar 1, 2015, 8:12:38 PM3/1/15
to ks...@googlegroups.com
spring-amqp , rabbitmq 를 공부하고 있습니다.

rabbitmq 에 대한 국내 자료가 너무 없네요ㅜㅜ

대용량 처리를 분산 하기 위하여 spring-amqp 와 rabbitmq 를 알아보고 있는 중 입니다.

sns 서비스를 예로 들어서 

조회시의 부담을 줄이기 위해  팔로워가 100만명인 사용자가 글을 작성했을 때, 인덱스 테이블에 100만행의 인서트를 하고자 합니다.

이런 경우에

web application 에서 포스트 작성 시 mq 서버로 메시지를 보내고  (was -> mq)

그걸 처리하는 별도의 컨슈머 서버가 존재하는게 맞는 구조 지요 ??

처음에는 
web application에서 mq 서버로 메시지를 보내고 

다시 web application 에서 그걸 리시브 해서 처리하는 구조를 생각했었습니다.. 

이런 식으로 처리하면 비동기 처리로서의 의미만 갖게 되는데 그렇다면 굳이 mq 를 쓸 필요없이 

컨트롤러단에서는 DeferredResult 나 Callable 을 이용. 서비스단에서는 @Async 를 이용한 비동기 처리를 하면 되지 않나라는 의문을 갖게 됐습니다.

그래서 리시브 해서 작업을 처리하는 컨슈머 서버를 따로 두는게 대용량 분산 처리가 제대로 되는 것이라 생각했습니다.

amqp 의 탄생 배경에 대해서 찾아봤습니다.

- 이전에도 상용화된 MQ 제품들은 많았지만, 한가지 문제가 있다면 대부분 플랫폼 종속적인 제품들이었기 때문에 서로 다른 이기종간에 메시지를 교환하기 위해서는 메시지 포멧 컨버전을 위한 메시지 브릿지를 이용하거나 (속도 저하 발생) 시스템 자체를 통일시켜야 하는 불편함과 비효율성이 있었다. (시스템을 교체하는 것은 논외로 치고 메시지 브릿지의 경우 MQ가 금융쪽에서도 많이 사용된다는걸 감안하면 속도 및 응답성의 저하는 치명적인 약점일 수 밖에 없다) 이러한 기존의 MQ들의 약점을 보완하기 위해 등장한것이 AMQP이다. 즉, AMQP의 목적은 서로 다른 시스템간에 (비용/기술/시간적인 측면에서) 최대한 효율적인 방법으로 메시지를 교환하기 위한 MQ 프로토콜인 것이다.

위 탄생배경을 보고 제가 했던 의문이 점점 맞다는 생각이 점점 드는데요.. 그래도 확신이 없기에 이렇게 질문드립니다.

최종적으로 질문을 요약드리자면

제가 이해하기론 서로 다른 이기종간에 메시지를 주고 받을 때 최적화를 위해 탄생한게 바로 AMQP 라고 이해했는데 맞는지요?

맞다면, SEND 하는 쪽과 RECEIVE하는 쪽이 서로 다른 이기종일 때 AMQP 를 쓰는 이유가 있다고 생각되는데 맞는지요?

물론 이기종이 아니더라도 쓸 수 있지만, 최소한 서로 다른 서버(혹은 서비스)간에 메시지를 전달하는데 쓰는게 맞다고 생각하는데 맞는지요?

제가 위에서 생각했던 WEB APPLICATION 에서 MQ 서버로 메시지를 SEND 하고 그걸 다시 WEB APPLICATION에서 RECEIVE해서 쓴다면 그게 MQ를 써야할 의미가 있는지요?



KwonNam Son

unread,
Mar 2, 2015, 6:39:46 AM3/2/15
to ks...@googlegroups.com
MQ는 비동기 처리용이고, 그간 Java 기반의 MQ가 Java 애플리케이션끼리만 작동했을텐데 RabbitMQ는 언어나 플랫폼이 달라도 작동하기 때문에 이기종간 메시징 특징이 추가된것입니다.

MQ로써의 특징과 RabbitMQ의 특징을 혼동하신 것 같습니다.

어쨌든 첫째로 비동기 처리를 하실거면 MQ를 사용하시면 되는거고 이기종간의 처리가 아니라면 굳이 RabbitMQ가 아니라 Java만 지원하는 MQ를 사용해도 되겠지요. 하지만 요즘 대세는이기종간 메시징 지원 여부에 상관없이  RabbitMQ 같네요.

둘째로, 웹 애플리케이션 서버가 MQ로 메시지를 보내고 그 메시지를 다시 동일한 웹 애플리케이션 서버가 받는 구조 같은데요 일반적으로는 MQ를 받아서 처리하는 Consumer 서버를 따로 둡니다. 근데 그것  Consumer 자체도 Tomcat 등으로 웹서버로 띄우는 경우가 제일 많은것 같습니다. Tomcat이 그 자체로 애플리케이션의 데몬 역할을 하니까요.

셋째로, 동일 웹 애플리케이션이 메시지를 보내게 그것을 다시 동일 웹 애플리케이션에서 받는 것이 무슨 의미가 있느냐? 차라리 @Async를 사용하는게 낫지 않겠냐? 라고 물어보실 수 있을 것인데 두번째에서 말씀드린대로 보통은 Consumer는 별도 서버로 분리하는게 좋습니다. 하지만 동일 서버가 Consumer 역할을 하더라도 MQ를 사용하는게 좋을 수도 있습니다. 왜냐하면 친구 100만명을 가진 사용자가 글을 썼다면 100만명에게 글 정보를 저장하는 @Async 코드가 실행됐다치죠. 근데 50만명 정도 저장하는 도중에 Tomcat 서버가 죽어버렸습니다. 그렇게 되면 분명히 앞서 500명 저장하던 데이터는 Rollback 이 되겠지요, 게다가 @Async 로 호출된 메소드는 톰캣이 죽는 순간 자기가 하고 있던 작업을 분실하게 됩니다. 따라서 웹 서버가 죽으면 100만명에 대한 글 저장 명령이 갑자기 사라지게 됩니다. 이는 정합성에 치명적 문제가 될 수 있습니다.

MQ는 트랜잭션 기능이 있습니다. 트랜잭션이 실패하면 MQ에서 Consumer로 보내진 메시지는 다시 회수되어 MQ에 저장되고 그걸 처리할 수 있는 다른 Consumer에다 고스란히 다시 보내줍니다. 따라서 MQ  메시지를 처리하던 컨슈머 서버가 갑자기 죽어도 메시지가 유실되지 않고 복구가 가능해집니다. 사실은 비동기 + 데이터 보존성 이것이 MQ를 사용하는 의미입니다.

그래서 결론은...
저라면 MQ 안 씁니다. ^^
누군가가 새로운 글을 올리면 그 글의 필드 중에 친구들에게 배포했는지 여부를  마킹하는 컬럼을 두고 Spring batch 로 주기적으로 처리할 것 갈아요. 일단 애플리케이션 코드가 더 간결하고 MQ 서버 유지보수에 대한 부담이 줄어들 것 같습니다.
친구들은.. 다른 친구가 쓴 글을 5분 정도는 더 기다렸다 봐 줄 수 있을 것 같네요...




2015년 3월 2일 오전 10:12, 애너벨리 <kwo...@gmail.com>님이 작성:

--
이 메일은 Google 그룹스 'Korea Spring User Group Q&A' 그룹에 가입한 분들에게 전송되는 메시지입니다.
이 그룹에서 탈퇴하고 더 이상 이메일을 받지 않으려면 ksug+uns...@googlegroups.com에 이메일을 보내세요.
http://groups.google.com/group/ksug에서 이 그룹을 방문하세요.
웹에서 이 토론을 보려면 https://groups.google.com/d/msgid/ksug/c63d6f7f-8cfb-46d1-89fe-48b40b303a78%40googlegroups.com을(를) 방문하세요.
더 많은 옵션을 보려면 https://groups.google.com/d/optout을(를) 방문하세요.



--
* 까먹지말자! http://kwon37xi.egloos.com

최빈

unread,
Mar 2, 2015, 9:30:08 PM3/2/15
to ks...@googlegroups.com
명쾌한 설명 정말 감사합니다 권남님 

덕분에 궁금증이 많이 해소됐어요. 

제 목표는 1000만명 한테 글 배달 5분 이내 라서 MQ는 써야할것 같습니다.

[인석] Chris Cho

unread,
Apr 8, 2015, 10:27:11 AM4/8/15
to ks...@googlegroups.com
안녕하세요, 조인석 입니다.

요구사항이 누군가 글을 올리면, 1000 만명 유저한테 5분내로 전달해야 하는 건가요?

제 생각에는 Producer/Consumer 개념으로 접근하기 보다는, Publish/Subscribe 개념으로 접근하는 것이 좋다고 봅니다. 
그렇다면 MQ를 쓸 이유가 명백해지죠..

그리고, 동일 WAS가 Publish나 Subscribe을 둘 다 하는 것도 별 문제 안되어 보입니다. 여러 WAS 중 한 녀석의 트랜잭션이 메시지를 만들어서 MQ에 집어 넣으면, 모든 WAS에서 받아 가는 구조로 가면 원하시는 시나리오가 완성되지 않을까 싶습니다.

RabbitMQ 튜토리얼에 자세히 나와 있네요.. 도움이 되겠습니다.

그럼, 좋은 하루 되세요!


--
이 메일은 Google 그룹스 'Korea Spring User Group Q&A' 그룹에 가입한 분들에게 전송되는 메시지입니다.
이 그룹에서 탈퇴하고 더 이상 이메일을 받지 않으려면 ksug+uns...@googlegroups.com에 이메일을 보내세요.
http://groups.google.com/group/ksug에서 이 그룹을 방문하세요.
Reply all
Reply to author
Forward
0 new messages