实现一个 MQ(消息队列)架构可以涉及到很多方面,包括消息的生产和消费、消息的存储和传输、消息的格式和协议等等。下面是一个简单的 MQ 架构的实现示例,仅供参考:

  1. 定义消息格式和协议:我们可以定义一个简单的消息格式,比如 JSON 格式,包含消息的 ID、内容、发送时间等信息。同时,我们可以定义一个简单的协议,比如 TCP 协议,用来传输消息。

  2. 实现消息的存储:我们可以使用数据库或者文件系统等方式来存储消息。对于消息队列来说,可以考虑使用类似于链表的数据结构来存储消息,每个节点包含一个消息和指向下一个节点的指针。

  3. 实现消息的生产和消费:我们可以使用多线程来实现消息的生产和消费。具体地,我们可以定义一个生产者线程和多个消费者线程,生产者线程负责从外部系统中获取消息并存储到消息队列中,消费者线程负责从消息队列中获取消息并进行处理。

  4. 实现消息的传输:我们可以使用 TCP 协议来传输消息。具体地,我们可以定义一个服务器程序,负责监听指定的端口号,并接受客户端的连接请求。一旦连接建立,服务器程序就可以和客户端进行数据传输。

综上所述,一个简单的 MQ 架构的实现可以包含以上几个部分。实际上,MQ 的实现还涉及到很多其他方面,比如消息的确认和重试、消息的过期和删除、消息的优先级和分区等等。因此,在实际项目中,需要根据具体的需求和场景来进行设计和实现。

