12월, 2018의 게시물 표시

래빗MQ 메시지 딜리버리 확인 메커니즘 - 소비자에서 브로커로

소비자 acknowledgements, 발행자 confirms 프로토콜 메소드는 성공적으로 진행되었는지 보장되지 않기 때문에, 발행자와 소비자는 딜리버리와 처리 확인을 위한 메커니즘이 필요하다. 래빗MQ가 지원하는 몇몇 메시징 프로토콜은 이러한 특성을 제공한다. 소비자로부터의 딜리버리 처리 acknowledgements는 AMQP 0-9-1 용어로 알려져 있다.(소비자 -> 브로커) 발행자로 가는 브로커 acknowledgements는 발행자 확인이라고 부르는 프로토콜 확장이다.(브로커 -> 발행자) 두개의 특성은 같은 아이디어로부터 나왔고, TCP로부터 영감을 받았다. 이것들은 퍼블리시에서 래빗MQ노드로, 래빗MQ노드에서 소비자로의 reliable한 딜리버리를 위해 필수적이다. 1. (consumer) delivery acknowledgements 래빗MQ가 소비자로 메시지를 보낼때, 언제를 메시지가 성공적으로 보내졌는지로 할지 알 필요가 있다. 이런 로직은 시스템에 따라 다르다. 그러니까 어플리케이션에서 결정하는게 우선적이다. AMQP 0-9-1에서는 소비자가 basic.consume 메소드를 사용하여 등록하거나 메시지가 basic.get 메소드로 fetch되었을때로 한다. 2. 딜리버리 구분자 : delivery tags 다른 주제를 보기 앞서, 어떻게 딜리버리가 구분되는지 설명하는것이 중요하다.(그리고 acknowledgements는 각자의 딜리버리이다.) 소비자가 등록되었을때, 메시지는 basic.deliver 메소드를 사용해서 래빗MQ에 의해서 전달된다.(푸쉬된다.) 이 메소드는 채널 상에서 딜리버리를 유일하게 구분하는 delivery tag를 가지고 온다. 그러니까 딜러버리의 scope은 채널이다. 3. 딜러버리 태그는 단조롭게 증가하는 양의 정수이고, 클라이언트 라이브러리와 같은 것에 의해서 표시된다. 딜리버리를 확인(acknowledge)하는 클라이언트 라이브러리 메소드는 delivery...

클러스터링 - CAP 와 PACELC

CAP 와 PACELC http://happinessoncode.com/2017/07/29/cap-theorem-and-pacelc-theorem/

래빗MQ 클러스터링 - 2. 네트워크 파티션

클러스터링과 네트워크 파티션 클러스터링을 사용해서 복제를 통한 데이터 안정성, 작업 가용성, 처리량 향상 등 여러 목표를 달성할 수 있다. 클러스터 멤버간의 네트워크 연결 실패는 데이터 일관성 및 가용성에 영향을 준다. 각각의 어플리케이션은 일관성에 대한 요구사항이 다르고, 다른 규모의 비가용성을 견디므로 다른 '파티션 처리전략'을 사용할 수 있다. 1. 네트워크 파티션 감지 노드는 다른 노드가 일정시간동안(디폴트 60초) 노드에 접속할 수 없으면 해당 노드가 작동 중지되었다고 판단한다. 두 노드가 다시 접촉하면, 두 노드가 서로 장애가 발생했다고 생각하면 노드는 파티션이 발생했는지 결정한다. 이것은 다음과 같은 형식으로 래빗MQ 로그에 기록된다. 파티션 존재여부는 서버로그, HTTP API(모니터링용) 및 CLI 명령인 rabbitmqctl cluster_status 을 통해 식별할 수 있다. rabbitmqctl cluster_status 는 보통 partition에 대한 빈 리스트를 보여주지만, 네트워크 파티션이 발생하면 그곳에 나타난다. HTTP API는 각 노드에 대한 파티션 정보를 반환한다. 관리UI는 파티션이 발생한 경우 개요 페이지에 경고를 표시한다. ex) 래빗MQ 로그 =ERROR REPORT==== 15-Oct-2012::18:02:30 === Mnesia(rabbit@hostname): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, hare@hostname} ex) rabbitmqctl cluster_status # => Cluster status of node rabbit@smacmullen ... # => [{nodes,[{disc,[hare@smacmullen,rabbit@smacmullen]}]}, # =>  {running_nodes,[rabbit@smacm...

