一、基于Netty实现消息中间件效果演示
private void procucterService(String queueName, String msg) {
Queue queue = queues.get(queueName);
if (queue == null) {
queue = new LinkedList();
queues.put(queueName, queue);
}
queue.offer(msg);
ChannelHandlerContext ctx = ctxs.get(queueName);
if (ctx != null) {
ctx.writeAndFlush(queue.poll());
}
}
二、Java语言创建队列实现的方式
1.点对点
public class QueueTest {
public static void main(String[] args) {
Queue queue = new LinkedList();
queue.offer("mayikt");
queue.offer("xiaowei");
queue.offer("xiaojun");
System.out.println(queue.size());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.size());
}
}
三、手写消息中间件思路的分析
四、基于Netty实现MQ消息中间件服务端
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling</artifactId>
<version>1.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling-serial</artifactId>
<version>1.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
五、基于NettyClient端实现生产者投递消息
六、基于NettyClient端实现手写消费者
七、生产者与消费者一直保持连接投递
@Data
public class DeliveryInfoEntity implements Serializable {
private String msg;
private String queueName;
private Boolean connType;
public DeliveryInfoEntity(String msg, String queueName, Boolean connType) {
this.msg = msg;
this.queueName = queueName;
this.connType = connType;
}
}
handler
public class NettyMQConsumerHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("消费者获取生产者消息:" + msg);
}
}
public class NettyMQServerHandler extends SimpleChannelInboundHandler<DeliveryInfoEntity> {
private static Map<String, Queue> queues = new HashMap<String, Queue>();
private static Map<String, ChannelHandlerContext> ctxs =
new HashMap<String, ChannelHandlerContext>();
@Override
protected void channelRead0(ChannelHandlerContext ctx, DeliveryInfoEntity dInfo) throws Exception {
String queueName = dInfo.getQueueName();
if (StringUtils.isEmpty(queueName)) {
return;
}
Boolean connType = dInfo.getConnType();
if (connType) {
procucterService(queueName, dInfo.getMsg());
return;
}
consumer(queueName, ctx);
}
private void procucterService(String queueName, String msg) {
Queue queue = queues.get(queueName);
if (queue == null) {
queue = new LinkedList();
queues.put(queueName, queue);
}
queue.offer(msg);
ChannelHandlerContext ctx = ctxs.get(queueName);
if (ctx != null) {
ctx.writeAndFlush(queue.poll());
}
}
private void consumer(String queueName, ChannelHandlerContext ctx) {
Queue queue = queues.get(queueName);
if (queue == null) {
return;
}
Object poll = queue.poll();
ctx.writeAndFlush(poll);
ctxs.put(queueName, ctx);
}
}
server端
public class NettyMQServer {
public static void start(int port) {
/**
* 客户端创建两个线程池组分别为 boss线程组和工作线程组
*/
// 用于接受客户端连接的请求 (并没有处理请求)
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
// 用于处理客户端连接的读写操作
NioEventLoopGroup workGroup = new NioEventLoopGroup();
// 用于创建我们的ServerBootstrap
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 解决netty可以支持传输对象
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(new NettyMQServerHandler());
}
});
// 绑定我们的端口号码
try {
// 绑定端口号,同步等待成功
ChannelFuture future = serverBootstrap.bind(port).sync();
System.out.println("MQ服务器启动成功:" + port);
// 等待服务器监听端口
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 优雅的关闭连接
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
start(5872);
}
}
producer
public class NettyMQProducer {
private static final String host = "127.0.0.1";
private static final int port = 5872;
private static String queueName = "mayikt";
public static void sendMsg(String msg) {
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
}
});
try {
ChannelFuture sync = bootstrap.connect().sync();
DeliveryInfoEntity deliveryInfoEntity = new DeliveryInfoEntity(msg, queueName,
true);
sync.channel().writeAndFlush(deliveryInfoEntity);
sync.channel().closeFuture().sync();
} catch (Exception e) {
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) {
sendMsg("每特教育第六期平均突破3万月薪");
}
}
consumer
public class NettyMQConsumer {
private static final String host = "127.0.0.1";
private static final int port = 5872;
private static String queueName = "mayikt";
public static void sendMsg(String msg) {
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(new NettyMQConsumerHandler());
}
});
try {
ChannelFuture sync = bootstrap.connect().sync();
DeliveryInfoEntity deliveryInfoEntity = new DeliveryInfoEntity(null, queueName,
false);
sync.channel().writeAndFlush(deliveryInfoEntity);
sync.channel().closeFuture().sync();
} catch (Exception e) {
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) {
sendMsg("每特教育第六期平均突破3万月薪");
}
}
utils
public final class MarshallingCodeCFactory {
public static MarshallingDecoder buildMarshallingDecoder() {
final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024 * 1024 * 1);
return decoder;
}
public static MarshallingEncoder buildMarshallingEncoder() {
final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
MarshallingEncoder encoder = new MarshallingEncoder(provider);
return encoder;
}
}