0
点赞
收藏
分享

微信扫一扫

Netty了解与入门

天行五煞 2023-03-30 阅读 117

Netty了解与入门

什么是Netty?

Netty是一个基于NIO(Non-blocking IO)的网络应用框架,其目的是帮助开发人员快速而简单地开发高性能、可扩展性好的网络应用程序。Netty提供了简单而强大的抽象,使得开发人员可以专注于业务逻辑的实现,而不用关心网络通信细节和复杂度。

Netty的核心设计思想是通过线程池和事件驱动实现高效、低延迟的网络通信,同时还提供了一些高级功能,如内存池、零拷贝、压缩解压等,从而大大提升了网络应用的性能和可维护性。Netty广泛应用于服务器框架、游戏服务器、通信协议、分布式系统等领域。

为什么要使用Netty?

  1. 高性能:Netty通过使用非阻塞IO和事件驱动,避免了传统的阻塞IO的额外线程和上下文切换,从而提高了吞吐量和响应性能。此外,Netty还包括高级特性,例如,零拷贝、内存池和压缩等,使其性能更加卓越。
  2. 易于使用:Netty提供简单的API和易于使用的抽象,使开发者可以更加专注于应用程序的逻辑,而无需担心底层的网络细节。
  3. 可重用组件:Netty包括许多经过充分测试和验证的可复用组件,这使得开发者能够更便捷地构建网络应用程序。
  4. 可扩展性:Netty允许开发者将自定义组件集成到应用程序中,以满足不同的业务需求和应用场景。
  5. 跨平台支持:Netty支持跨各种操作系统和设备的网络应用程序开发。
  6. 社区活跃:Netty具有充满活力的开源开发社区,开发者可以通过获取技术支持、解决问题等方式获得帮助。

Netty的特性与组件

Netty的特性和重要组件及其作用的简要介绍:

  1. 异步和事件驱动模型:Netty基于NIO线程模型,采用异步和事件驱动的方式处理请求和响应,可以提升系统的吞吐量和并发性能。
  2. Channel:Channel是Netty网络通信的基本单位,它们负责数据的读取和写入,以及事件的处理和传递。
  3. EventLoop和EventLoopGroup:EventLoop是Netty中核心的I/O线程,负责处理任务。一个 EventLoopGroup 包含一个或多个 EventLoop。EventLoopGroup 用于管理 EventLoop 的创建和维护。
  4. ChannelPipeline 和 ChannelHandler:ChannelPipeline 是 Netty 中处理事件的链式结构,每个 ChannelHandler 负责处理 Pipeline 中的特定事件,如连接建立、数据读写、连接关闭等。
  5. ByteBuf:Netty 自己实现的动态可扩展字节容器,支持高效的读写和引用计数机制。
  6. Bootstrap 和 ServerBootstrap:Client端使用 Bootstrap 来连接一个服务器,Server端使用 ServerBootstrap 来启动服务。

以上是Netty的一些重要组件,下面是服务端示例中这些组件的用法:

  1. 我们使用 NioEventLoopGroup 创建两个 EventLoop,一个用于处理连接,一个用于处理读写操作。
  2. 我们使用 ServerBootstrap 来启动服务,并设置一系列的参数,如通道类型、父 EventLoopGroup、子 EventLoopGroup、TCP 参数等。
  3. 我们实现了一个 SimpleChannelInboundHandler 用于处理从客户端来的请求。
  4. 在 ChannelPipeline 中添加了一个 StringDecoder 和 StringEncoder 用于处理半包和消息的编解码。
  5. 在前面的聊天记录中,我还提到了 ChannelFuture、ChannelHandlerContext、ByteBufAllocator 等组件,它们分别用于异步操作的结果处理、事件处理上下文的传递、内存分配等。

以上就是 Netty 的一些重要组件和特性,通过这些组件和特性,Netty 可以提供高性能的网络通信基础设施,帮助开发者高效地构建各种高性能应用。

Hello World!

HelloWorldServer 创建一个简单的服务端

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
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 static void main(String[] args) throws Exception {
        new HelloWorldServer(8888).run();
    }

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new HelloWorldServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            System.out.println("HelloWorldServer is listening on " + port);

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

            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    private class HelloWorldServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelActive(final ChannelHandlerContext ctx) {
            final ByteBuf buf = ctx.alloc().buffer(4);
            buf.writeBytes("Hello World!".getBytes());
            final ChannelFuture f = ctx.writeAndFlush(buf);
            f.addListener(ChannelFutureListener.CLOSE);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

HelloWorldServer 创建一个简单的客户端

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
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 static void main(String[] args) throws Exception {
        new HelloWorldServer(8888).run();
    }

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new HelloWorldServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            System.out.println("HelloWorldServer is listening on " + port);

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

            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    private class HelloWorldServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelActive(final ChannelHandlerContext ctx) {
            final ByteBuf buf = ctx.alloc().buffer(4);
            buf.writeBytes("Hello World!".getBytes());
            final ChannelFuture f = ctx.writeAndFlush(buf);
            f.addListener(ChannelFutureListener.CLOSE);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

举报

相关推荐

0 条评论