Obsidian/Recognition/Programing/RabbitMQ(AMQP)/RabbitMQ 장애조치.md

5.7 KiB
Raw Blame History

#RabbitMQ

장애 방지 방법

1. 브로커

1-1. Clustering

rabbitmqctl의 join_cluster 명령을 통해서 클러스터를 구성할 수 있다. 공식문서

  • 주의할점
    • 모든 노드는 같은 Erlang 쿠키 정보를 가지고 있어야 한다.
    • 네트워크는 LAN을 통해서 구성돼야 한다.
    • 모든 노드는 같은 버전의 RabbitMQ와 Erlang으로 작동 되어야 한다.
    • 클러스터에 참여하기 전 노드는 DISK or RAM 모드를 설정할 수가 있다. (RAM 모드 설정 시 메시지 손실을 방지할 수 없기 때문에 DISK 모드를 권장한다)

1-2. Exchange and Queue Durability

서버의 오류로 인해서 재가동 시 이전의 설정으로 자동 복원이 되도록 한다.

아래의 함수를 통해 Exchanger, Queue Durability를 설정하여 브로커가 재가동 시에도 이전의 정보를 가지고 복원되게 할 수 있다. durable 값을 true로 넘겨준다.

Channel.exchangeDeclare(exchange_name, exchange_type, durable, auto_delete, args);
Channel.queueDeclare(queue_name, durable, exclusive, autoDelete, args);

1-3. Queue Mirroring

큐 미러링을 통해서 모든 노드에 메시지를 동기화 시킨다.

동일 클러스터에 있는 노드중 하나의 노드가 동작하지 않는다면 큐에 있는 메시지는 노드가 다시 동작하지 않는 한 복구되지 않는다.(모든 노드의 큐는 동일한 메시지를 가지지 않는다.) 큐 미러링을 통해서 이러한 점을 보완할 수 있다.

큐 미러링 설정 rabbitmqctl set_policy 명령을 통해서 미러링 정책을 정할 수 있다. ex) rabbitmqctl set_policy -p {호스트명} {정책명} {큐이름(정규식표현가능)} {정책파라미터}

 ※ 모든 노드의 큐에 미러링을 설정하게 된다면 메시지 신뢰성은 높아지겠지만 성능은 저하될 수 있다.
큐미러링 설정 예)

# 1. host1 ha-all라는 정책 이름을 가지고 ha. 이름으로 시작하는 큐를 모든 노드에 미러링
rabbitmqctl set_policy -p host1 ha-all “^ha\. {ha-mode:all}

# 2. host1 ha-two라는 정책 이름을 가지고 two. 이름으로 시작하는 큐를 2개의 노드에만 미러링
rabbitmqctl set_policy -p host1 ha-two “^two\. {ha-mode:exactly,ha-params:2}

# 3. host1 ha-nodes라는 정책 이름을 가지고 nodes. 이름으로 시작하는 큐를 특정 노드에 미러링
rabbitmqctl set_policy -p host1 ha-nodes “^nodes\. {ha-mode:nodes, ha-params:[rabbit@jun-VirtualBox]};

1-4. Master and Slave

큐의 마스터와 슬레이브에 대해서 고려하여 서버를 구성한다.

  • 큐에는 마스터와 슬레이브 두가지 타입이 있다.
  • 모든 노드에 존재하는 각 큐에는 반드시 하나의 마스터 큐가 있어야 한다.
  • 큐에 메시지가 라우팅 되면 가장 먼저 마스터 큐에 메시지가 들어오게 되고 이 후 슬레이브 큐에 전달된다.
장애시 마스터 자동 지정 우선순위
  1. 메시지 동기화 타입인 노드
  2. 디스크타입으로 동작하는 노드
  3. 조인순서가 빠른 노드
참고

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=oidoman&logNo=220833403583 (RabbitMQ ACK) https://ssup2.github.io/theory_analysis/RabbitMQ_Ack/


Queue Durable 설정

재기동시 메시지 유지 참고, Storage저장방식, RabbitMQ서버 장애 대응

  • queue생성시 durable속성을 true로 주고 만든다.
  • message publish할때 MessageProperties.PERSISTENT_TEXT_PLAIN을 설정함
  • publisher confirms 사용

RabbitMQ ACK

Producer와 Consumer 사이의 Message 전달을 보장

Producer Confirm

  • Producer -> RabbitMQ 메시지 전달
  • RabbitMQ -> Producer ACK 전송.
    • Exchange에 설정된 규칙에 따라서 수신한 Message를 버려지면 Producer에게 즉시 ACK전송.
    • Message가 Queue로 전송되면 Queue가 Message를 저장한 이후에 Producer에게 ACK 전송.
    • Queue가 Mirroring 되어 있다면 Message는 Mirroring된 모든 Queue에 복사된 이후에 Producer에게 ACK 전송.
    • 만약 ACK가 일시작 Network장애로 인해서 Producer에게 전달되지 않은 상황인경우 연결이 재생성된 이후에 ACK를 받지 못한 Message를 재전송함. ※ 이경우 RabbitMQ는 중복된 Message를 수신할 수 있고 Consumer에게 그대로 전송됨.

Consumer Acknowledgement

  • RabbitMQ -> Consumer Message 전달
  • Consumer -> RabbitMQ ACK 전송. (Message 처리후)
  • RabbitMQ Queue 메시지 삭제
    • Consumer는 Message를 수신한 다음 반드시 특정 시간내에 ACK를 전송할 필요 없음(Time Out 없음, 수동Ack처리 가능)
    • RabbitMQ에서 ACK를 받지못한상태에서 연결끊어지면 연결 재생성이후 Message 재전송.
    • Message가 정상 수신되었어도 Consumer에 의해 Reject(해당 Msg), Nack(ACK를 전송하지 않은 모든 Msg) 될 수 있음.
    • 거절된 Message는 Reject/Nack응답과 함께 전동된 Requeue옵션에 따라 처리가 달라짐.
      • Requeue옵션 설정 O : Message는 원래 있던 Queue로 돌아간다. (이후 Consumer로 재전송)
      • Requeue옵션 설정 X : Queue의 DLX(Dead Letter Exchange)옵션에 따라 처리
        • DLX 옵션 O : DLX로 전송.
        • DLX 옵션 X : 버려짐.
    • RabbitMQ Server가 데이터를 계속 가지고 있다면, RabbitMQ Server는 Delivery Acknowledgement Timeout(Default : 30초) 시간 동안 보관 하고 이후 데이터를 ACK 받은 것으로 처리 한다. 참고 (설정 변경 가능)