• Netty 简介


    上文我们介绍了NIO和BIO的区别,NIO相对于BIO是一次很大的进步。但我们平时开发中并不会使用NIO。这是因为NIO在开发中存在以下问题

    NIO的类库和API繁杂,使用麻烦,需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等,这就像我们会使用Hibernate、MyBatis这些ORM框架而不会直接使用Connection、Statement一样
    需要其他额外技能作为铺垫,必须对多线程和网络编程非常熟悉才能写出高质量的NIO程序
    可靠性能力补齐,工作量和难度都非常大,例如客户端面临断线重连、网络闪断、半包读写、失败缓存、网络拥塞、异常码流等问题的处理
    JDK NIO的BUG,例如著名的epoll bug,该问题会导致Selector空轮训,最终导致CPU 100%

    所以开发出一个健壮的NIO程序并不容易,真正使用中,我们更推荐使用Netty,Mina这些NIO框架。相比较而言,Netty有以下优点

    API使用简单、开发门槛低
    功能强大,预置了多种编码解码功能,支持多种主流协议
    定制能力强,可以通过ChannelHandler对通信框架进行灵活扩展
    性能高,与业界其他主流NIO框架对比,Netty性能最优
    成熟、稳定,Netty修复了已经发现的所有JDK NIO的BUG,业务开发人员不需要再为NIO的BUG而烦恼
    社区活跃、版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会被加入
    经历了大规模的商业应用考验,质量得到验证。

    下面我们先看下,netty是如何运用的呢

    服务端

    public void bind(int port) throws Exception {
            // 配置服务端的NIO线程组
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_BACKLOG, 1024)
                        .childHandler(new ChildChannelHandler());
                // 绑定端口,同步等待成功
                ChannelFuture f = b.bind(port).sync();
    
                // 等待服务端监听端口关闭
                f.channel().closeFuture().sync();
            } finally {
                // 优雅退出,释放线程池资源
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    
        private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
            @Override
            protected void initChannel(SocketChannel arg0) throws Exception {
                arg0.pipeline().addLast(new TimeServerHandler());
            }
        }

    客户端

    public void connect(int port, String host) throws Exception {
            // 配置客户端NIO线程组
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group).channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch)
                                    throws Exception {
                                ch.pipeline().addLast(new TimeClientHandler());
                            }
                        });
                // 发起异步连接操作
                ChannelFuture f = b.connect(host, port).sync();
                // 当代客户端链路关闭
                f.channel().closeFuture().sync();
            } finally {
                // 优雅退出,释放NIO线程组
                group.shutdownGracefully();
            }
        }

    使用netty能够减少我们的代码量,减少api的使用。netty封装了nio,我们只需把业务添加到SocketChannel即可。

  • 相关阅读:
    Advanced Developer's Blog
    图片文字识别
    Unit test resources
    SpringBoot-mvn插件
    flask中使用proto3
    QTA-qtaf自动化测试实践
    AttributeError: module 'virtualenv' has no attribute 'create_environment'
    qtaf dick 报错 NameError: name 'dict_values' is not defined
    24点python实现
    mysql在win下移植
  • 原文地址:https://www.cnblogs.com/xmzJava/p/9711680.html
Copyright © 2020-2023  润新知