NettyServer
1、private Map< String, Channel> channels:< ip:port, channel> 所有通道。
2、private ServerBootstrap bootstrap : netty 服務端啟動器。
3、private io.netty.channel.Channel channel:服務端監聽通道。
4、private EventLoopGroup bossGroup;Netty boss線程組(負責連接事件)
5、private EventLoopGroup workerGroup : nety work線程組(負責IO事件)
代碼@1:調用父類的構造方法,主要初始化AbstractPeer(channelHandler、url)和AbstractEndpoint(codec2、timeout、idleTimeout )
代碼@2:根據URL中的host與端口,創建localAddress。
代碼@3:如果配置了< dubbo:parameter key = “bind.ip” value = “”/> 與 < dubbo:parameter key = “bind.port” />,則用該IP與端口創建bindAddress,通常用于多網卡,如果未配置,bindAddress與 localAddress綁定的IP與端口一樣。
代碼@4:初始化accepts與idleTimeout ,這兩個參數未被其他地方使用。
代碼@5,調用doOpen方法,正式在相應端口建立網絡監聽。
1.2、源碼分析NettyServer#doOpen
代碼@1:創建Netty服務端啟動幫助類ServerBootstrap.
代碼@2:創建服務端Boss線程,線程名:.NettyServerBoss,主要負責客戶端的連接事件,主從多Reactor線程模型中的主線程(連接事件)。
代碼@3:創建服務端Work線程組,線程名:NettyServerWorker-序號,線程個數取自參數:iothreads,默認為(CPU核數+1)與32取小值,顧名思義,IO線程數,主要處理讀寫事件,編碼、解碼都在IO線程中完成。
代碼@4:創建用戶Handler,這里是NettyServerHandler。
代碼@5:Netty啟動的常規寫法,關注如下內容:
addLast(“decoder”, adapter.getDecoder()) : 添加解碼器
addLast(“encoder”, adapter.getEncoder()) :添加編碼器
addLast(“handler”, nettyServerHandler) :添加業務Handler。
這里簡單介紹一下流程:
1、客戶端建立與服務端連接,此時Boss線程的連接事件觸發,建立TCP連接,并向IO線程注冊該通道(Channel0)的讀事件。
2、當客戶端向服務端發送請求消息后,IO線程中的讀事件觸發,會首先調用adapter.getDecoder() 根據對應的請求協議(例如dubbo)從二進制流中解碼出一個完整的請求對象,然后傳入到業務handler,例如nettyServerHandler,執行相應的事件方法,例如recive方法。
3、當服務端向Channel寫入響應結果時,首先編碼器會按照協議編碼成二進制流,供客戶端解碼。