博客
关于我
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学习总结(2)——Netty的高性能架构之道
    查看>>
    Netty学习总结(3)——Netty百万级推送服务
    查看>>
    Netty学习总结(4)——图解Netty之Pipeline、channel、Context之间的数据流向
    查看>>
    Netty学习总结(5)——Netty之TCP粘包/拆包问题的解决之道
    查看>>
    Netty学习总结(6)——Netty使用注意事项
    查看>>
    Netty实现Http服务器
    查看>>
    Netty客户端断线重连实现及问题思考
    查看>>
    Netty工作笔记0001---Netty介绍
    查看>>
    Netty工作笔记0002---Netty的应用场景
    查看>>
    Netty工作笔记0003---IO模型-BIO-Java原生IO
    查看>>
    Netty工作笔记0004---BIO简介,介绍说明
    查看>>
    Netty工作笔记0005---NIO介绍说明
    查看>>
    Netty工作笔记0006---NIO的Buffer说明
    查看>>
    Netty工作笔记0007---NIO的三大核心组件关系
    查看>>
    Netty工作笔记0008---NIO的Buffer的机制及子类
    查看>>
    Netty工作笔记0009---Channel基本介绍
    查看>>
    Netty工作笔记0010---Channel应用案例1
    查看>>
    Netty工作笔记0011---Channel应用案例2
    查看>>
    Netty工作笔记0012---Channel应用案例3
    查看>>
    Netty工作笔记0013---Channel应用案例4Copy图片
    查看>>