以下是一个简单的 Java 消息队列示例代码,使用了多线程和 TCP 协议:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList; public class MessageQueue { private LinkedList<Message> queue = new LinkedList<Message>(); public synchronized void putMessage(Message message) {
queue.add(message);
notifyAll();
} public synchronized Message getMessage() throws InterruptedException {
while (queue.isEmpty()) {
wait();
}
return queue.removeFirst();
} public static void main(String[] args) {
MessageQueue queue = new MessageQueue();
Producer producer = new Producer(queue);
Consumer consumer1 = new Consumer(queue);
Consumer consumer2 = new Consumer(queue);
producer.start();
consumer1.start();
consumer2.start();
} } class Message implements java.io.Serializable { private static final long serialVersionUID = 1L; private String id;
private String content; public Message(String id, String content) {
this.id = id;
this.content = content;
} public String getId() {
return id;
} public String getContent() {
return content;
} } class Producer extends Thread { private MessageQueue queue; public Producer(MessageQueue queue) {
this.queue = queue;
} public void run() {
try {
ServerSocket serverSocket = new ServerSocket(9999);
while (true) {
Socket socket = serverSocket.accept();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message message = (Message) ois.readObject();
queue.putMessage(message);
ois.close();
socket.close();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
} } class Consumer extends Thread { private MessageQueue queue; public Consumer(MessageQueue queue) {
this.queue = queue;
} public void run() {
try {
while (true) {
Message message = queue.getMessage();
System.out.println("Consumer " + getId() + " got message: " + message.getContent());
Socket socket = new Socket("localhost", 9998);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message);
oos.close();
socket.close();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
} }

在这个示例中,我们定义了一个简单的消息队列,使用了一个链表来存储消息。然后,我们定义了一个生产者线程和两个消费者线程,生产者线程负责从外部系统中获取消息并存储到消息队列中,消费者线程负责从消息队列中获取消息并进行处理。我们使用 TCP 协议来传输消息,生产者线程监听端口号 9999,消费者线程通过连接 localhost 的 9998 端口来发送消息。在实际应用中,需要根据具体需求进行修改和扩展。

并在此代码基础上增加 协议类和注释

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList; // 消息队列类
public class MessageQueue { private LinkedList<Message> queue = new LinkedList<Message>(); // 往队列中添加消息
public synchronized void putMessage(Message message) {
queue.add(message);
notifyAll();
} // 从队列中取出消息
public synchronized Message getMessage() throws InterruptedException {
while (queue.isEmpty()) {
wait();
}
return queue.removeFirst();
} // 主函数
public static void main(String[] args) {
MessageQueue queue = new MessageQueue();
Producer producer = new Producer(queue);
Consumer consumer1 = new Consumer(queue);
Consumer consumer2 = new Consumer(queue);
producer.start();
consumer1.start();
consumer2.start();
} } // 消息类
class Message implements java.io.Serializable { private static final long serialVersionUID = 1L; private String type; // 消息类型,例如:ORDER, PAYMENT, SHIPMENT, 等等
private String content; // 消息内容
private String sender; // 消息发送者
private String receiver; // 消息接收者 // 构造方法
public Message(String type, String content, String sender, String receiver) {
super();
this.type = type;
this.content = content;
this.sender = sender;
this.receiver = receiver;
} // 返回消息类型
public String getType() {
return type;
} // 返回消息内容
public String getContent() {
return content;
} // 返回消息发送者
public String getSender() {
return sender;
} // 返回消息接收者
public String getReceiver() {
return receiver;
} } // 编解码协议类
class Protocol { public static final String HEADER = "MESSAGE"; // 消息头
public static final String DELIMITER = ":"; // 分隔符 // 将消息编码为字符串
public static String encode(Message message) {
return HEADER + DELIMITER + message.getType() + DELIMITER + message.getContent() + DELIMITER
+ message.getSender() + DELIMITER + message.getReceiver();
} // 将字符串解码为消息
public static Message decode(String messageString) {
String[] parts = messageString.split(DELIMITER);
return new Message(parts[1], parts[2], parts[3], parts[4]);
} } // 生产者线程类
class Producer extends Thread { private MessageQueue queue;
private ServerSocket serverSocket; // 构造方法
public Producer(MessageQueue queue) {
this.queue = queue;
} // 启动线程
public void run() {
try {
serverSocket = new ServerSocket(9999); // 监听端口号9999
while (true) {
Socket socket = serverSocket.accept(); // 接收连接
ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); // 创建输入流
String messageString = (String) in.readObject(); // 读取消息字符串
Message message = Protocol.decode(messageString); // 解码消息
queue.putMessage(message); // 添加消息到队列
in.close(); // 关闭输入流
socket.close(); // 关闭连接
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
} } // 消费者线程类
class Consumer extends Thread { private MessageQueue queue; // 构造方法
public Consumer(MessageQueue queue) {
this.queue = queue;
} // 启动线程
public void run() {
while (true) {
try {
Message message = queue.getMessage(); // 从队列中取出消息
System.out.println("Received message: " + message.getContent()); // 输出消息内容
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }

以下是在上面代码基础上增加消息确认和重试功能:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList; // 消息队列类
public class MessageQueue { private LinkedList<Message> queue = new LinkedList<Message>(); // 往队列中添加消息
public synchronized void putMessage(Message message) {
queue.add(message);
notifyAll();
} // 从队列中取出消息
public synchronized Message getMessage() throws InterruptedException {
while (queue.isEmpty()) {
wait();
}
return queue.removeFirst();
} // 主函数
public static void main(String[] args) {
MessageQueue queue = new MessageQueue();
Producer producer = new Producer(queue);
Consumer consumer1 = new Consumer(queue);
Consumer consumer2 = new Consumer(queue);
producer.start();
consumer1.start();
consumer2.start();
} } // 消息类
class Message implements java.io.Serializable { private static final long serialVersionUID = 1L; private String type; // 消息类型,例如:ORDER, PAYMENT, SHIPMENT, 等等
private String content; // 消息内容
private String sender; // 消息发送者
private String receiver; // 消息接收者
private boolean confirmed; // 消息是否已确认
private int retryCount; // 消息重试次数 // 构造方法
public Message(String type, String content, String sender, String receiver) {
super();
this.type = type;
this.content = content;
this.sender = sender;
this.receiver = receiver;
confirmed = false;
retryCount = 0;
} // 返回消息类型
public String getType() {
return type;
} // 返回消息内容
public String getContent() {
return content;
} // 返回消息发送者
public String getSender() {
return sender;
} // 返回消息接收者
public String getReceiver() {
return receiver;
} // 返回消息是否已确认
public boolean isConfirmed() {
return confirmed;
} // 设置消息已确认
public void setConfirmed() {
confirmed = true;
} // 返回消息重试次数
public int getRetryCount() {
return retryCount;
} // 增加消息重试次数
public void incrementRetryCount() {
retryCount++;
} } // 编解码协议类
class Protocol { public static final String HEADER = "MESSAGE"; // 消息头
public static final String DELIMITER = ":"; // 分隔符 // 将消息编码为字符串
public static String encode(Message message) {
return HEADER + DELIMITER + message.getType() + DELIMITER + message.getContent() + DELIMITER
+ message.getSender() + DELIMITER + message.getReceiver() + DELIMITER + message.isConfirmed()
+ DELIMITER + message.getRetryCount();
} // 将字符串解码为消息
public static Message decode(String messageString) {
String[] parts = messageString.split(DELIMITER);
Message message = new Message(parts[1], parts[2], parts[3], parts[4]);
message.setConfirmed(Boolean.parseBoolean(parts[5]));
message.incrementRetryCount();
return message;
} } // 生产者线程类
class Producer extends Thread { private MessageQueue queue;
private ServerSocket serverSocket; // 构造方法
public Producer(MessageQueue queue) {
this.queue = queue;
} // 启动线程
public void run() {
try {
serverSocket = new ServerSocket(9999); // 监听端口号9999
while (true) {
Socket socket = serverSocket.accept(); // 接收连接
ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); // 创建输入流
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); // 创建输出流
String messageString = (String) in.readObject(); // 读取消息字符串
Message message = Protocol.decode(messageString); // 解码为消息对象
if (!message.isConfirmed()) { // 如果消息未确认
queue.putMessage(message); // 添加到队列中
}
out.writeObject("ACK"); // 发送确认消息
out.flush();
in.close();
out.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace
}
}
}

Java简单实现MQ架构和思路01的更多相关文章

  1. 为什么要用消息队列 及 自己如何设计一个mq架构

    1. 解耦:如左图, 系统a因为业务需求需要调用系统b,后续因为业务需求可能需要改代码调用系统c,甚至还要考虑被调用的系统挂了访问超时的问题.耦合性太高! 如右图, 系统a产生一条数据发送到消息队列里 ...

  2. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  3. 整理下.net分布式系统架构的思路

    最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路.今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正. 首先说明的是.ne ...

  4. 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)

    高吞吐高并发Java NIO服务的架构(NIO架构及应用之一) http://maoyidao.iteye.com/blog/1149015   Java NIO成功的应用在了各种分布式.即时通信和中 ...

  5. Java生鲜电商平台-Java后端生成Token架构与设计详解

    Java生鲜电商平台-Java后端生成Token架构与设计详解 目的:Java开源生鲜电商平台-Java后端生成Token目的是为了用于校验客户端,防止重复提交. 技术选型:用开源的JWT架构. 1. ...

  6. java简单数据类型转化

    java简单数据类型,有低级到高级为:(byte,short,char)→int→long→float→double (boolean不参与运算转化) 转化可以分为 低级到高级的自动转化 高级到低级的 ...

  7. 00:Java简单了解

    浅谈Java之概述 Java是SUN(Stanford University Network),斯坦福大学网络公司)1995年推出的一门高级编程语言.Java是一种面向Internet的编程语言.随着 ...

  8. java简单学生成绩管理系统

    题目要求: 一. 数据结构要求:(5 分) 1.定义 ScoreInformation 类,其中包括七个私有变量(stunumber, name, mathematicsscore, englishi ...

  9. MVC架构模式分析与设计(一)---简单的mvc架构

    首先 我要感谢慕课网的老师提供视频资料 http://www.imooc.com/learn/69 下面我来进行笔记 我们制作一个简单的mvc架构 制作第一个控制器 testController.cl ...

  10. java简单词法分析器(源码下载)

    java简单词法分析器 : http://files.cnblogs.com/files/hujunzheng/%E7%AE%80%E5%8D%95%E8%AF%8D%E6%B3%95%E5%88%8 ...

随机推荐

  1. OpenHarmony Meetup 深圳站招募令

      OpenHarmony Meetup城市巡回深圳站火热来袭!! 日期:2023年10月15日14:00 地点:深圳市福田区上步路中路1003号 深圳市科学馆 与OpenHarmony技术大咖近距离 ...

  2. 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析

    在 MongoDB 中,我们使用 find() 和 find_one() 方法来在集合中查找数据,就像在MySQL数据库中使用 SELECT 语句来在表中查找数据一样 查找单个文档 要从MongoDB ...

  3. Visual Studio 2022插件的安装及使用 - 编程手把手系列文章

    这次开始写手把手编程系列文章,刚写到C#的Dll程序集类库的博文,就发现需要先介绍Visual Studio 2022的插件的安装及使用,因为在后面编码的时候会用到这些个插件,所以有必要先对这个内容进 ...

  4. 支持API 9的Sample已上新,速来拿走

    原文:https://mp.weixin.qq.com/s/sPDG5sG5F_gTp0cE1VV3gQ,点击链接查看更多技术内容.   今年的华为开发者大会上我们发布了HarmonyOS 3.1 D ...

  5. 抓包整理————ip 协议二[十三]

    前言 介绍一下什么是nat协议和napt协议,和简单带一下LVS. 正文 什么是nat(Network Address Translation) 协议呢? 比如现在你家分配了一个ip,但是你家有10个 ...

  6. 重新点亮shell————管道和重定向[二]

    前言 简单介绍一下管道和重定向. 正文 管道和信号一样,是进程通信的方式之一 管道符是"|",将前一个命令执行的结果传递给后面的命令. 比如说: ls -l | more 就是第一 ...

  7. 《Effective C#》系列之(零)——概要

    把全书的内容讲述完整可能需要很长时间,我可以先回答主要目录和核心的内容.如果您有任何特定问题或需要更详细的解释,请告诉我. <Effective C#>一书共包含50条C#编程建议,以下是 ...

  8. 【数学】主成分分析(PCA)的详细深度推导过程

    Based on Deep Learning (2017, MIT) book. 本文基于Deep Learning (2017, MIT),推导过程补全了所涉及的知识及书中推导过程中跳跃和省略的部分 ...

  9. Docker部署Node应用简单实践

    简介: 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用. 前言 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用.本文假设 ...

  10. Java单元测试技巧之PowerMock

    简介: 高德的技术大佬向老师在谈论方法论时说到:"复杂的问题要简单化,简单的问题要深入化." 这句话让我感触颇深,这何尝不是一套编写代码的方法--把一个复杂逻辑拆分为许多简单逻辑, ...