作者:empty 出版社:empty |
Netty是一个异步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务器和客户端, Netty是于nio的, 它封装了jdk的nio, 让我们加方法灵活.2.Netty的特点是什么?·高并发:Netty是一款基于NIO(Nonblocking IO, 非塞IO) 开发的网络通信框架, 对比于BIO(Blocking I/O, 阻lO) , 他的并发性能得·传输快:Netty的传输依于零拷贝特性, 尽量减少不必要的内存拷贝, 实现了更高效率的传输,·封装好:Netty封装了NIO操作的很多细节, 提供了易于使用词用接,3.Netty的优势有哪些?·使用简单:封装了NIO的很多细节, 使用更简单,·功能强大:预置了多种编解码功能,支持多种主流协议,·定制能力强:可以通过Channel Handler对通信框架进行灵活地扩展,·性能高:通过与其他业界主流的NIO框架对比, Netty的综合性能最优,·稳定; Netty修复了已经发现的所有NIO的bug, 让开发人员可以专注于业务本身,·社区活跃:Netty是活沃的开源项目, 版本迭代用期短, bug修复速度快.4.Netty的应用场景有哪些?典型的应用有:阿里分布式服务框架Dubbo, 默认使用Netty作为基础通信组件, 还有Rocket MQ也是使用Netty作为通讯的基础,5.Netty高性能表现在哪些方面?·1O线程模型:同步非阻塞,用最少的资源做更多的事,·内存零拷贝:尽量减少不必要的内存拷贝,实现了更高效率的传输,·内存油设计;申请的内存可以重用,主要指直接内存,内部实现是用一颗二叉查找树管理内存分配情况,
·申形化处理读写:避免使用锁带来的性能开销.·高性能序列化协议:支持proto buf等高性能序列化协议,6.BIO、NIO和AIO的区别?BIO:一个连接一个线程, 客户端有连接请求时服务器端就需要启动一个线程进行处理, 线程开销大,伪异步IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源,NIO:一个请求一个线程, 但客户健发送的连接请求都会注册到多路复用器上, 多路复用器轮询到连接有I/O请求时才启动一个线程进行处理.AIO:一个有效请求一个线程, 客户媒的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理BIO是面向流的, NIO是面向缓冲区的; BIO的各种流是阻塞的, 而NIO是非阻塞的; BIO的Stream是单向的, 而NIO的channel是双向的,NIO的特点:事件驱动模型、单线程处理多任务, 非阻塞I/O, 1/O读写不再塞, 而是退回0.基于block的传输比基于流的传输更高效、更高级的Iogcopy、IO多路复用大大提高了Java网络应用的可性性和实用性, 基于Reactor线程模型,在Reactor模式中, 事性分发器等特某个事性或者可应用或个操作的状态发生, 事件分发器就把这个事件传给事先注册的事件处理函数或者回调函数,际的读写操作, 如在Reactor中实现读:注册读就结事件和相应的事性处理器、事性分发器等待事件、事件到来, 激活分发器, 分发器调用事件对应的处理器完成实际的读操作,处理读到的数据,注册新的事件,然后还控制权,7.NIO的组成?Buffer:与Channel进行交互, 数据是从Channel读入缓冲区, 从缓冲区写入Channel中的fip方法:反转此凌冲区, 将position绘limit, 然后将position置为D, 其实就是切换读写模式clear方法:清除北冲区, 将position置为0, 把capacity的值给limit,rewind方法:重境此缓冲区, 将post n置为DDirect ByteBuffer可减少一次系统空间到用户空间的拷贝, 但Buffer创建和的毁的成本更高, 不可控, 遇常会用内存池来提高性能, 直接冲区主要分基础系统的本机/O操作影车的大型, 持久的吸冲区, 如果数据比较小的中小应用情况下, 可以考虑使用heap Buffer, 由JVM进行管理,Channel表示IO源与目标打开的连接, 是双向的, 但不能直接访问数据, 只能与Buffer进行交互, 通过源码可知, File Channel的read方法和write据复制了两次!Selector可便一个单独的线程管理多个Channel, open方法可创建Selector, register方法向多路复用器器注册通道, 可以监听的事件类型:读, 写、accept, 注册事件后会产生一个Selection Key:它表示Selectable Channel和Selector之间的注册关系, wakeup方法:使尚未回的第一个选择操唤醒的因是:注册了新的channel或者事件; channel关闭, 取消注册; 优先级更高的事件触发(如定时墨事件) , 希望及时处理,Selector在Linux的实现类是EP all Selector impl, 委托给EPoll Array Wrapper实现, 其中三个native方法是对epoll的封装, 而EPoll Selector l mpl.imp法, 通过调用epoll_ctl向epoll实例中注册事件, 还将注册的文件描述符(fd) 与Selection Key的对应关系添加到fd To Key中, 这个map维护了文件描述Selection Key的映时,fd To Key有时会变得非常大, 因为注册到Selector上的Channel非常多(百万连接) :过期或失效的Channel没有及时关闭, fd To Key总是串行读取的select方法中进行的, 该方法是非线程安全的.Pipe:两个线程之间的单向数据连接, 数据会被写到sink通道, 从source通道读取NIO的服务线建立过程:Selector open 0:打开一个Selector; ServerSocket ChanneL.open) :创建服务端的Channel; bind(:绑定到某个姚上,塞模式:register() 注册Channel和关注的事件到Selector上; select o轮询拿到已经就的事件8.Netty的线程模型?Netty通过Reactor模型基于多路复用器接收井处理用户请求, 内部实现了两个线程池, boss h程池和work线程池, 其中boss线程池的线程负责处理证事件, 当接收到accept事件的请求时, 把对应的socket封装到一个Nio Socket Channel中, 并交给work线醒池, 其中work线程池负责请求的read和w对应的Handler处理,单线程模型:所有I/O操作都由一个线程完成, 即多路复用、事性分发和处理都是在一个Reactor线程上完成的, 既要接收客户端的连接请求, 向服务端;要发送/读取请求威应答/明应消息, 一个NIO线程时处理成百上千的链路, 性能上无法支撑, 速度慢, 若线程进入死档环, 整个程序不可用, 对于准发的应用场景不合适,多线程模型:有一个NIO线程(Acceptor} 只负责监听图务端, 接收客户端的TCP连接请求, NIO线程池负责网络IO的操作, 即消息的读取, 解码送:1个NIO线程可以同时处理N条链, 但是1个链路只对应1个NIO线程, 这是为了防止发生并发操作问, 但在并发百万客户端连接或需要安全个Acceptor线程可能会存在性能不足问题,https:thinkwon.blog.cednneVarticle/detais/1043910813/21Evagee5i92sVarning:ThedocumentwascrealqshnyhSpi2e205shuc, NFb_Think Won的博客-C SDN博客主从多线程模型:Acceptor线程用于绑定监听端, 接收客户端连接, 将Socket Channel从主线程池的Reactor线程的多路复用器上移除, 重新注池的线程上, 用于处理I/O的读与等操作, 从而保证main Reactor只负责接入认证、握手等操作:9.TCP粘包/拆包的原因及解决方法?TCP是以流的方式来处理数据, 一个完整的包可能会被TCP拆分成多个包进行发送, 也可能把小的封装成一个大的数挺包发送,TCP粘包/分包的原因:应用程序写入的字节大小大于套接字发送缓冲区的大小,会发生拆包现象,而应用程序写入数据小于套接字缓冲区大小,同卡将应用多次巧入的数据发这将会发生粘包现象,进行MSS大小的TCP分段, 当TCP报文长度-TCP头部长度>MSS的时候将发生拆包以太网顿的payload(净荷) 大于MTU(1500字节) 进行ip分片,解决方法消息定长:Fixed Length Frame Decoder类包尾增加特殊字符分:·行分隔符类:Line Based Frame Decoder·或自定义分隔符类:Delimiter Based Frame Decoder将消息分为消思头和消思体, Length Field Based Frame Decoder莞, 分为有头部的拆包与粘包.长度字段在煎且有头部的拆包与粘包、多扩展头部的10.什么是Netty的零拷贝?Netty的零拷贝主要包含三个方面·Netty的接收和发送ByteBuffer采用DIRECT BUFFERS, 使用堆外直接内存进行Socket读写, 不需要进行字节缓冲区的二次拷贝, 如果使用传(HEAP BUFFERS) 进行Sack et读写, JVM会将堆内存Buffer拷贝一份到直接内存中, 然后才写入Socket中, 相比于堆外直接内存, 消息在了一次缓冲区的内存拷贝,·Netty提供了组合Buffer对象, 可以聚合多个ByteBuffer对象, 用户可以像操作一个Buffer那样方便的对组合Buffer进行操作, 避免了传统方式将几个小Buffer合并成一个大的Buffer,·Netty的文件传拍采用了transfer To方法, 它可以直接将文件想冲区的数据发送到目标Channel, 避免了传统通过循环wrte方式导数的内存拷.11.Netty中有哪种重要组件?·Channel:Netty网络操作抽象类,它除了包括基本的I/O操作:如bind,connect.read、write等,·Event La ap:主要是配合Channel处理I/O操作, 用来处理连接的生命周期中所发生的事情,·ChannelFuture:Netty框架中所有的I/O操作都为异步的, 因此我们需要Channel Future的addListener o注册一个Channel Future Listener|操作执行成功或者失败时,监听就会目动发返回结果.·Channel Handler.充当了所有处理入站和出站数挺的逻辑容器, Channel Handler主要用来处理各种事件, 这里的事件很广泛, 比如可以是连接异常、数据转换等.·Channel Pipeline:为Channel Handler链提供了容器, 当channel创建时, 会被自动分配到它专属的Channel Pipeline, 这个关联是永久性A12.Netty发送消息有几种方式?Netty有两种发送源息的方式·直接写入Channel中, 消息从Channel Pipeline当中尾部开始移动,·写入和Channel Handler绑定的Channel Hander Context中, 满息从Channel Pipe ne中的下一个Channe Handler中移动.13.默认情况Netty起多少线程?何时启动?Netty默认是CPU处理器数的满倍, bind