分布式——消息中间件实践

本文介绍了如何设计并实现一个简单消息队列系统,包括消息处理中心、消息生产者和消费者的角色。通过Java的ArrayBlockingQueue实现消息存储,并创建一个服务端接收和处理消息,客户端则可以发送消息和消费消息。示例展示了客户端生产与消费消息的过程。
摘要由CSDN通过智能技术生成

第一章 消息队列

1 设计一个简单的消息队列
消息队列的完整使用场景至少包含三个角色:

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

1.1 消息处理中心

package cn.distributed.msg;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * ClassName:Broker
 * Description:消息处理中心
 * Author:tanglp
 * Date:2022/9/13
 */
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("消息处理中心内暂存的消息达到最大负荷,不能继续放入消息!");
        }
    }

    // 消费消息
    public static String consume() {
        String msg = messageQueue.poll();
        if (msg != null) {
            // 消息条件满足情况,从消息容器中取出一条消息
            System.out.println("已经消费消息:" + msg + ",当前暂存消息数量是:" + messageQueue.size());
        }else {
            System.out.println("消息处理中心内没有消息可提供消费!");
        }
        return msg;
    }
}

1.2 对Broker提供服务

package cn.distributed.msg;

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

/**
 * ClassName:BrokerServer
 * Description:消息服务提供
 * Author:tanglp
 * Date:2022/9/13
 */
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);

                // CONSUME表示要消费一条消息
                if (str.equals("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 Exception {
        ServerSocket server = new ServerSocket(SERVICE_PORT);
        while (true) {
            BrokerServer brokerServer = new BrokerServer(server.accept());
            new Thread(brokerServer).start();
        }
    }
}

1.3 客户端访问

package cn.distributed.msg;

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

/**
 * ClassName:MqClient
 * Description:客户端访问
 * Author:tanglp
 * Date:2022/9/13
 */
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;
        }
    }
}

1.4 实现

package cn.distributed.msg;

/**
 * ClassName:Main
 * Description:
 * Author:tanglp
 * Date:2022/9/13
 */
public class Main {

}

class ProduceClient {
    public static void main(String[] args) throws Exception {
        MqClient client = new MqClient();
        client.produce("hello world");
    }
}

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

1.5 结果展示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DigitalDynamo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值