NIO 之netty(初级篇)

Posted 吊炸天的技术宅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NIO 之netty(初级篇)相关的知识,希望对你有一定的参考价值。

        各位技术大佬们,下午好,今天要和大家分享 新的 web 容器之netty 。不过今天之分享自己对 netty 的一些理论知识和原理。最近在看一本叫做netty 权威指南这本书。下面将基于一些常见问题而做出自己的理解



    1    netty 是什么?


                netty 是一个web容器,主要应用在 http 协议的基础上 ,它是一个强大的NIO框架。netty框架用java 写的。与tomcat 相比最大的不同其实就是BIO  和 NIO 。说到底它能给我们提供一个快速开发的便捷。不过它的常用api确实很多。大家可以记住常见的 管道(Channel)和轮询线程(Selector)原理即可。


  2  netty 底层原理及实现


                我们知道tomcat 6之前是不支持nio的 。之前的都是bio模型。也就是客户端一个请求服务开启一个线程。如果请求过多会导致线程过多服务宕机。后来改善用了线程池(ThreadPoolExecutor)可以设置最大链接数。过多的请求将会以队列的形式排队。这种方法虽然可以减轻宕机的几率,但是线程过多也会导致服务压力过大。所以后面出来了NIO,也就是一种新的 new IO  通信模式。其实NIO 也是基于底层系统来实现。常见的网络通信有五种通信模式 : 阻塞io模型 ,非阻塞io模型,io 复用模型 ,信号驱动模型,异步io 。 其中nio基于多路复用模型。

         多路复用模型 分为三种 select  poll  epoll 模型。    具体详细介绍可以去了解linux网络通信机制。 epoll 具备更多的数量和遍历活跃的连接(fd) 。基于这个。我们再来看nio的api  Channel 和Selector   可以理解为活跃的fd  和一个轮询线程。

        ServerSocketChannel servtChannel = ServerSocketChannel .open()

        Selector   selector = Selector.open()

        servtChannel .register(selector ,SelectionKey.OP_ACCEPT

       while(!stop){   //stop 为一个停止的方法

                Set<selectedKeys>   key = selector .selectedKeys()

                Iterator<SelectedKeys> it=  key.iterator()

                SelectedKeys key = null

                while(it.hasNext()){

                    key = it.next()

                         it.remove()

                        handleInput(key)        //处理SocketChannel 携带的的数据

                }

        }


     这里我们可以看到其实一个线程就可以处理轮询监听基于fd信号SocketChannel 携带的数据。关于ServerSocketChannel  和 selector 大家可以更深一步查看起源码。其实也就是封装底层操作系统的接口。


    3 netty的高效


            作为开发的童鞋们们都知道,开发一个web服务器是多么不容易,不说需要熟悉底层操作系统的原理和网络通信机制,还需要各种异常流程处理和复杂逻辑。这里我粗糙罗列了netty 一些优秀的地方:


        1, TCP 粘包/拆包


            TCP 协议是个 “流”协议,就是一种没有界限的一串数据。但是在业务上认为,一个完整的包可能会被TCP拆分多个包。也有可能是多个包封装成一个大的数据包。这就是需要在tcp协议上定义另外一种协议 来规范和约定。比如http协议请求头中规定传输的字节。又例如FTP协议中增加回车换行符进行分割。所以netty框架中就有了 LineBasedFrameDecoder 和 StringDecoder  定义换行 解码器 和分隔符解码器


        2, 序列化


           java 是面向接口编程。所以就少不了序列化对象。 java原生的序列化解码器不支持和其他语言通信,码流太低,序列化性能太低。所以需要用到业界比较主流的编解码框架 ,常见的有 Google的 Protobuf  ,Facebook 的Thrift ,JBoss Marshalling



    总结: 好了,今天的分享又要告一段落,后续的将会有中篇和下篇,将会涉及到高级篇 netty私有协议栈 开发和 netty 高性能之道。后面的将会更加精彩。因为高级篇和高性能需要深入研究底层协议和性能方面。总之一句话概括,基础是内功,框架是招式。融汇贯通得看修行。 大家学习按照这学习三部曲是没有错的。从 会用框架 到 熟悉框架原理这个过程是个成长最快的过程。


        不过从今后起,个人觉得学习的最好方式就是看书。比起看博客逛论坛书上更具系统性。学习netty 这个框架就是看书的。因为个人觉得收获很多。效率更高。


        

        

        

以上是关于NIO 之netty(初级篇)的主要内容,如果未能解决你的问题,请参考以下文章

线程之初级篇

WEB框架之---Django初级篇

学习笔记之CSRF初级篇

学习笔记之CSRF初级篇

学习笔记之CSRF初级篇

学习笔记之CSRF初级篇