본문 바로가기

개발

rabbitmq tutorial 2 - Work Queues 와 Round Robbin

Work Queues

하나의 work queue를 만들고 이 큐는 여러 worker에게 시간이 많이 드는 작업을 분배하는데 사용된다. 
work queue는 resource-intensive한 일은 즉시 수행하지 않고, 완료 될 때까지 기다리지 않는다. 
대신에 그 일을 나중에 하도록 일정을 잡는다. 작업을 메시지로 캡슐화하여 대기열에 보내고, 백그라운드에서 실행 중인 작업자 프로세스가 작업을 시작하고 최종적으로 작업을 실행한다. 이 개념은 짧은 HTTP 요청 기간 동안 복잡한 태스크를 처리할 수 없는 웹 응용 프로그램에서 특히 유용하다.

처음에는 간단한 hello world 였는데, 이제 복잡한 작업을 나타내는 문자열을 보내보자.  이미지나 PDF 파일 같은 실제 작업이 없으므로 Sread.sleep() 함수를 사용하여 사용 중인 것처럼 한다. 모든 점은 "작업"의 1초를 차지합니다. 예를 들어 Hello에서 설명하는 [가짜 작업…]은 점이 3개 므로 3초가 걸립니다.

Recv.java 파일이 수정되어야 하는데 메시지 본문에 있는 모든 점에 대해 1초 분량의 작업을 위장해야 한다.
 
소스에서 위장하는 메소드는 dowork 메소드이다. 


rabbitMq 홈페이지에서는 테스트 시 jar 파일 받아서 하고 특성상 Consumer 가 여러개 있어야 해서 

다음과 같이 $CP에 환경 설정하고 했는데 실행하기 귀찮……. 너어무 귀찬!!!!!

# shell 3
java -cp $CP NewTask

Spring boot 가 잘되있으니깐 boot로 하자! 

gradle이나 maven은 내가 jar 파일을 CP에 설정하지 않아도 되고, jar 파일로 만들면 쉽게 실행도 되니깐 boot로

main 메소드 안에 github에 있는 소스 넣고 gradle build 돌리면 jar 파일 만들어 지고 java -jar 명령으로 실행! 


밑에 두개는 consumer 를 띄움.




아래는 메세지를 보내는 부분을 boot로 실행.



메시지를 보내면 RabbitMQ management에서는 다음과 같이 차트에서 메세지를 받았다고 뜬다.

Round-robin dispatching

작업 대기열의 장점 중 하나는 작업을 쉽게 병렬 처리할 수 있다는 것입니다. 만약 일이 밀려 있다면, 더 많은 worker를 추가할 수 있고, 그렇게 하면 쉽게 확장할 수 있다.
기본적으로 RabbitMQ는 소비자에게 순서대로 각 메시지를 보냅니다. 평균적으로 모든 소비자는 동일한 수의 메시지를 받게 됩니다. 이러한 메시지 배포 방법을 라운드 로빈이라고 한다.



Message acknowledgment

작업을 수행하는 데 몇 초가 걸릴 수 있다. 소비자들 중 한 명이 긴 작업을 시작해서 부분적으로만 끝나면 어떻게 되는지 궁금할 것이다. 현재 코드로는 RabbitMQ가 고객에게 메시지를 전달하면 즉시 삭제되도록 되어있다. 이 경우, worker가 중단 되면 처리중이었던 메시지를 잃게 될 것이다. 이 특정 작업자에게 발송되었지만 아직 처리되지 않은 모든 메시지도 손실된다.

하지만 rabbitMq를 사용할때는 하고 있던 작업을 잃고 싶지 않습니다. worker가 죽으면, 그 일을 다른 worker 에게 전해주길 바란다.

RabbitMQ는 메시지 수신을 지원한다. 특정 메시지가 수신되고 처리되었으며 RabbitMQ를 삭제할 수 있다는 내용의 확인 메시지를 소비자가 RabbitMQ에 다시 보낸다.

확인 메시지를 보내지 않고 소비자가 죽거나, 연결이 닫히거나, TCP 연결이 끊어진 경우, RabbitMQ는 메시지가 완전히 처리되지 않았다는 것을 이해하고 메시지를 다시 대기시킨다. 동시에 다른 소비자가 있다면, 그것은 다른 소비자에게 신속하게 다시 전달할 것이다. 이렇게 하면 worker가 갑자기 다운되도 어떠한 메시지도 손실되지 않을 수 있다.

메시지 타임아웃은 없다. RabbitMQ는 소비자가 사망할 때 메시지를 다시 전달합니다. 메시지를 처리하는 데 매우 오랜 시간이 걸리더라도 괜찮다.

수동 메시지 확인은 기본적으로 켜져 있습니다. 앞의 예에서 autoAck=true 플래그를 통해 해당 플래그를 명시적으로 껐습니다. 일단 우리가 일을 마치면, 이제는 이 flag을 false으로 설정하고 worker에게 proper acknowledgment을 보낼 때이다.

반응형