分享

netty菜鸟成长记——(1)

本帖最后由 helianthus 于 2016-11-27 21:23 编辑
问题导读:
1.netty是什么?强大在哪里?适用于什么场合?
2.netty组织架构
3.netty的helloworld



1.netty介绍
    关于Netty的介绍,最权威的解释可以去其官网查看(http://netty.io/);netty是一款基于NIO(non-blocking IO)的开源的客户端/服务端编程框架,提供了事件驱动的、异步的网络应用程序框架,面对用户提供了丰富易用的的用户API接口,借助netty能够快速开发高性能、高可靠的网络服务C/S。
2.netty的优势
     底层消息通信框架除了netty,还有RabbitMQ、zeroMQ等,用过apache storm的人都知道,在storm早期版本中,其底层网络通信框架采用的是zeroMQ,但由于RabbitMQ、zeroMQ无论在易用性、性能等方面比起netty都略逊一筹,因此storm后来在官网宣布其底层消息框架采用netty。
    借鉴国内以为大牛总结的netty优势,主要如下:
    • API使用简单,开发门槛低;
    • 功能强大,预置了多种编解码功能,支持多种主流协议;
    • 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展;
    • 性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优;
    • 成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;
    • 社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;
    • 经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它已经完全
能够满足不同行业的商业应用了。
3.netty的应用场景
    在目前火的一塌糊涂的大数据以及微服务架构等领域中,其底层都是多借点多进程之间的通信,考虑到整个系统的稳定性、灵活性、高性能等,底层通信框架就必须要考虑采用稳定且高效的分布式通信框架。那么,netty将是目前的首选方案。Netty的稳定性和高性能已经在众多优秀的开源分布式项目中作为底层通信框架得到肯定,比如spark、storm、akka等。
4.netty框架
下载1.jpg
    上图是netty官方发布的架构总览图。关于对其解读目前可以参考http://www.cnblogs.com/Irving/p/5709130.html这篇文档,对架构有初步的认识。
5.helloworld分析
    前提工作——在netty官网首页的download标签选择下载netty-4.1.6.Final.tar.bz2,其中包含了源码、编译类库和Java Doc。由于作为第三方的开发者,只需要依赖其中的二进制jar包就OK
(1)服务端
      基于netty框架创建服务端时,使用期辅助类ServerBootstrap,它提供了一系列的方法用于设置服务端启动相关的参数。在netty官网上发布的example很多(https://github.com/netty/netty/tree/4.1/example),以后可以慢慢看。
      初次学习,先分析并尝试调试一个例子,来自https://my.oschina.net/zhdkn/blog/541670,功能是在客户端发送一串字符串时,服务端接收到之后返回当前服务端时间
public class TimeServer {
    public void bind(int port) throws  Exception{
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap b = new ServerBootstrap();
        try {
            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 ch) throws Exception {
            ch.pipeline().addLast(new TimeServerHandler());
            System.out.println("server add time server handler");
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        new TimeServer().bind(port);
    }
}
代码分析:
1》首先创建两个EventLoopGroup(并不是必须要创建两个不同的EventLoopGroup,也可以只创建一个并共享),然后通过构造函数创建ServerBootstrap 实例。
2》NioEventLoopGroup 实际就是Reactor 线程池, 负责调度和执行客户端的接入、网络读写事件的处理、用户自定义任务和定时任务的执行。通过
ServerBootstrap 的group 方法将线程组和线程类型两个EventLoopGroup 实例传入
3》接着需要设置服务端Channel,Netty 通过Channel 工厂类来创建不同类型的Channel,对于服务端, 需要创建NioServerSocketChannel
4》指定NioServerSocketChannel 后,需要设置TCP 的一些参数,作为服务端,主要是要设置TCP 的 backlog 参数
5》然后,为启动辅助类指定Handler,此处的Hanlder 是NioServerSocketChannel 对应的ChannelPipeline 的Handler
6》“f.channel().closeFuture().sync()”用于服务阻塞,等待服务器链路关闭之后main函数才退出。
7》服务端启动的最后一步,就是绑定本地端口,启动服务,在服务端类的主方法main()中可以看到
(2)客户端
public class TimeClient {
    public void connect(int port,String host) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        try {
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new TimeClientHandler());
                            System.out.println("client add time client handler");
                        }
                    });
            //发起异步连接操作
            ChannelFuture f = b.connect(host,port).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws Exception {
        int port = 8080;
        new TimeClient().connect(port,"127.0.0.1");
    }
}
代码分析:
1》创建客户端处理I/O读写的NioEventLoopGroup线程组
2》用户线程创建Bootstrap 实例,类似ServerBootstrap, 客户端也使用Builder 模式来构造。通过API 设置创建客户端相关的参数,异步发起客户端连接
3》通过Bootstrap 的ChannelFactory 和用户指定的Channel 类型创建用于客户端连接的NioSocketChannel
4》创建默认的Channel Handler Pipeline,用于调度和执行网络事件。不过此处仅是设置handler,并没有创建实际的handler对象,当initChannel 方法被执行时才创建业务Handler
5》异步发起TCP 连接,判断连接是否成功,如果成功,则直接将NioSocketChannel 注册到多路复用器上,监听读操作位,用于数据报读取和消息发送;如果没有立即连接成功,则注册连接监听位到多路复用器,等待连接结果
6》执行connect() 操作后有三种结果:
①连接成功,返回True;
②暂时没有连接上,服务端没有返回ACK应答,连接结果不确定,返回False;
③连接失败,直接抛出I/O异常

没找到任何评论,期待你打破沉寂

关闭

推荐上一条 /2 下一条