一个简单的消息中间件MQ实现

版权声明:个人原创 https://blog.csdn.net/qq_42459181/article/details/88399182

1. 消息处理中心类:
  此类是处理消息逻辑的基本类,若从MQ客户端接收的消息CONSUME,则为消费消息;若从MQ客户端接收的消息不为CONSUME,则为生产消息。

package com.richinfo.demo;
/**
 * 消息处理中心类
 * 
* Created by WangXJ
* 2019-02-20 10:57
*/

import java.util.concurrent.ArrayBlockingQueue;

public class Broker {
	
	// 队列存储消息的最大数量
	private final static int MAX_SIZE = 3;
	
	// 保存消息数据的容器
	private static ArrayBlockingQueue<String> messageQueue =
			new ArrayBlockingQueue<>(MAX_SIZE);
	
	// 生产消息
	public static void produce(String msg) {
		if (messageQueue.offer(msg)) {
			System.out.println("成功向消息处理中心投递消息: " + msg + ", 当前"
					+ "暂存的消息数量是: " +messageQueue.size());
		} else {
			System.out.println("消息处理中心内暂存的消息达到最大负荷, 不能继续放入消息!");
		}
		
		System.out.println("======================================");
	}
	
	// 消费消息
	public static String consume() {
		String msg = messageQueue.poll();
		if (msg != null) {
			// 消费条件满足,从消息容器中取出一条消息
			System.out.println("已经消费消息: " + msg + ",当前暂存的消息数量是: " + 
					messageQueue.size());
		} else {
			System.out.println("消息处理中心内没有消息可供消费!");
		}
		
		System.out.println("======================================");
		
		return msg;
	}
		
}

2. 消息处理中心的对外服务类:
  此类实现Runnable接口,循环监听服务端口(此处为9999),通过接收到的message类型(CONSUME或非CONSUME)操作消息队列(生产消息或消费消息)。

package com.richinfo.demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 消息处理中心的对外服务
 * 
* Created by WangXJ
* 2019-02-20 11:21
*/
public class BrokerServer implements Runnable{
	
	// 监听的服务端口号
	public static int SERVICE_PORT = 9999;
	
	private final Socket socket;
	
	public BrokerServer(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try (
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			PrintWriter out = new PrintWriter(socket.getOutputStream());
		){
			while (true) {
				String str = in.readLine();
				if (str == null) {
					continue;
				}
				System.out.println("接收到原始数据: " + str);
				
				if (str.equals("CONSUME")) { // CONSUME 表示要消费一条消息
					// 从消息队列中消费一条消息
					String message = Broker.consume();
					out.println(message);
					out.flush();
				} else {
					// 其他情况都表示生产消息放到消息队列中
					Broker.produce(str);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(SERVICE_PORT);
		while (true) {
			BrokerServer brokerServer = new BrokerServer(server.accept());
			new Thread(brokerServer).start();
		}
	}
}

3. MQ客户端类:
  模拟MQ客户端,给生产者类和消费者类提供服务(生产消息 、消费消息)。

package com.richinfo.demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * MQ客户端
 * 
* Created by WangXJ
* 2019-02-20 14:19
*/
public class MqClient {

	// 生产消息
	public static void produce(String message) throws Exception {
		Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVICE_PORT);
		try (
			PrintWriter out = new PrintWriter(socket.getOutputStream());
		) {
			out.println(message);
			out.flush();
		}
	}
	
	// 消费消息
	public static String consume() throws Exception {
		Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVICE_PORT);
		try (
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			PrintWriter out = new PrintWriter(socket.getOutputStream());
		) {
			// 先向消息队列发送字符串 “CONSUME” 表示消费
			out.println("CONSUME");
			out.flush();
			// 再从消息队列获取一条消息
			String message = in.readLine();
			
			return message;
		}
	}
}

4. 生产者类:
  此类用于调用MQ客户端生产消息并存入消息队列。

package com.richinfo.demo;
/**
 * 生产者
 * 
* Created by WangXJ
* 2019-02-20 14:59
*/
public class ProduceClient {

	public static void main(String[] args) throws Exception {
		MqClient client = new MqClient();
		client.produce("Hello 蒜头王八");
	}

}

5. 消费者类:
  此类用于调用MQ客户端消费消息队列里的消息。

package com.richinfo.demo;
/**
 * 消费者
 * 
* Created by WangXJ
* 2019-02-20 15:10
*/
public class ConsumeClient {

	public static void main(String[] args) throws Exception {
		MqClient client = new MqClient();
		String message = client.consume();
		System.out.println("获取的消息为: " + message);
	}

}

总结:
  简单实现了一个MQ客户端,通过生产者或消费者可以直接调用MQ客户端中响应的方法(生产消息或消费消息),MQ客户端再对消息队列(ArrayBlockingQueue类)进行操作(添加/生产消息或读取/消费消息)。

猜你喜欢

转载自blog.csdn.net/qq_42459181/article/details/88399182