[Netty实现异步、事件驱动的模型 ]

 

目录

 🍍Netty介绍:

 🍍基于Netty的异步、事件驱动的模型

 🍍 Netty的高级特性的代码实现逻辑的解释:

 🍍NettyServerHandler 业务处理简单实现:

 🍍依赖:

 🍍Netty API:

 🍍流程讲解:

🍍上面NettyServerHandler中的方法是由Netty的事件循环(EventLoop)触发调用的。

🍍Netty的事件循环(EventLoop)是通过NIO Selector实现的。


 🍍Netty介绍:

  • Netty是一个基于Java NIO的网络通信框架,用于快速开发高性能、高可靠性的网络应用程序。它提供了一组易于使用的API,可以轻松地实现各种网络协议和应用程序,如HTTP、WebSocket、TCP、UDP等。Netty的主要特点包括:
  • 高性能:Netty使用异步、事件驱动的模型,可以处理大量的并发连接和请求。

  • 可扩展性:Netty的设计模式和组件化架构使得它非常易于扩展和定制。

  • 易于使用:Netty提供了简单易用的API和文档,使得开发人员可以快速上手。

  • 可靠性:Netty提供了丰富的错误处理机制和异常处理机制,可以保证应用程序的稳定性和可靠性。

  • 安全性:Netty提供了SSL/TLS支持,可以保证网络通信的安全性。

 🍍基于Netty的异步、事件驱动的模型

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;

public class NettyServer {
    private int port;

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

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            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 HttpServerCodec());
                     ch.pipeline().addLast(new HttpObjectAggregator(65536));
                     ch.pipeline().addLast(new ChunkedWriteHandler());
                     ch.pipeline().addLast(new NettyServerHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)
             .childOption(ChannelOption.SO_KEEPALIVE, true)
             .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        new NettyServer(port).run();
    }
}

 🍍 Netty的高级特性的代码实现逻辑的解释:

HttpServerCodec:用于处理HTTP请求和响应的编解码器。

在NettyServer类的childHandler()方法中,我们添加了一个HttpServerCodec对象,用于将HTTP请求和响应的字节流转换为HTTP消息对象。HttpServerCodec实际上是一个编解码器,它将HTTP请求和响应的字节流转换为HTTP消息对象,然后将HTTP消息对象转换为字节流发送给客户端。

HttpObjectAggregator:用于将HTTP请求和响应的多个部分合并成一个完整的消息。

在NettyServer类的childHandler()方法中,我们添加了一个HttpObjectAggregator对象,用于将HTTP请求和响应的多个部分合并成一个完整的消息。HttpObjectAggregator实际上是一个聚合器,它将HTTP请求和响应的多个部分合并成一个完整的消息,然后将完整的消息传递给下一个处理器进行处理。

ChunkedWriteHandler:用于处理大文件或大数据流的传输。

在NettyServer类的childHandler()方法中,我们添加了一个ChunkedWriteHandler对象,用于处理大文件或大数据流的传输。ChunkedWriteHandler实际上是一个处理器,它可以将大文件或大数据流分成多个块进行传输,从而避免一次性将整个文件或数据流加载到内存中。

PooledByteBufAllocator:用于内存池分配,可以提高内存使用效率。

在NettyServer类的childOption()方法中,我们设置了一个PooledByteBufAllocator对象,用于内存池分配。PooledByteBufAllocator实际上是一个内存池分配器,它可以提高内存使用效率,避免频繁地创建和销毁ByteBuf对象,从而提高性能和可靠性。

new NettyServerHandler()表示创建一个NettyServerHandler类的实例,NettyServerHandler类是一个自定义的业务逻辑处理器,实现了ChannelInboundHandler接口。

在Netty中,ChannelInboundHandler用于处理入站事件(例如接收到的数据),ChannelOutboundHandler用于处理出站事件(例如要发送的数据)。业务逻辑处理器通常实现ChannelInboundHandler接口,用于处理从客户端接收到的数据或者连接事件等。

在通道处理链(ChannelPipeline)中不同的组件将会负责不同的任务,例如读取数据、解码数据、编码数据、协议处理、业务处理等。业务处理器是通道处理链中的最后一步,用于处理业务逻辑。它将在之前的组件将接收到的数据解码,进行协议处理后,将处理结果交给业务处理器进行进一步的处理。

在添加业务处理器时,可以通过ch.pipeline().addLast(new NettyServerHandler())将其添加到通道处理链中。这样,在服务端接收到客户端的数据时,经过之前的组件处理后,数据将交给ServerHandler进行业务处理。

 🍍NettyServerHandler 业务处理简单实现:

