博客
关于我
Netty入门使用
阅读量:791 次
发布时间:2023-02-14

本文共 5190 字,大约阅读时间需要 17 分钟。

Netty 是一个高性能、异步事件驱动的 NIO 框架,基于 Java NIO 提供的 API 实现,封装了 NIO 中的一些难以使用和 bug。Netty 提供了简单易用的 API,能够快速开发可维护的高性能协议服务器和客户端,同时修复了 JDK NIO 中已知的 bug。

Netty 的优势

  • API 使用简单:Netty 提供了简洁易用的 API,开发门槛低。
  • 功能强大:预置了多种编解码器,支持主流协议开发。
  • 定制能力强:通过 ChannelHandler 可以灵活扩展通信框架。
  • 性能优越:综合性能优于其他主流 NIO 框架。
  • 成熟稳定:修复了所有已知的 JDK NIO BUG,开发过程中无需担心 NIO 的问题。
  • 社区活跃:版本迭代频繁,问题快速修复,新功能不断加入。
  • 实战验证:经历了大规模商业应用验证,质量经过测试,Dubbo、Elasticsearch 等项目选择了 Netty。
  • 为什么选择 Netty 而不是 AIO?

    Netty 在 Linux 上的性能优于 AIO,因为 AIO 的底层实现仍依赖 EPOLL,缺乏优势。AIO 接收数据需要预先分配缓存,可能导致内存浪费。此外,AIO 处理回调结果速度较慢,难以满足高并发需求。Netty 作者原话:“Not faster than NIO (epoll) on unix systems (which is true) There is no daragram suppport Unnecessary threading model (too much abstraction without usage)”

    Netty 的架构

    Netty 采用事件驱动架构,核心组件包括:

  • EventLoopGroup:管理多个事件循环组,负责处理 I/O 事件。
  • Channel:表示网络连接,接收读写事件。
  • Pipeline:处理数据流,包含编码器、解码器等。
  • Handler:处理事件,扩展通信逻辑。
  • Hello Netty 实例

    服务端

  • 创建服务端启动类
  • public class MyServer {    private int port;    public MyServer(int port) {        this.port = port;    }    public static void main(String[] args) throws InterruptedException {        MyServer myServer = new MyServer(19091);        System.out.println("服务器即将启动");        myServer.start();        System.out.println("服务器已关闭");    }    private void start() throws InterruptedException {        NioEventLoopGroup bossGroup = new NioEventLoopGroup();        try {            ServerBootstrap bootstrap = new ServerBootstrap();            bootstrap.group(bossGroup)                    .channel(NioServerSocketChannel.class)                    .localAddress(new InetSocketAddress(port))                    .childHandler(new ChannelInitializer<>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new MyServerHandler());                        }                    });            System.out.println("MyServer 服务端已经准备就绯...");            ChannelFuture channelFuture = bootstrap.bind().sync();            System.out.println("服务器启动完成");            channelFuture.channel().closeFuture().sync();        } finally {            bossGroup.shutdownGracefully().sync();        }    }}
    1. 服务端处理器
    2. public class MyServerHandler extends ChannelInboundHandlerAdapter {    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("MyServerHandler 连接已建立...");        super.channelActive(ctx);    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf in = (ByteBuf) msg;        System.out.println("Server Accept Client Context (" + ctx.channel().remoteAddress() + ")消息 - " + in.toString(CharsetUtil.UTF_8));        ctx.writeAndFlush(in);    }    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        ByteBuf byteBuf = Unpooled.copiedBuffer("Server Receive Client msg", CharsetUtil.UTF_8);        ctx.writeAndFlush(byteBuf);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        ctx.close();    }}

      客户端

    3. 创建客户端启动类
    4. public class MyClient {    private String host;    private int port;    public MyClient(String host, int port) {        this.host = host;        this.port = port;    }    public static void main(String[] args) throws InterruptedException {        MyClient myClient = new MyClient("127.0.0.1", 19091);        System.out.println("客户端即将启动");        myClient.start();        System.out.println("客户端已关闭");    }    private void start() throws InterruptedException {        NioEventLoopGroup bossGroup = new NioEventLoopGroup();        try {            Bootstrap bootstrap = new Bootstrap();            bootstrap.group(bossGroup)                    .channel(NioSocketChannel.class)                    .remoteAddress(new InetSocketAddress(host, port))                    .handler(new ChannelInitializer<>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new MyClientHandler());                        }                    });            System.out.println("客户端准备就绯,随时可以连接服务端");            ChannelFuture channelFuture = bootstrap.connect().sync();            System.out.println("客户端启动连接完成");            channelFuture.channel().closeFuture().sync();        } finally {            bossGroup.shutdownGracefully().sync();        }    }}
      1. 客户端处理器
      2. public class MyClientHandler extends SimpleChannelInboundHandler {    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        ByteBuf byteBuf = Unpooled.copiedBuffer(" Hello, Netty", CharsetUtil.UTF_8);        ctx.writeAndFlush(byteBuf);    }    @Override    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf in = (ByteBuf) msg;        System.out.println("Client Accept Server (" + ctx.channel().remoteAddress() + ")消息 - " + in.toString(CharsetUtil.UTF_8));    }}

        测试结果

        服务端启动时会输出:

        MyServer 服务端已经准备就绯...服务器启动完成

        客户端启动时会输出:

        客户端准备就绯,随时可以连接服务端客户端启动连接完成

        通过以上示例,可以看到 Netty 的使用流程,完成了一个简单的客户端与服务端通信。更多 Netty 功能可以参考官方文档深入学习。

    转载地址:http://hccfk.baihongyu.com/

    你可能感兴趣的文章
    Netty 调用,效率这么低还用啥?
    查看>>
    Netty 高性能架构设计
    查看>>
    Netty+Protostuff实现单机压测秒级接收35万个对象实践经验分享
    查看>>
    Netty+SpringBoot+FastDFS+Html5实现聊天App详解(一)
    查看>>
    netty--helloword程序
    查看>>
    netty2---服务端和客户端
    查看>>
    【Flink】Flink 2023 Flink易用性和稳定性在Shopee的优化-视频笔记
    查看>>
    Netty5.x 和3.x、4.x的区别及注意事项(官方翻译)
    查看>>
    netty——bytebuf的创建、内存分配与池化、组成、扩容规则、写入读取、内存回收、零拷贝
    查看>>
    netty——Channl的常用方法、ChannelFuture、CloseFuture
    查看>>
    netty——EventLoop概念、处理普通任务定时任务、处理io事件、EventLoopGroup
    查看>>
    netty——Future和Promise的使用 线程间的通信
    查看>>
    netty——Handler和pipeline
    查看>>
    Vue输出HTML
    查看>>
    netty——黏包半包的解决方案、滑动窗口的概念
    查看>>
    Netty中Http客户端、服务端的编解码器
    查看>>
    Netty中使用WebSocket实现服务端与客户端的长连接通信发送消息
    查看>>
    Netty中实现多客户端连接与通信-以实现聊天室群聊功能为例(附代码下载)
    查看>>
    Netty中的组件是怎么交互的?
    查看>>
    Netty中集成Protobuf实现Java对象数据传递
    查看>>