一、基于多线程搭建简单MQ

 1 package com.miaoshaProject.mq.demo;
 2 
 3 import com.alibaba.dubbo.common.json.JSONObject;
 4 import com.fasterxml.jackson.databind.util.JSONPObject;
 5 
 6 import java.util.concurrent.LinkedBlockingDeque;
 7 
 8 /**
 9  * @Author wangshuo
10  * @Date 2022/5/4, 21:42
11  * 基于多线程搭建简单MQ
12  */
13 public class ThreadMQ {
14 
15     private static LinkedBlockingDeque<JSONObject> mq = new LinkedBlockingDeque<JSONObject>();
16 
17     public static void main(String[] args) {
18 
19         Thread producerThread = new Thread(new Runnable() {
20             @Override
21             public void run() {
22                 try {
23                     while (true) {
24                         Thread.sleep(1000);
25                         JSONObject jsonObject = new JSONObject();
26                         jsonObject.put("name", "wangshuo");
27                         mq.offer(jsonObject);
28                     }
29                 } catch (InterruptedException e) {
30                     e.printStackTrace();
31                 }
32             }
33         }, "生产者");
34 
35         Thread consumerThread = new Thread(new Runnable() {
36             @Override
37             public void run() {
38                 try {
39                     while (true) {
40                         JSONObject poll = mq.poll();
41                         if (poll != null) {
42                             System.out.println(poll.get("name"));
43                         }
44                     }
45                 } catch (Exception e) {
46                     e.printStackTrace();
47                 }
48             }
49         }, "消费者");
50 
51         producerThread.start();
52         consumerThread.start();
53     }
54 }

二、基于netty实现

1.注册中心 NettyMQServer

 1 package com.miaoshaProject.mq.demo;
 2 
 3 import com.alibaba.dubbo.common.json.JSONObject;
 4 import com.fasterxml.jackson.databind.util.JSONPObject;
 5 
 6 import java.util.concurrent.LinkedBlockingDeque;
 7 
 8 /**
 9  * @Author wangshuo
10  * @Date 2022/5/4, 21:42
11  * 基于多线程搭建简单MQ
12  */
13 public class ThreadMQ {
14 
15     private static LinkedBlockingDeque<JSONObject> mq = new LinkedBlockingDeque<JSONObject>();
16 
17     public static void main(String[] args) {
18 
19         Thread producerThread = new Thread(new Runnable() {
20             @Override
21             public void run() {
22                 try {
23                     while (true) {
24                         Thread.sleep(1000);
25                         JSONObject jsonObject = new JSONObject();
26                         jsonObject.put("name", "wangshuo");
27                         mq.offer(jsonObject);
28                     }
29                 } catch (InterruptedException e) {
30                     e.printStackTrace();
31                 }
32             }
33         }, "生产者");
34 
35         Thread consumerThread = new Thread(new Runnable() {
36             @Override
37             public void run() {
38                 try {
39                     while (true) {
40                         JSONObject poll = mq.poll();
41                         if (poll != null) {
42                             System.out.println(poll.get("name"));
43                         }
44                     }
45                 } catch (Exception e) {
46                     e.printStackTrace();
47                 }
48             }
49         }, "消费者");
50 
51         producerThread.start();
52         consumerThread.start();
53     }
54 }

2.生产者 NettyMQProducer

  1 package com.miaoshaProject.mq.demo;
  2 
  3 import com.alibaba.fastjson.JSONObject;
  4 import io.netty.bootstrap.Bootstrap;
  5 import io.netty.buffer.ByteBuf;
  6 import io.netty.buffer.Unpooled;
  7 import io.netty.channel.*;
  8 import io.netty.channel.nio.NioEventLoopGroup;
  9 import io.netty.channel.socket.SocketChannel;
 10 import io.netty.channel.socket.nio.NioSocketChannel;
 11 
 12 /**
 13  * @ClassName MayiktNettyMQProducer
 14  * @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com
 15  * @Version V1.0
 16  **/
 17 public class NettyMQProducer {
 18     public void connect(int port, String host) throws Exception {
 19         //配置客户端NIO 线程组
 20         EventLoopGroup group = new NioEventLoopGroup();
 21         Bootstrap client = new Bootstrap();
 22         try {
 23             client.group(group)
 24                     // 设置为Netty客户端
 25                     .channel(NioSocketChannel.class)
 26                     /**
 27                      * ChannelOption.TCP_NODELAY参数对应于套接字选项中的TCP_NODELAY,该参数的使用与Nagle算法有关。
 28                      * Nagle算法是将小的数据包组装为更大的帧然后进行发送,而不是输入一次发送一次,因此在数据包不足的时候会等待其他数据的到来,组装成大的数据包进行发送,虽然该算法有效提高了网络的有效负载,但是却造成了延时。
 29                      * 而该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输。和TCP_NODELAY相对应的是TCP_CORK,该选项是需要等到发送的数据量最大的时候,一次性发送数据,适用于文件传输。
 30                      */
 31                     .option(ChannelOption.TCP_NODELAY, true)
 32                     .handler(new ChannelInitializer<SocketChannel>() {
 33                         @Override
 34                         protected void initChannel(SocketChannel ch) throws Exception {
 35                             ch.pipeline().addLast(new NettyClientHandler());
 36 ////                            1. 演示LineBasedFrameDecoder编码器
 37 //                            ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
 38 //                            ch.pipeline().addLast(new StringDecoder());
 39                         }
 40                     });
 41 
 42             //绑定端口, 异步连接操作
 43             ChannelFuture future = client.connect(host, port).sync();
 44             //等待客户端连接端口关闭
 45             future.channel().closeFuture().sync();
 46         } finally {
 47             //优雅关闭 线程组
 48             group.shutdownGracefully();
 49         }
 50     }
 51 
 52     public static void main(String[] args) {
 53         int port = 9008;
 54         NettyMQProducer client = new NettyMQProducer();
 55         try {
 56             client.connect(port, "127.0.0.1");
 57         } catch (Exception e) {
 58             e.printStackTrace();
 59         }
 60     }
 61 
 62     public class NettyClientHandler extends ChannelInboundHandlerAdapter {
 63 
 64 
 65         @Override
 66         public void channelActive(ChannelHandlerContext ctx) throws Exception {
 67 
 68             JSONObject data = new JSONObject();
 69             data.put("type", "producer");
 70             JSONObject msg = new JSONObject();
 71             msg.put("userId", "123456");
 72             msg.put("age", "23");
 73             data.put("msg", msg);
 74             // 生产发送数据
 75             byte[] req = data.toJSONString().getBytes();
 76             ByteBuf firstMSG = Unpooled.buffer(req.length);
 77             firstMSG.writeBytes(req);
 78             ctx.writeAndFlush(firstMSG);
 79         }
 80 
 81         /**
 82          * 客户端读取到服务器端数据
 83          *
 84          * @param ctx
 85          * @param msg
 86          * @throws Exception
 87          */
 88         @Override
 89         public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 90             ByteBuf buf = (ByteBuf) msg;
 91             byte[] req = new byte[buf.readableBytes()];
 92             buf.readBytes(req);
 93             String body = new String(req, "UTF-8");
 94             System.out.println("客户端接收到服务器端请求:" + body);
 95         }
 96 
 97         // tcp属于双向传输
 98 
 99         @Override
100         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
101             ctx.close();
102         }
103     }
104 }