public class NettyServerHandlerextends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 处理读取到的数据
        ByteBuf buf = (ByteBuf) msg;
        String data = buf.toString(CharsetUtil.UTF_8);
        System.out.println("Received data: " + data);

        // 回写响应数据
        String response = "Hello, client!";
        ByteBuf respBuf = Unpooled.copiedBuffer(response, CharsetUtil.UTF_8);
        ctx.write(respBuf);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 刷新缓冲区,将响应数据发送给客户端
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 处理异常
        cause.printStackTrace();
        ctx.close();
    }
}
 🍍依赖:
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.63.Final</version>
</dependency>

 🍍Netty API:

  • Channel:表示一个网络连接,可以用于读取和写入数据。

  • ChannelHandler:表示一个处理器,用于处理网络事件和数据。

  • EventLoop:表示一个事件循环,用于处理事件和任务。

  • Bootstrap:用于启动客户端连接。

  • ServerBootstrap:用于启动服务器端连接。

  • ByteBuf:表示一个字节缓冲区,用于读取和写入数据。

  • Codec:表示一个编解码器,用于将数据转换为字节流或消息对象。

  • Future:表示一个异步操作的结果,可以用于获取操作结果或添加回调函数。

  • Promise:表示一个异步操作的结果,可以用于设置操作结果或添加回调函数。

  • ChannelPipeline:表示一个处理器链,用于将多个处理器组合成一个处理器。

  • ChannelHandlerContext:表示一个处理器上下文,用于获取当前处理器的信息和操作。

  • ChannelFuture:表示一个异步操作的结果,可以用于获取操作结果或添加回调函数。

  • ChannelFutureListener:表示一个异步操作的回调函数,用于处理操作结果。

  • ChannelOption:表示一个通道选项,用于设置通道的参数。

  • ChannelConfig:表示一个通道配置,用于设置通道的参数。

  • ChannelInboundHandlerAdapter:表示一个入站处理器适配器,用于处理入站事件和数据。

  • ChannelOutboundHandlerAdapter:表示一个出站处理器适配器,用于处理出站事件和数据。

  • ChannelDuplexHandler:表示一个双向处理器,用于处理入站和出站事件和数据。

  • ChannelInitializer:表示一个通道初始化器,用于初始化通道的处理器链。

  • ChannelPromise:表示一个异步操作的结果,可以用于设置操作结果或添加回调函数。

  • NioEventLoopGroup:表示一个NIO事件循环组,用于处理NIO事件。

  • EpollEventLoopGroup:表示一个Epoll事件循环组,用于处理Epoll事件。

  • DefaultEventExecutorGroup:表示一个默认的事件执行器组,用于执行事件处理器。

  • DefaultChannelGroup:表示一个默认的通道组,用于管理通道。

  • DefaultChannelHandlerContext:表示一个默认的通道处理器上下文,用于获取当前处理器的信息和操作。

  • DefaultChannelPipeline:表示一个默认的通道处理器链,用于将多个处理器组合成一个处理器。

  • EmbeddedChannel:表示一个嵌入式通道,用于测试通道处理器。

  • AttributeKey:表示一个属性键,用于设置通道的属性。

  • Attribute:表示一个通道属性,用于设置和获取通道的属性。

  • SslContext:表示一个SSL上下文,用于加密和解密数据。

 🍍流程讲解:

🍍上面NettyServerHandler中的方法是由Netty的事件循环(EventLoop)触发调用的。

在Netty中,事件循环是一个线程,它负责监听所有的I/O事件,包括连接事件、读写事件、异常事件等等。当有事件发生时,事件循环会将该事件封装成一个Netty的事件对象,并将该事件分配给事件循环中的一个线程去处理。

具体来说,在Netty服务端接收到客户端发送的消息时,Netty会将这个事件封装成一个ChannelReadEvent事件对象,然后将该事件对象分配到事件循环中的一个线程去处理。在事件循环中,事件对象会被传递给处理链(Pipeline),然后经过各个组件的处理,直到到达业务处理器(就是我们定义的ServerHandler)。

当业务处理器接收到事件对象时,业务处理器会根据事件对象的类型以及业务逻辑的需要,调用相应的方法进行处理。例如,在NettyServerHandler中,我们重写了channelRead方法,用于处理客户端发送的消息。当一个ChannelReadEvent事件对象传递到ServerHandler时,Netty会自动调用channelRead方法,并将接收到的消息作为参数传递给该方法,业务处理器可以在该方法中对消息进行处理,然后将处理结果发送给客户端。

综上所述,ServerHandler中的方法是由Netty的事件循环触发调用的,当服务端接收到客户端发送的消息时,Netty会将该事件封装成一个事件对象,并将该事件对象分配到事件循环中的一个线程去处理,事件对象会经过处理链中的各个组件进行加工处理,最终到达业务处理器中,业务处理器根据消息的内容进行处理,并将处理结果返回给客户端。


🍍Netty的事件循环(EventLoop)是通过NIO Selector实现的。

在Java NIO中,Selector是一个多路复用器,它可以同时监控多个通道的IO事件。当一个通道发生IO事件时,Selector会将该事件加入到事件集合中,并通知事件循环处理器处理这些事件。

在Netty中,事件循环是一个线程,它负责处理事件和数据,并将它们传递给事件处理器进行处理。事件循环会不断地从事件队列中取出事件,并将事件传递给事件处理器进行处理。

Netty的事件循环模型是基于NIO Selector实现的。当Netty启动一个服务端或客户端时,它会创建一个或多个事件循环组(EventLoopGroup),每个事件循环组包含一个或多个事件循环(EventLoop)。

每个事件循环都会创建一个NIO Selector,并在事件循环线程中不断地轮询Selector,以便处理通道的IO事件。当一个通道发生IO事件时,Selector会将该事件加入到事件集合中,并通知事件循环处理器处理这些事件。

事件循环会将事件封装成事件对象,并将事件对象放入事件队列中。事件处理器会从事件队列中取出事件,并进行处理。当事件处理器处理完一个事件后,它会将处理结果返回给事件循环,事件循环会将处理结果发送给客户端或服务端。

因此,Netty的事件循环(EventLoop)是通过NIO Selector实现的。事件循环会不断地轮询Selector,以便处理通道的IO事件,并将事件封装成事件对象放入事件队列中。事件处理器会从事件队列中取出事件,并进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是汤圆丫

怎么 给1分?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值