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

102 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#RabbitMQ
## 장애 방지 방법
### 1. 브로커
#### 1-1. Clustering
> rabbitmqctl의 join_cluster 명령을 통해서 클러스터를 구성할 수 있다. [공식문서](https://www.rabbitmq.com/clustering.html)
- 주의할점
- 모든 노드는 같은 Erlang 쿠키 정보를 가지고 있어야 한다.
- 네트워크는 LAN을 통해서 구성돼야 한다.
- 모든 노드는 같은 버전의 RabbitMQ와 Erlang으로 작동 되어야 한다.
- 클러스터에 참여하기 전 노드는 DISK or RAM 모드를 설정할 수가 있다.
(RAM 모드 설정 시 메시지 손실을 방지할 수 없기 때문에 DISK 모드를 권장한다)
#### 1-2. Exchange and Queue Durability
>서버의 오류로 인해서 재가동 시 이전의 설정으로 자동 복원이 되도록 한다.
>
아래의 함수를 통해 Exchanger, Queue Durability를 설정하여 브로커가 재가동 시에도 이전의 정보를 가지고 복원되게 할 수 있다. durable 값을 true로 넘겨준다.
``` Erlang
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 {호스트명} {정책명} {큐이름(정규식표현가능)} {정책파라미터}
※ 모든 노드의 큐에 미러링을 설정하게 된다면 메시지 신뢰성은 높아지겠지만 성능은 저하될 수 있다.
###### 큐미러링 설정 예)
``` Erlang
# 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 설정
>재기동시 메시지 유지 [참고](https://skarlsla.tistory.com/14), 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 받은 것으로 처리 한다. [참고](https://kaizen8501.tistory.com/220) (설정 변경 가능)
---