netty

    1.tomcat和netty对比
        1.1    tomcat介绍 
        tomcat是web应用服务器,由一系列组件构成,核心组件由以下三个:
            web容器(完成web服务器的功能)
            servlet容器(名字为catalina,用于处理servlet代码)
            jsp容器(用于将jsp动态网页翻译成servlet代码)
        因此,tomcat是应用服务器,也是servlet/jsp容器,作为servlet容器,tomcat负责处理客户请求,将请求传给servlet,并将servlet的响应传回客户。
        在中小型系统和并发访问用户不是很多的场合下,tomcat被普遍使用,是开发和调试jsp的首选。
        1.2 tomcat支持的协议
        HTTP/1.1:体现在持久连接、请求和响应的处理、虚拟机主持、请求的路由和处理、错误处理和日志记录以及兼容性和向后兼容性等方面。是的tomcat作为一款可靠的web服务器,为使用
                 HTTP/1.1协议提供了良好支持
        HTTP/2.0:tomcat从8.5版本开始支持HTTP/2.0协议。该协议在传输方面进行了重要改进,包括采用二进制传输而非HTTP/1.1协议的文本格式,支持服务推送等。
                主要通过移除SPDY/2的相关功能实现,因为HTTP/2.0虽然和SPDY有所不同,但两者之间存在相似之处。
                HTTP/2.0协议中,一个基本的协议单元是帧,与TCP中的数据包概念相似。
        AJP:tomcat中,AJP协议主要用于连接apache http服务器和其他反向代理服务器,实现web服务器和servlet容器之间的通信。
            通过AJP连接器,tomcat可以与支持AJP协议的web服务器进行集成,提供更好的性能和扩展性。
        1.3 tomcat优缺点
        优点:轻量级和易部署、开源、稳定性好、支持servlet和jsp、支持多种应用(不仅可以作为web服务器运行,还可作为独立的应用服务器运行,支持多种应用和框架)
        缺点:内存占用较大(可能会影响性能)、线程数量限制(可能影响并发的性能)、
              安全性(tomcat虽采取了安全配置,但用户仍需额外的安全措施来保护自己的应用程序和数据)、需用户自行负责更新和维护    
        1.4    netty介绍
        netty是java开源框架,提供异步的、事件驱动的网络应用程序框架和工具,用来快速开发高性能、高可靠性的网络服务器和客户端程序。
        是基于NIO的客户端、服务器端的编程框架,
        使用netty可确保快速和简单开发一个网络应用,例如实现了某种协议的客户端、服务端应用。Netty相当简化和流水线化了网络应用的编程开发过程。
        例如,基于TCP和UDP的socket服务开发,快速和简单并不用产生维护性或性能上的问题。
        Netty是一个吸收了多种协议的实现经验,并经过精心设计的项目。Netty在保证易于开发的同时还保证了应用的性能,稳定性和伸缩性。
        此外,netty整合了网络编程、多线程处理和并发多个领域,极大地简化了网络开发的流程。
        netty本质上是一个NIO框架,适用于服务器通讯相关的多种应用场景。可快速和轻松的开发网络应用程序,如协议服务器和客户端。极大地简化了TCP和UDP套接字服务器等网络编程。
    
    1.5 netty支持的协议,包括但不限于
        tcp/udp:提供了基于nio的tcp和udp编程框架,可用来构建高性能、高可用的网络应用
        http/https:提供了http/https编程框架,可用来开发web服务器和客户端
        websocket:提供了websocket编程框架,可用来开发双向通信应用程序,如聊天室等
        spdy/http2:提供了spdy/http2编程框架,可用来实现高效的web应用
        mqtt/coap:提供了mqtt/coap编程框架,可用来开发iot应用
        此外,还支持各种二进制和文本协议,如ftp、smtp等。这些协议都是通过netty的channelhandler来处理的,只需要根据业务需求实现对应的channelhandler即可。
    1.6 netty优点:使用简单,开发门槛低、功能强大、定制能力强、性能高、成熟稳定
    1.7 netty和tomcat的区别:
        作用:tomcat是servlet容器,可被视为web服务器;netty是异步事件驱动的网络应用程序框架和工具,用户简化网络编程。例如tcp和udp套接字服务器
        协议:tomcat基于http协议的web服务器,netty可通过编程自定义各种协议,因为netty本身可编码和解码字节流,所以netty可实现http服务器、ftp服务器、udp服务器、
            rpc服务器、websocket服务器、redis的proxy服务器、mysql的proxy服务器等
        性能:虽然某些方面tomcat有较好的,但是netty的性能更好。
        选择tomcat还是netty,主要取决于具体需求。构建高性能、高并发的网络应用,并且需要实现自定义协议,则netty更为合适。因为netty的异步、事件驱动的设计模式更好地应对高并发场景,并且支持自定义协议,提供了更为灵活的网络编程框架。如果是构建web应用服务器,并且基于http协议的应用较多,则tomcat更为合适。因为tomcat一度是web容器的标准,并且对http层的支持更完善。
    1.8 netty和tomcat的应用场景:
        tomcat主要用于传统的web应用程序,如电子博客、商务网站等。是一个开源的web服务器,提供了一个容器来运行java应用程序,并处理http请求和响应。tomcat设计目标是提供一种简单、易用、可靠的方式来开发和部署java web应用程序
        
        netty则更适用于处理大量并发连接和高吞吐量的场景,如实时通信、游戏服务器等。netty是一个基于事件驱动的异步网络应用框架,提供了高性能、可扩展的并发能力。设计目标是提供简单、高效、可靠的方式来开发可维护的高性能服务器和客户端。
        
        相同的服务器配置下, netty的并发支持能力通常更高。
        tomcat的默认并发数是150,可通过配置提高,但受制于线程数。netty基于NIO,可处理更多的并发连接,并且不需要为每个请求创建新的线程。因此netty在处理大量并发连接时具有更好的性能和效率
    1.9 tomcat和netty来处理大量并发连接的优化
        netty优化方式:
            异步和事件驱动的设计:netty通过异步和事件驱动的设计模式,通过非阻塞IO(NIO)连接,可高效地大量处理并发连接,从而无需为每个连接创建新的线程
            连接管理和复用:使用连接池和连接复用技术来管理连接,重用已建立的连接,避免频繁创建和销毁连接的开销
            流量控制和背压机制:可根据服务器的负载情况动态调整接收和发送数据的速率,避免服务器过载
            高效的线程模型:采用多线程模型,通过合理的线程划分和调度,充分利用多核处理器的性能,提高并发处理能力
            自定义协议和编码解码器:netty支持自定义协议,并提供丰富的编解码器,可灵活地处理各种协议和数据格式,以满足不同的场景需求
            高性能的数据传输:使用了零拷贝技术和缓冲区优化,减少了数据传输过程中的内存拷贝和分配开销,提高了数据传输的效率
            监控和调优:netty提供了丰富的监控和调优手段,可以实时检测服务器的性能指标,并根据需要进行调整和优化,以保证系统的稳定性和性能。
            总结:通过异步和事件驱动的设计、流量管理和复用、流量控制、高效的线程模型、自定义协议和编解码器、高性能的数据传输、监控和调优,netty能够有效地处理大规模并发连接,并提供高性能、可扩展的网络应用服务。
        
        tomcat优化方式:
             服务器配置优化:优化服务器配置,如调整线程池大小、连接器配置等,可提高并发处理能力,可根据实际应用的需求和硬件资源来合理配置
             使用负载均衡和集群技术:通过负载均衡将请求分发至多个tomcat实例,可实现水平扩展,提高并发处理能力。同时,集群技术可将多个tomcat实例组成一个集群,共同处理请求,进一步提高并发处理能力。
             连接池和连接复用:tomcat也可使用连接池和连接复用技术来管理连接,避免频繁创建和销毁连接的开销
             异步处理和事件驱动:虽然tomcat是同步的,但可以通过异步处理和事件驱动的模式来提高并发处理能力。例如使用异步servlet或spring的异步web框架等技术
             数据库读写分离:对于数据库的读写操作,可采用读写分离的策略,将读操作和写操作分发到不同的数据库实例,减轻单点数据库的压力,提高并发处理能力。
             缓存技术:合理使用缓存,例如redis、memcached等,可减少对数据库的访问次数,减轻数据库的压力,从而提高并发处理能力
             监控和调优:通过监控tomcat的性能指标,及时发现瓶颈并调优,如调整JVM参数、优化SQL语句等
             总结:通过服务器配置优化、负载均衡和集群技术、连接池的连接复用、异步处理和事件驱动、数据库读写分离、缓存和监控调优等手段,tomcat也可以有效地支持大规模并发连接
    1.10 tomcat和netty网络模型的区别
        tomcat的网络模型主要有三种:JIO(即BIO)、NIO、NIO2(即AIO)
        JIO(Java I/O):传统的同步阻塞模型,即BIO,此模型中,IO操作是同步的,并且当数据未准备好时,线程会被阻塞。适用于连接数较少且数据量大的场景
        NIO(Non Blocking I/O):java7引入的模型,支持非阻塞的IO操作,此模型中,IO操作是异步的,当数据未准备好时,线程不会被阻塞,而是可继续执行其他任务,适用于高并发、高吞吐量的场景
        NIO2(Asynchronous I/O):JAVA7引入的另一种异步模型,也被称为AIO,与NIO相比,NIO2更简单、更轻量级,提供了基于回调的异步I/O操作。适用需要处理大量并发连接的场景
        总结:tomcat7之前,主要适用JIO模型;从tomcat7开始,支持NIO和NIO2模型;tomcat8之后,默认适用NIO模型,可根据需求选择合适的网络模型。
        
        netty的网络模型是基于非阻塞IO(NIO)的,适用了事件驱动和异步的设计模式。netty的核心组件包括channel、eventloop、channelhandler等,通过这些组件的协作,实现高效的网络通信
        netty网络模型特点:    
            事件驱动:netty的事件驱动设计使它能够高效地处理并发连接,当网络事件发生时,netty会将其封装成一个事件对象,并传递给相应的channelhandler进行处理
            异步性:netty的异步性使它不会阻塞线程等待IO操作完成,而是通过回调函数通知处理完成或错误消息,这种异步的设计使netty更够处理更多的并发连接
            内存池化:netty使用了内存池化技术,通过预先分配一定数量的bytebuf对象,避免频繁的内存和回收操作,减少了GC的次数和提供了性能。
            零拷贝:减少了数据在内存中的拷贝次数,提高了数据传输的效率,通过优化文件通道的读写操作,netty能够避免不必要的内存拷贝和数据复制
            高度可定制:提供了丰富的channelhandler接口,用户可根据需求实现自定义的channelhandler来处理网络事件,这种可定制性,使netty可适应不同的应用场景
            异步事件驱动模型:netty使用异步事件驱动模型来处理网络事件,eventloop会循环监听事件, 当事件到来时,会调用channelhandler进行处理。这种模型使得netty能够充分利用多核cpu的资源,提高处理性能
            线程模型:netty使用了多reactor模型,包括一个mainreactor和多个subreactor,mainreactor负责接收新连接,subreactor负责处理已接受的新连接。这种线程模型使得netty能够高效地处理大量并发连接。
    1.11 tomcat和netty架构设计:
        tomcat架构设计分成以下几个组成部分:
            连接器:负责处理http请求和响应的数据流,可以支持多种协议和传输方式,如HTTP、HTTPS、AJP等,连接器可配置多个,每个监听器监听不同的端口
            Web容器:负责管理web应用程序,每个应用程序都有一个context,包含了该应用程序的servler、filter、listener等组件的定义和配置.web容器还负责类加载、session管理、安全性等方面的处理。
            集群负载均衡(clustering and load balancing):tomcat支持将多个tomcat实例组成一个集群,以提高性能和可用性。集群中的tomcat实例可以通过共享session等方式进行通信,并且可通过负载均衡将请求分发到不同的tomcat实例商。
            日志和监控:tomcat提供了丰富的日志记录和监控记录,监控tomcat的监控指标和运行指标
            总结:tomcat的架构设计包括连接器、web容器、集群和负载均衡、日志和监控等部分,组件协同工作,使得tomcat能够提供高性能、可扩展的web应用服务
        
        netty架构设计:
            netty的架构设计包含以下几部分:
                通信调度层:由一系列辅助类完成,包括reactor线程(nioeventloop及其父类)niosocketchannel/nioserversocketchannel及其父类、buffer组件、unsafe组件等。主要职责是负责监听网络层的读写和连接操作,负责将网络层的数据读取到缓冲区,然后触发各种网络事件,例如创建连接、连接激活、读事件、写事件等
                责任链层:负责上述的各种网络事件在责任链中的有序传播,同时负责动态地编排责任链。责任链可选择监听和处理自己关心的事件,可以拦截处理事件,以及向前向后传播事件。
                总结;netty的设计基于NIO模型,具有异步、事件驱动的特点,可高效地处理大量并发连接。
    2.netty入门
        2.1 netty说明
            是一个NIO客户端服务器框架,使用它可以快速简单地开发网络应用程序,比如服务器端和客户端的协议。
            具体来说,netty就是对java nio的封装。nio是java1.4后引入的基于事件模型的非阻塞IO框架。
            在NIO之前,对于数据的处理都是基于BIO,BIO是以阻塞的形式对数据进行处理的,虽然处理比较简单,但是由于其阻塞操作会涉及到线程的上下文切换操作,导致BIO在并发场景下略显吃力。
            相对,NIO可以较好的应对并发场景。但是NIO推出的NIO类库和API繁杂,使用起来比较麻烦和出现BUG,因此出现了一些列解决NIO问题的框架,Netty就是其中著名的一个.
            
            netty特点:
                基于事件机制达成关注点分离(消息编解码,协议编解码,业务处理)
                可定制的线程处理模型,单线程,多线程池等
                屏蔽NIO本身的BUG
                性能上的优化
                相较于NIO接口功能更丰富
                对外提供统一的接口,底层支持NIO和BIO两种方式,可自由切换
        2.2 netty总体架构
            总体来说,netty分成两大块:核心模块和服务模块
            核心模块:主要提供netty的一些基础基类和底层接口,由三部分组成
                zero-copy-capable rich byte buffer(零拷贝缓冲区):用来提升性能,减少资源占用
                universal communication api(统一通信api):为同步和异步提供统一的编程接口
                extensible event model(易扩展的事件模型)
            服务模块:因为netty的核心是io,因此服务模块和IO操作息息相关,主要有:
                网络接口数据处理相关服务,如报文的粘包,拆包处理,数据的加密,解密等
                各网络层协议实现服务:包括传输层和应用层相关网络协议的实现
                文件处理相关服务
        2.3 netty处理结构,三层
            底层的IO复用层(reactor):负责实现多路复用
            中间层的通用数据处理层(pipeline):主要作用是对传输层的数据在进出口进行拦截并处理,比如粘包处理,编解码处理等
            顶层的应用实现层:开发者使用netty都是在这一层进行操作,同时netty本身已在这一层提供一些常用的实现,如HTTP协议,FTP协议等
            
            整体流程:数据从网络传输到IO复用层,IO服务层接收到数据后将数据传输至数据处理层进行处理,这一层会通过一系列的handler以及应用服务器对数据进行处理,
                    然后返回给IO复用层,最后通过它返回给网络
                    
        2.4 netty线程模型说明
            不同的线程模型对程序的性能有很大的影响,目前存在的线程模型有传统阻塞I/O服务模型Reactor模式
            根据Reactor的数量和处理资源池线程的数量又分为三种典型实现,分别是单Reactor线程,单Reactor多线程,主从Reactor多线程.
            netty主要基于主从Reactor多线程模型做一定的改进,其中主从Reactor多线程模型有多个Reactor
            运行流程:
                首先Reactor主线程MainReactor对象通过select监听连接事件,收到事件后,通过Acceptor处理连接事件
                Acceptor处理连接事件后,MainReactor将连接分配给SubReactor,然后SubReactor将连接加入到连接队列进行监听,并创建handler进行各种事件处理
                当有新的事件发生时,SubReactor就会调用对应的handler来处理.handler通过read来读取数据,分发给后面的worker线程处理
                worker线程池分配独立的worker线程进行业务处理,并返回结果
                hander收到响应结果后,再通过send将结果返回给client
                优点:父线程与子线程数据交互简单,职责明确,父线程只负责接收新连接,子线程完成后续的业务处理
            
            工作原理:
                netty抽象了两组线程池bossgroup和workergroup,其中bossgroup专门负责客户端的连接,workergroup专门负责网络的读写.
                bossgroup和workergroup的类型都是nioeventloopgroup.nioeventloopgroup相当于一个事件循环组,这个组中含有多个事件循环,每一个事件循环是一个nioeventloop
                nioeventloop表示一个不断执行处理任务的线程,也就是说可以含有多个nioeventloop,每个nioeventloop都有一个selector,用于监听绑定在其上的socket的网络通讯
                每个booseventgroup循环执行的步骤有3步:
                    轮询accept事件;
                    处理accept事件,与client建立连接,生成niosocketchannel,并将其注册到某个workernioeventloop上的selector;
                    处理任务队列的任务,即runalltasks;
                
                每个workernioeventgroup循环执行的步骤也有3步:轮询read,write事件;处理I/O事件,即read,write事件,在对应niosocketchannel处理;处理队列的任务runalltasks
                每个workernioeventloop处理业务时,会使用pipeline(管道),pipeline中包含了channel,也就是说通过pipeline可以获取到对应通道,管道中维护了很多的处理器.
    3.netty知识点汇总
        3.1 NIO基本概念
            阻塞(Block)和非阻塞(Non-Block):阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式
            阻塞:往往需要等待缓冲区的数据处理好之后才处理其他的事情,否则一直等在哪里
            非阻塞:进程访问数据缓冲区的时候,如果数据还未准备好,则直接返回,无需等待.如果数据已准备好,则也直接返回
            
            同步和异步:都是基于应用程序和操作系统处理IO事件所采用的方式.比如:
            同步:应用程序直接参与IO读写的操作
                同步方式在处理IO事件时,必须阻塞在某个方法上等待IO事件完成(阻塞IO事件或者轮询IO事件的方式)
            异步:所有的IO读写交给操作系统去处理,应用程序只需等待通知
                此时,可以去做其他的事情,并不需要去完成真正的IO操作,当操作IO完成后,会给应用程序一个通知
            异步相对于同步带来的直接好处就是在处理IO数据的时候,异步的方式可以将这部分等待锁消耗的资源用于处理其他事情,提升服务自身的性能.
        3.2 BIO和NIO的对比
            3.2.1 BIO(传统的IO)
                同步并阻塞的IO方式,传统的java.io包,基于流模型实现,提供了一些熟知的IO功能,例如file抽象,输入输出流等.交互方式是同步阻塞的方式,意味着在读取输入流或写入输出流时,在读写
                动作完成之前,线程会一直阻塞,它们之间的调用是可靠的线性顺序.
            3.2.2 NIO(Non-blocking/New I/O)
                NIO是一种同步非阻塞的IO模型,于java1.4引入,对应java.nio包,提供了channel,selector,buffer等抽象.NIO中的N可以理解为Non-blocking,不单纯是new.
                支持面向缓冲的,基于通道的IO操作方法
                NIO中提供了和传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞方式.
                对于高负载,高并发的网络应用,应使用NIO的非阻塞模式来开发
            3.3.3 BIO和NIO的对比
                BIO:面向流,阻塞IO,无触发
                NIO:面向缓冲,非阻塞IO,选择器触发
                
                NIO特点:一个线程可以处理多个通道,减少线程创建数量;读写非阻塞,节约资源;没有可读/可写数据时,不会发生阻塞导致线程资源的浪费
        3.3 Reactor模型
            3.3.1 单线程的Reactor模型
                多个client,多个channel,唯一selector,唯一thread
            3.3.2 多线程的Reactor模型
                多个client,多个channel,多个selector,多个thread
            3.3.3 多线程主从Reactor模型
                多个client,多个channel,多个selector,多个thread,多个子channel,子channel对应的多个selector,子channel对应的多个thread
        3.4 Netty基本概念
            3.4.1 Netty简介
                是一个NIO客户端服务器框架,可快速轻松开发网络应用程序,例如协议服务器和客户端,极大地简化了网络编程,例如TCP和UDP套接字服务器
                快速简便并不意味着应用程序需遭受可维护性和性能问题的困扰.
                netty经过精心设置,结合了许多协议(例如FTP,SMTP,HTTP以及各种基于二进制和文本的旧式协议)的实施经验.
                结果,netty成功找到了一种无需妥协即可轻松实现开发,性能,稳定性和灵活性的办法
            3.4.2 Netty执行流程
                server启动,netty从ParentGroup中选出一个NioEventLoop对指定的port进行监听
                client启动,netty从EventLoopGroup中选出一个NioEventLoop对连接server并处理server发送来的数据
                client连接server的port,创建channel
                netty从childgroup中选出一个nioeventloop与该channel绑定,用于处理该channel的操作
                client通过channel向server发送数据包
                pineline中的处理器一次对channel中的数据包进行处理
                server如需向client发送数据,则需将数据经过pineline中的处理器处理成bytebuffer数据包进行传输
                server将数据包通过channel发送给client
                pipeline中的处理器一次对channel中的数据包进行处理
            3.4.3 Netty核心组件
                Channel:是java nio的基本构造,可以看作是传入或传出数据的载体.因此,它可被打开或关闭,连接或断开连接
                EventLoop和EventLoopGroup:
                    EventLoop定义了Netty的抽象,用来处理连接的生命周期中所发生的历史事件,在内部,将会为每个Channel分配一个EventLoop.
                    EventLoogGroup是一个EventLoop池,包含多个EventLoop
                    Netty为每个Channel分配了一个EventLoop,用户处理用户连接需求,对用户的请求的处理等所有事件.EventLoop本身只是一个线程驱动,在其生命周期内只会绑定一个线程,让该线程处理一个channel的所有IO事件
                    
                    一个Channel一旦与一个EventLoop相绑定,那么在channel的整个生命周期内是不能改变的.一个EventLoop可以与多个Channel绑定.即Channel和EventLoop的关系是n:1,
                    而EventLoop和线程的关系是1:1
                    
                    ServerBootStrap和BootStrap:BootStrap和ServerBootStrap被称为引导类,指对应用程序进行配置,并使他运行起来的过程.netty处理引导的方式是使应用程序和网络层隔离.
                    BootStrap是客户端的引导类,BootStrap在调用build(连接UDP)和connect(连接TCP)方法时,会新创建一个Channel,仅创建一个单独的,没有父Channel的Channel来实现所有的网络交换
                    ServerBootStrap是服务端的引导类,ServerBootStrap在调用build()方法时会创建一个ServerChannel来接受客户端的连接,并且该ServerChannel管理多个子Channel用于客户端之间的通信
                    
                    ChannelHandler和ChannelPipeline:ChannelHandler是对Channel中数据的处理器,这些处理器可以是系统本身定义好的编解码器,也可以是用户自定义的,这些处理器会被统一添加到一个
                    ChannelPipeline的对象中,然后按照添加的顺序对Channel中的数据进行依次处理
                    
                    ChannelFuture:Netty中所有的IO操作都是异步的,即操作不会立即得到返回结果,所以Netty中定义了一个ChannelFuture作为异步操作的代言人,表示异步操作本身.
                    如果想获得该异步操作的返回值,可以通过该异步对象的addListener()方法为该异步操作添加NIO网络编程框架的Netty监听器,为其注册回调,当结果出来后马上调用执行
                    
                    Netty的异步编程模型都是建立在Future与回调概念上的.
        3.5 Netty源码阅读
            最好在debug的情况下进行阅读,因此需要准备客户端和服务端以及对应的handler
            3.5.1 server端
                EventLoopGroup parentGroup = new NioEventLoopGroup();
                EventLoopGroup childGroup  = new NioEventLoopGroup();
                
                ServerBootStrap bootstrap = new ServerBootStrap();
                bootstrap.group(childGroup,parentGroup).channel(NioServerSocketChannel.class)
                                                .childHandler(new ChannelIntilizar<SocketChannel>(){
                                                    @Override
                                                    protected void initChannel(SocketChannel ch) throw Exception{
                                                        ChannelPipeline pipeline = ch.pipeline();
                                                        pipeline.addLast(new StringDecoder());
                                                        pipiline.addLast(new StringEncoder());
                                                        pipeline.addLast(new DemoSocketServerHandler());
                                                    }
                                                });
                ChannelFuture future = bootstrap.bind(8888).sync();
                System.out.pringln("服务器已启动");
                future.channel().closeFuture().sync();
            3.5.2 server端handler
                public class DemoSocketServerHandler extends ChannelInboundHandlerAdapter{
                    @Override
                    public void channelRead(ChannelHandlerContext ctx,Object msg)throw Exception{
                        System.out.pringln("Client Address =="+ctx.channel().remoteAddress());
                        ctx.channel().writeFlush("from server:=="+UUID.randomUUID());
                        ctx.fierChannelActive();
                        TimeUnit.MILLISECONDS.sleep(500);
                    }
                    
                    @Override
                        public void exceptionCaught(ChannelHandlerContext ctx,
                                Throwable cause) throws Exception {
                        cause.printStackTrace();
                        ctx.close();
                    }
                }
            3.5.3 client端
                EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
                ServerBootStrap bootstrap = new ServerBootStrap();
                bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
                                                .childHandler(new ChannelIntilizar<SocketChannel>(){
                                                    @Override
                                                    protected void initChannel(SocketChannel ch) throw Exception{
                                                        ChannelPipeline pipeline = ch.pipeline();
                                                        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
                                                        pipiline.addLast(new StringEncoder(CharsetUtil.UTF_8));
                                                        pipeline.addLast(new DemoSocketClientHandler());
                                                    }
                                                });
                ChannelFuture future = bootstrap.connect("localhost",8888).sync();
                future.channel().closeFuture().sync();                                
            3.5.4 client端handler
                public class DemoSocketClientHandler extends ChannelInboundHandlerAdapter(){
                    @Override
                    public void channelRead(ChannelHandlerContext ctx,Object msg) throw Exception{
                        System.out.println(msg);
                        ctx.channel().writeAndFlush("from client:"+System.currentTimeMillis());
                        TimeUnit.MILLISECONDS.sleep(500);
                    }
                    
                    @Override
                    public void channelActive(ChannelHandlerContext ctx) throw Exception{
                        ctx.channel().writeAndFlush("from client: begin talking");
                    }
                    
                    @Override
                    public void exceptionCaught(ChannelHandlerContext xtx,Throwable cause) throw Exception{
                        cause.printStackTrace();
                        ctx.close();
                    }
                }
            3.5.5    NioEventLoopGroup初始化分析
                先了解下NioEventLoop和NioEventLoopGroup的关系,方便后续源码的理解
                NioEventLoop本身是一个单线程的Executor,必然拥有一个execute(Runnable commond)的实现方法,而NioEventLoop的execute()实现方法是在其父类SingleThreadEventExecutor中,
                在SingleThreadEventExecutor的execute方法中,有一句startThread();代码,这句代码最终调用了NioEventLoop的一个成员Executor执行了当前成员的execute方法。
                对应的成员是:io.netty.util.concurrent.SingleThreadEventExecutor#executor。而executor成员的初始化也是在当前代码执行时创建的匿名Executor,
                也就是执行到即新建并且执行当前匿名execute方法
                总结:NioEventLoop本身是一个Executor;NioEventLoop内部封装这一个新的线程Executor成员;NioEventLoop有两个execute方法,除了本身的execute方法,还有对应的
                    成员属性Executor对应的execte方法
                    
                NioEventLoopGroup也是一个Executor,并且是一个线程池的Executor,所以也有execute()方法,对应的实现在其父类    io.netty.util.concurrent.AbstractEventExecutorGroup#execute
                在NioEventLoopGooup构造中,在其父类MultithreadEventExecutorGroup的构造中再次引入了一个新的Executor,
                这个Executor对应的execute()就是在NioEventLoop中的成员Executor的execute()执行时调用的。                
                总结:    NioEventLoopGroup是一个线程池线程Executor;NioEventLoopGroup也封装了一个线程Executor.NioEventLoopGroup也有两个Executor()方法
                
                NioEventLoopGroup初始化代码分析:
                    NioEventLoopGroup构造方法基本初始化参数:
                        nThreads:DEFAULT_EVENT_LOOP_THREADS//默认当前CPU逻辑核心数的两倍, 
                        selectorProvide:SelectorProvider.provider()//当前JVM中唯一的一个单例的provider,
                        SelectStrategyFactory:DefaultSelectStrategyFactory.INSTANCE//默认选择策略工厂实例
                        chooserFactory:DefaultEventExecutorChooserFactory.INSTANCE//选择器工厂实例
                    重点方法是MultithreadEventExecutorGroup的构造方法分析
                        首先判断初始化构造函数中的Executor函数,当其为空时,将其初始化
                        executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());首先newDefaultThreadFactory()创建默认的线程工厂,然后创建ThreadPerTaskExecutor线程Executor对象
                        (此时创建的Executor是NioEventLoopGroup内创建的Executor对象,并非NioEventLoopGroup本身,可称为总Executor对象)
                        
                        随后创建children数组,根据需要创建的线程数创建对应数量的数组
                        children = new EventExecutor[nThreads]; 因为每个NioEventLoopGroup都是NioEventLoop集合的元素,所以此时的children数组就是当前NioEventLoopGroup的NioEventLoop
                        所以NioEventLoop的创建是在NioEventLoopGroup初始化的时候
                        
                        NioEventLoop初始化:整个过程存在一个成功标志,catch每个NioEventLoop创建完成过程,如果发生异常,则将所有已创建的NioEventLoop关闭。
                    
参考资料:https://blog.csdn.net/zhangzehai2234/article/details/135175994 (tomcat和netty对比)
          https://blog.csdn.net/weixin_40909461/article/details/138355959 (netty入门)    
          https://blog.csdn.net/qq_35190492/article/details/113174359 (netty知识点汇总)                            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值