消息中间件-简易实现

1.创建使用ArrayBlockingQueue数据模型作为消息自定义中间件的消息载体,及消费生产模式

package MyQueue;

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:"+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.创建线程模拟MQ的消息接受及发送,启动后开启消息接受及发送

package MyQueue;

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

public class BrokerServer implements Runnable {
    public static int SERVER_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 meString=Broker.consume();
                    out.println(meString);
                    out.flush();
                }else{
                    //其他情况都表示生产消息放到消息队列中
                    Broker.produce(str);
                }
            }
            
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        
    }
    
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(SERVER_PORT);
        while (true) {
            BrokerServer borkerServer=new BrokerServer(server.accept());
            new Thread(borkerServer).start();
        }
    }
        
}

3.创建生产及消费方法,模拟消息机制

package MyQueue;

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;


public class MqClient {
    //生产者
    @SuppressWarnings("unused")
    public static void produce(String message) throws IOException {
        @SuppressWarnings("resource")
        Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVER_PORT);
        PrintWriter out=new PrintWriter(socket.getOutputStream());
                    out.println(message);
                    out.flush();
    }
    
    //消费消息ss
    public static String consume() throws UnknownHostException, IOException{
        @SuppressWarnings("resource")
        Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVER_PORT);    
        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.创建消息接受者

package MyQueue;

import java.io.IOException;
import java.net.UnknownHostException;

public class ConsumeClient {
        public static void main(String[] args) throws UnknownHostException, IOException {
            MqClient mq=new MqClient();
            String mes=mq.consume();
            System.out.println("获取的消息为:"+mes);
        }
}

5.创建消息生产者

package MyQueue;

import java.io.IOException;

public class ProduceClient {
        public static void main(String[] args) throws IOException {
            MqClient client=new MqClient();
            client.produce("Hello new World!");
        }
}

总结:使用ArrayBlockingQueue数据结构,线程服务,socket通信模拟MQ机制可以加深对对成熟中间件的理解!

猜你喜欢

转载自www.cnblogs.com/deng-xiaoming/p/10740401.html