实现一个 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 3.2 Beta1版本正式发布

    5 月 31 日,开放原子开源基金会正式发布 OpenAtom OpenHarmony(以下简称"OpenHarmony")3.2 Beta1 版本.   全球开发者可通过Gite ...

  2. [一本通1681]统计方案 题解(Meet in mid与逆元的结合)

    题目描述 小\(B\)写了一个程序,随机生成了\(n\)个正整数,分别是\(a[1]-a[n]\),他取出了其中一些数,并把它们乘起来之后模\(p\),得到了余数\(c\).但是没过多久,小\(B\) ...

  3. C# 循环与条件语句详解

    C# Switch 语句 使用 switch 语句选择要执行的多个代码块中的一个. 示例: switch(expression) { case x: // 代码块 break; case y: // ...

  4. Windows wsl2安装Ubuntu

    wsl(Windows Subsystem for Linux)即适用于Windows的Linux子系统,是一个实现在Windows 10 / 11上运行原生Linux的技术. wsl2 为其迭代版本 ...

  5. HarmonyOS音频通话开发指导

      常用的音频通话模式包括VOIP通话和蜂窝通话. ● VOIP通话:VOIP(Voice over Internet Protocol)通话是指基于互联网协议(IP)进行通讯的一种语音通话技术.VO ...

  6. 第十篇:异步IO、消息队列

    一.协程 二.异步IO_Gevent 三.协程异步IO操作 四.事件驱动模型 五.IO多路复用 六.异步IO理论 一.回顾 线程 vs 进程 线程:CPU最小调度单位,内存共享: 线程同时修改同一份数 ...

  7. 重新整理数据结构与算法(c#)——算法套马踏棋算法[三十三]

    前言 马踏棋盘 概念在这,不做过多复述. https://baike.sogou.com/v58959803.htm?fromTitle=马踏棋盘 思路是这样子的,一匹马有上面几种做法,然后进行尝试, ...

  8. Redis为什么是单线程还支持高并发

    Redis为什么设计成单线程模式因为redis是基于内存的读写操作,所以CPU不是性能瓶颈,而单线程更好实现,所以就设计成单线程模式 单线程模式省却了CPU上下文切换带来的开销问题,也不用去考虑各种锁 ...

  9. 力扣278(java&python)-第一个错误的版本(简单)

    题目: 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最新版本没有通过质量检测.由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的. 假设你有 n 个版本 ...

  10. HarmonyOS NEXT应用开发—在Native侧实现进度通知功能

    介绍 本示例通过模拟下载场景介绍如何将Native的进度信息实时同步到ArkTS侧. 效果图预览 使用说明 点击"Start Download"按钮后,Native侧启动子线程模拟 ...