使用 Netty 搭建消息中心

本文介绍了如何使用Netty搭建消息中心,讲解了Netty的基础概念如选择器、Channel、EventLoop等,并讨论了消息扩展的工厂模式、消息缓冲机制、连接超时和流控。还分享了异步处理中的注意事项,以及服务端的代码实现,包括EventLoopGroup、ServerBootstrap和NioServerSocketChannel的使用。
摘要由CSDN通过智能技术生成

简介:
Netty 是一套异步事件驱动的网络应用程序框架,支持快速开发可维护、高性能、面向协议的服务器和客户端。Netty 中涵盖包括网络通讯、多线程处理和并发等多个领域的专业知识,并优雅的将这些知识组织和处理。

重要
本例中,所有消息处理均采用模拟处理方式,不涉及实际实现!!!

规则:推送消息必须为 email|内容、text|内容、hi|内容 … …

消息扩展采用工厂模式

消息缓冲机制:使用Netty里的ChannelOutboundBuffer类,通过给它配置一个高水位线和低水位线。
当buffer的大小超过高水位线的时候对应channel的isWritable就会变成false,当buffer的大小低于低水位线的时候,isWritable就会变成true。应用判断isWritable,如果是false就不再写数据了。高水位线和低水位线是字节数,默认高水位是64K,低水位是32K,我们可以根据我们的应用需要支持多少连接数和系统资源进行合理规划。

基础概念:
Netty 中的几个基础知识点

  • 选择器
  • Channel
  • EventLoop
  • 回调
  • Future
  • 事件和 ChannelHandler

Netty 中的 Socket 参数

  • ChannelOption.SO_BACKLOG

BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。

  • ChannelOption.SO_KEEPALIVE

是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)并且在两个小时左右上层没有任何数据传输的情况下,这套机制才会被激活。

  • ChannelOption.TCP_NODELAY

在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。这里就涉及到一个名为Nagle的算法,该算法的目的就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。TCP_NODELAY就是用于启用或关于Nagle算法。如果要求高实时性,有数据发送时就马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数减少网络交互,就设置为false等累积一定大小后再发送。默认为false。

爬坑记录

  • 异步处理,流控先行

与异步相比,同步有天然的负反馈机制,也就是如果后端慢了,前面也会跟着慢起来,可以自动的调节。但是异步就不同了,异步就像决堤的大坝一样,洪水是畅通无阻。如果这个时候没有进行有效的限流措施就很容易把后端冲垮。如果一下子把后端冲垮倒也不是最坏的情况,就怕把后端冲的要死不活。这个时候,后端就会变得特别缓慢,如果这个时候前面的应用使用了一些无界的资源等,就有可能把自己弄死。

  • 连接超时
  • 在不同的线程里使用 PooledByteBufAllocator 分配和回收

项目扩展
我对于 ByteBuf 还没有深入的理解,后续补充吧(ByteBuf——Netty 的数据容器 )… …

消息处理中心 Demo

项目用于搭建一个类似于在线通讯的消息推送中心(可通过简单的改变消费者,实现即时通讯)。

消息中心为服务端。支持各种消息发送,提供友好接口可支持消息种类扩充
  • 服务端
// Server.java
package com.archer.server;

import com.archer.init.Initializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Server {
    private static int port;

    public Server(int port) {
        this.port = port;
    }

    public static void run() throws InterruptedException {

        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new Initializer())
                    .option(ChannelOption.SO_BACKLOG, 128) 
                    .option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 64 * 1024)
                    .option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 32 * 1024)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture future = bootstrap.bind(port).sync();

            System.out.println("服务器启动了!");
            future.channel().closeFuture().sync();
        } finally {
            worker.shutdownGracefully();
            boss.shutdownGracefully();
            System.out.println(
好的,以下是使用Netty搭建TCP服务器的示例代码(Hello World): ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class HelloWorldServer { private final int port; public HelloWorldServer(int port) { this.port = port; } public void run() throws Exception { // 创建两个 EventLoopGroup,一个用于接收客户端连接,一个用于处理客户端请求 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { // 创建 ServerBootstrap 对象,用于配置服务器 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // 添加消息处理器 ch.pipeline().addLast(new HelloWorldServerHandler()); } }); // 绑定端口,开始接收客户端请求 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 f.channel().closeFuture().sync(); } finally { // 释放资源 workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new HelloWorldServer(port).run(); } } ``` 其中,`HelloWorldServerHandler` 是自定义的消息处理器,可以根据需要进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值