(一) 消息队列入门学习

参考书籍《分布式消息中间件实践》 感谢!

消息队列的功能

	消息队列,它包含了两个关键词:消息和队列。
	1,消息是指在应用间传输的数据,消息队列的表现形式是多样的(文本,结构化的对象格式)
	2,对于队列,抽象意义上来说,就是消息的进和出,从时间意义上来说进和出不一定是同步
	   的,因此一个典型的消息队列,至少要包含消息的发送、接收和暂存功能(如图)   
Send
Receive
消息生产者
消息处理中心
消息消费者

 1. 消息处理中心:负责消息的接受、存储、转发等
 2. 消息生产者:负责产生和发送消息到消息处理中心
 3. 消息消费者:负责从消息处理中心获取消息,并进行相应的处理

设计一个简单的消息队列

	从上面我们可以得到结论,消息队列服务的核心是消息处理中心,它至少要具备消息发送、
	    消息接收的消息暂存的功能。

消息处理中心

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){
        /*
            offer()--- 如果插入数据时队列没满 返回true 如果满了返回false
         */
        if (messageQueue.offer(msg)){
            System.out.println("成功向消息队列中投递信息:"+msg+"当前暂存消息队列的数量是"+messageQueue.size());
        }else {
            System.out.println("消息处理中心暂存的消息达到最大负荷,不能继续放入消息");
        }
        System.out.println("------------------------------------");
    }

    //消费消息
        public static  String consume(){
        /*
            pool方法删除数据时队列不为null 则返回队列头部的数据  如果队列为null立即返回null
         */
            String msg=messageQueue.poll();

            if (msg!=null){
                System.out.println("已经消费消息:"+msg+",当前暂存的消息数量是:"+messageQueue.size());
            }else {
                System.out.println("消息队列中已经没有消息可供消费!");
            }

            System.out.println("------------------------------------");
            return msg;
        }
}

外提供Broker类服务

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

/**
 * BrokerServer  类来对外提供Broker类服务
 */
public class BrokerServer implements  Runnable{

    public static int serverPort= 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 (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws  Exception {
        ServerSocket serverSocket = new ServerSocket(serverPort);
        while (true){
            //-----accept 该方法如无连接会阻塞等待连接
            BrokerServer brokerServer = new BrokerServer(serverSocket.accept());
            new Thread(brokerServer).start();
        }
    }
}

客户端访问

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

/**
 * 客户端访问
 */
public class MqClient {
    //生产消息
    public  static void produce(String message) throws  Exception{
        Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.serverPort);
        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.serverPort);
        try (
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream());
        ){
            //先向消息队列发发送字符串表示消费
            out.println("CONSUME");
            out.flush();

            //在从消息队列中获取一条消息
            String message = in.readLine();

            return  message;
        }
    }
}

测试生产消息(向服务中心队列添加数据)

public class ProduceCLient {
    public static void main(String[] args)  throws  Exception{
        MqClient.produce("hello World");
    }
}

测试消费消息(向服务中心队列删除数据)

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

测试结果如下

接收到原始数据:hello World
成功向消息队列中投递信息:hello World当前暂存消息队列的数量是1
------------------------------------
接收到原始数据:hello World
成功向消息队列中投递信息:hello World当前暂存消息队列的数量是2
------------------------------------
接收到原始数据:hello World
成功向消息队列中投递信息:hello World当前暂存消息队列的数量是3
------------------------------------
接收到原始数据:hello World
消息处理中心暂存的消息达到最大负荷,不能继续放入消息
------------------------------------
接收到原始数据:hello World
消息处理中心暂存的消息达到最大负荷,不能继续放入消息
------------------------------------
接收到原始数据:CONSUME
已经消费消息:hello World,当前暂存的消息数量是:2
------------------------------------
接收到原始数据:CONSUME
已经消费消息:hello World,当前暂存的消息数量是:1
------------------------------------
接收到原始数据:CONSUME
已经消费消息:hello World,当前暂存的消息数量是:0
------------------------------------

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

猜你喜欢

转载自blog.csdn.net/qq_41446768/article/details/83451674