래빗MQ 메시지 발행 성능절충

1. 래빗MQ에는 메시지 발행에 대한 여러 설정이 있다. 메시지 발행속도는 배달 보장 메커니즘을 사용하면 느려진다. 추가적인 배달 보장없이 메시지를 발행하면 속도는 훨씬 빠르지만 안전하지 못하다. 아래와 같은 설정들을 할수 있다. - 배달보장 없음   : 걍 빠르다. - 실패통보   : 메시지의 mandatory 플래그를 true로 전달.    래빗MQ는 라우팅 못하면 basic.return RPC를 통해 메시지를 발행자에게 다시 보냄.    (성공하면 안보냄)    basic.return은 비동기로 동작하고, 처리하도록 설정해야 한다.    보통 콜백 메소드 등록해야 할 것이다. - 발행자 확인   : 래빗MQ는 basic.ack(성공) or basic.nack(실패)를 리턴한다.     보통 비동기적으로 응답하는 콜백 핸들러를 전달해야 한다. - 대체 익스체인지   : 라우팅할 수 없으는 메시지를 dead letter queue에 저장.     익스체인지 선언시 대체 익스체인지 명시. - 트랜잭션   : 메시지 전달 보장하는 방법 (발행자 확인 구현전에는 이게 유일한 방법이었다고 함)     브로커의 큐에 메시지를 성공적으로 전달했음을 basic.return으로 응답.     tx.select, tx.selectok, tx.commitok, tx.rollback 이런 것들이 사용된다.     (걍 발행자 확인을 쓰는 것이 권장된다.) - HA 큐   : 큐에 있는 동안 손실되지 않도록 하는 것.     큐를 여러서버에 중복해 복사본을 저장하는 기능     HA 큐로 메시지가 발행되면 HA 큐를 담당하는 클러스터의 각 서버로 메시지 동기화.  ...

래빗MQ 메시지 속성

1. 래빗MQ 메시지는 AMQP 스펙의 세가지 low-level 프레임으로 구성된다. - 메소드 프레임 - 콘텐츠 헤더 프레임 - 바디 프레임 2. 콘텐츠 헤더 프레임은 Basic.Properties 데이터 구조로 사전에 정의한 값들이 있다. - content-type : 소비자에게 메시지 본문을 해석하는 방법을 전달   ex) application/json, application/xml - content-encoding : 메시지 본문이 어떤 방법으로 압축 or 인코딩 되었는지 전달   ex) base64, gzip - message-id, correlation-id : 메시지, 메시지 응답 고유하게 식별   ex) uuid   : 어플리케이션에서 원하는 용도로 자유롭게 사용     correlation-id에는 message-id의 값을 지정할 수 있다. - timestamp : 메시지 크기를 줄이고 메시지 생성 시점에 대한 표준 시간 전달   : 이것도 어플레키에션 용도     메시지 성능 측정 가능. 메시지 수명 체크후 처리여부 결정 가능 - expiration : 메시지의 만료   : 문자열, 만료됐으면 큐에 안들어가고 삭제. 큐설정으로도 만료가능(x-message-ttl) - delivery-mode : 메시지를 디스크 또는 메모리에 저장할지 - app-id, user-id : 문제가 발생한 발행자 어플리케이션 추적 - reply-to : 패턴을 값으로 전달해 응답 메시지를 라우팅 - headers : 메시지 라우팅할때 사용자 정의 형식의 속성 정의 - priority : 메시지 우선순위 0~9(0이 높음) -  cluster-id  : (사용을 권장하지 않음) - type : 발행자와 소비자 사이의 계약을 정의 출처 : rabbitmq in depth 3장 (도서) ...