6

作者: 01010100 | 来源:发表于2018-03-16 17:59 被阅读26次

    Netty:

    1、总体描述,

    应用场景Netty是一个高性能、异步事件驱动的NIO框架。封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。应用场景:首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。 高性能基础通信组件。

    2、Netty VS NIO

    1)跨平台与兼容性:NIO算是底层的APIs需依赖系统的IO APIs。但Java NIO发现在不同系统平台会出现问题。 NIO2只支持JDK1.7+,而且没提供DatagramSocket,故NIO2不支持UDP协议。 而Netty提供统一接口,同一语句无论在JDK6.X 还是JDK7.X 都可运行,无需关心底层架构功能!2)JAVA NIO的ByteBuffer构造函数私有,无法扩展。Netty提供了自己的ByteBuffer实现,通过简单APIs对其进行构造、使用和操作,一此解决NIO的一些限制。

    3)NIO对缓冲区的聚合与分散操作可能会导致内存泄漏。直到JDK1.7才解决此问题。

    4)NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。

    5)使用JAVA NIO需要具备其他的额外技能做铺垫,例如熟悉Java多线程编程。这是因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序。

    6)可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题。7)JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。3、epoll bugJDK的NIO类库有一个epoll死循环bug,它会导致Selector空轮询,IO线程CPU达到100%,严重影响系统运行。

    netty从api使用层面对该bug进行了规避解决:1)对Selector的select操作周期进行统计。每完成一次空的select操作进行一次计数。2)在某个周期内如果连续N次空轮询,则说明触发了JDK NIO的epoll死循环bug。3)创建新的Selector,将出现bug的Selector上的channel重新注册到新的Selector上。4)关闭bug的Selector,使用新的Selector进行替换。

    5、启动Demo与线程池模型

    EchoServer:

    public void run() { 

     // 创建一个ServerBootstrap启动工具类 // 构造方法里传入NioServerSocketChannelFactory 

     ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true));

     ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true)); 

     ServerBootstrap bootstrap = new ServerBootstrap( 

     //构建一个创建NioServerSocketChannel的工厂类NioServerSocketChannelFactory 

     new NioServerSocketChannelFactory( boss, worker));

     // Set up the ChannelPipelineFactory.pipeline主要负责管理channel和netty之间消息的传递 

     bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

     public ChannelPipeline getPipeline() throws Exception { 

     //传入echoServerHandler 

     return Channels.pipeline(new EchoServerHandler()); 

     } });

     // Bind and start to accept incoming connections. 

     bootstrap.bind(new InetSocketAddress(port));}

    boss pool:处理Acceptor事件,负责连接的建立,连接建立后将交由worker pool处理,默认一个线程

    worker pool:处理I/O读写事件,线程池默认大小,netty=处理器个数*2,dubbo=处理器个数 + 1

    在真正的业务中,还应该添加自己的业务线程池,而不应该把业务处理放在netty的worker pool中。

    NioEventLoopGroup:线程池

    EventLoopGroup bossGroup = new NioEventLoopGroup(1);

    EventLoopGroup workerGroup = new NioEventLoopGroup();

    ServerBootstrap b = new ServerBootstrap();

    b.group(bossGroup, workerGroup)

     .channel(NioServerSocketChannel.class) 

    .option(ChannelOption.SO_BACKLOG, 100)

     .handler(new LoggingHandler(LogLevel.INFO)) 

    .childHandler(new ChannelInitializer() { ..

    ChannelPipeline:

    ChannelPipline:包含一系列handler,如编解码handler处理器,addLast,利用事件传输机制,handler按顺序触发

    相关文章

      网友评论

        本文标题:6

        本文链接:https://www.haomeiwen.com/subject/decqqftx.html