一、基于多线程搭建简单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 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16229258.html
浙公网安备 33010602011771号