Work Queues

2020. 4. 19. 20:39Spring Micro Services/RabbitMQ

반응형

Constants.java
0.00MB
NewTask.java
0.00MB
Worker.java
0.00MB

Hello World! 에서는 지정한 큐로 메세지를 주고 받는 프로그램을 작성해았습니다. 이번 예제에서는 시간이 많이 걸리는 작업을 여러작업에 배포하는 예제를 알아보자.

 

Work Queues 의 가장 핵심적인 개념은 Round-robin 분배 방식이다. 리소스를 많이 사용하는 작업을 즉시 수행하지 않고 완료될때까지 기다려야 한다. 대신에 작업이 나중에 수행 될수 있도록 예약해야 합니다. 작업을 메시지로 캡슐화하여 대기열로 보냅니다.

 

백그라운드에서 실행중인 작업 프로세스는 작업을 Pop 하고 작업을 실행합니다. 여러 Worker를 실행하면 작업은 공유 될것입니다.

 

[Work Queues 개념]

 

PRODUCER

메세지 발송을 위한 NewTask.java 프로그램을 작성한다.

package com.rabbitmq.tutorials.chap02;

import java.nio.charset.StandardCharsets;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;

public class NewTask {
	public static void main(String[] argv) throws Exception {
	
		System.out.println(Constants.HEADER);
		String rabbitmqHost = "localhost";
		
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(rabbitmqHost);
		
		try {
			// 서버연결
			Connection connection = factory.newConnection();
			
			// 채널생성	
			Channel channel = connection.createChannel();
			
			// QUEUE 생성
			boolean isDurable = true;
			boolean isExclusive = false;
			boolean isAutoDelete = false;
			
			channel.queueDeclare(Constants.queue, isDurable, isExclusive, isAutoDelete, null);
			
			// 메세지 전송
			String message = String.join(" ", argv);
			
			channel.basicPublish("", Constants.queue,
					MessageProperties.PERSISTENT_TEXT_PLAIN, 
					message.getBytes(StandardCharsets.UTF_8));
			
			System.out.println(" [x] Sent '" + message + "'");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}

 

CONSUMER

메세지 수신을 위한 Worker.java 프로그램을 작성한다.

package com.rabbitmq.tutorials.chap02;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

public class Worker {
	
	public static void main(String[] args) throws Exception {
		System.out.println(Constants.HEADER);
		String rabbitmqHost = "localhost";
		
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(rabbitmqHost);

		// 서버연결
		final Connection connection = factory.newConnection();
		
		// 채널생성
		final Channel channel = connection.createChannel();
		
		// QUEUE 생성
		boolean isDurable = true;
		boolean isExclusive = false;
		boolean isAutoDelete = false;
		boolean isAutoAck = false;
		
		channel.queueDeclare(Constants.queue, isDurable, isExclusive, isAutoDelete, null);
		System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
		
		// 한 번에 하나의 미확인 메세지만 처리
		channel.basicQos(1);
		
		// 메세지수신
		DeliverCallback deliverCallback = (consumerTag, delivery) -> {
			String message = new String(delivery.getBody(), "UTF-8");
			System.out.println(" [x] Received '" + message + "'");
			
			try {
				doWork(message);
			} finally {
				System.out.println(" [x] Done");
				channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
			}
		};
		channel.basicConsume(Constants.queue, isAutoAck, deliverCallback, consumerTag -> { });
	}

	private static void doWork(String task) {
		for (char ch : task.toCharArray()) {
			if (ch == '.') {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException _ignored) {
					Thread.currentThread().interrupt();
				}
			}
		}
	}

}

- doWork 메소드는 정상적으로 작업이 분배되는지 확인 하기 위해 지연 처리를 위해 구현된 메소드이다.

 

프로그램 실행

CONSUMER 실행

cmd 명령으로 창을 두개 띄운다. 각각의 창에  java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.Worker 실행한다.

그러면 아래와 같이 프로그램이 실행 되어져야한다.

 

PRODUCER 실행

cmd 창을 띄운다. 그리고 다섯개의 메세지를 전송한다. 실행명령은 아래와 같다.

   

java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.NewTask First message.

Ctrl+C

 

java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.NewTask Second message.

Ctrl+C

 

java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.NewTask Third message.

Ctrl+C

 

java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.NewTask Fourth message.

Ctrl+C

 

java -classpath ../lib/*; com.rabbitmq.tutorials.chap02.NewTask Fifth message.

Ctrl+C

 

왼쪽 맨위의 창을 C1 이라 하고 왼쪽 두번째 창을 C2 라고 하자. 메세지를 보낸 결과를 보면 첫번째는 C1 두번째 메세지는 C2로 분배 되는 것을 확인 할 수 있다.

 

※ 참고사이트

RabbitMQ Tutorial : https://www.rabbitmq.com/tutorials/tutorial-two-java.html

 

반응형

'Spring Micro Services > RabbitMQ' 카테고리의 다른 글

Topic  (0) 2020.04.19
Routing  (0) 2020.04.19
Publish/Subscribe  (0) 2020.04.19
Hello World  (0) 2020.04.19
Quick Start  (0) 2020.04.17