3.消费者 NettyMQConsumer

  1 package com.miaoshaProject.mq.demo;
  2 
  3 import com.alibaba.fastjson.JSONObject;
  4 import io.netty.bootstrap.Bootstrap;
  5 import io.netty.buffer.ByteBuf;
  6 import io.netty.buffer.Unpooled;
  7 import io.netty.channel.*;
  8 import io.netty.channel.nio.NioEventLoopGroup;
  9 import io.netty.channel.socket.SocketChannel;
 10 import io.netty.channel.socket.nio.NioSocketChannel;
 11 
 12 /**
 13  * @ClassName MayiktNettyMQProducer
 14  * @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com
 15  * @Version V1.0
 16  **/
 17 public class NettyMQConsumer {
 18     public void connect(int port, String host) throws Exception {
 19         //配置客户端NIO 线程组
 20         EventLoopGroup group = new NioEventLoopGroup();
 21         Bootstrap client = new Bootstrap();
 22         try {
 23             client.group(group)
 24                     // 设置为Netty客户端
 25                     .channel(NioSocketChannel.class)
 26                     /**
 27                      * ChannelOption.TCP_NODELAY参数对应于套接字选项中的TCP_NODELAY,该参数的使用与Nagle算法有关。
 28                      * Nagle算法是将小的数据包组装为更大的帧然后进行发送,而不是输入一次发送一次,因此在数据包不足的时候会等待其他数据的到来,组装成大的数据包进行发送,虽然该算法有效提高了网络的有效负载,但是却造成了延时。
 29                      * 而该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输。和TCP_NODELAY相对应的是TCP_CORK,该选项是需要等到发送的数据量最大的时候,一次性发送数据,适用于文件传输。
 30                      */
 31                     .option(ChannelOption.TCP_NODELAY, true)
 32                     .handler(new ChannelInitializer<SocketChannel>() {
 33                         @Override
 34                         protected void initChannel(SocketChannel ch) throws Exception {
 35                             ch.pipeline().addLast(new NettyClientHandler());
 36 ////                            1. 演示LineBasedFrameDecoder编码器
 37 //                            ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
 38 //                            ch.pipeline().addLast(new StringDecoder());
 39                         }
 40                     });
 41 
 42             //绑定端口, 异步连接操作
 43             ChannelFuture future = client.connect(host, port).sync();
 44             //等待客户端连接端口关闭
 45             future.channel().closeFuture().sync();
 46         } finally {
 47             //优雅关闭 线程组
 48             group.shutdownGracefully();
 49         }
 50     }
 51 
 52     public static void main(String[] args) {
 53         int port = 9008;
 54         NettyMQConsumer client = new NettyMQConsumer();
 55         try {
 56             client.connect(port, "127.0.0.1");
 57         } catch (Exception e) {
 58             e.printStackTrace();
 59         }
 60     }
 61 
 62     public class NettyClientHandler extends ChannelInboundHandlerAdapter {
 63 
 64 
 65         @Override
 66         public void channelActive(ChannelHandlerContext ctx) throws Exception {
 67 
 68             JSONObject data = new JSONObject();
 69             data.put("type", "consumer");
 70             // 生产发送数据
 71             byte[] req = data.toJSONString().getBytes();
 72             ByteBuf firstMSG = Unpooled.buffer(req.length);
 73             firstMSG.writeBytes(req);
 74             ctx.writeAndFlush(firstMSG);
 75         }
 76 
 77         /**
 78          * 客户端读取到服务器端数据
 79          *
 80          * @param ctx
 81          * @param msg
 82          * @throws Exception
 83          */
 84         @Override
 85         public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 86             ByteBuf buf = (ByteBuf) msg;
 87             byte[] req = new byte[buf.readableBytes()];
 88             buf.readBytes(req);
 89             String body = new String(req, "UTF-8");
 90             System.out.println("客户端接收到服务器端请求:" + body);
 91         }
 92 
 93         // tcp属于双向传输
 94 
 95         @Override
 96         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
 97             ctx.close();
 98         }
 99     }
100 }