`
m635674608
  • 浏览: 4939712 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Netty源码学习笔记

    博客分类:
  • java
 
阅读更多

Netty一般都通过bootStrap来启动, 网络动作过程就是服务器端bind->accept->read->write,客户端 connect->read->write,一般bind或者connect后会有多次readwrite。依据这种特性nettybind,acceptread,write的线程分离,connectreadwrite线程分离

 

一、Netty主要可以分为3部分: buffer, channel, handle

1、      Channelbuffer

l  所有的实现类中都提供,readerIndex, writerIndex两个指针,无需nio bufferflip.

l  可以通过ChannelBufferFactory来创建channelbuffer. 分为两类buffer

 HeapChannelBufferFactory jvm堆上创建缓冲区,默认是BIG_ENDIAN排序

DirectChannelBufferFactory:对应nio ByteBuffer.allocateDirect(),直接缓冲区分配

l  WrappedChannelBuffer实现对ChannelBuffer封装,通过其可以自定义channelbuffer.

 

2、      Channel:

通常每种类型的channel一般都有一个对应channelfactory,以及一个channelconifg类。  通过channelfactory创建channel实例,然后由channelconifg来配置channel属性。

l  ChannelGroup  一组通道的集合,线程安全, 关闭的通道会自动从集合中删除, 可以通过ChannelGroup广播消息。

l  Channel的种类:

LocalChannel LocalServerChannel:本地通道、虚拟一个网络。

DatagramChanneel: udp连接通道.

ServerSocketChannelSoketChannel:  处理tcp/ip连接的通道。

l  Channelevent:  用于将:channel的相关信息 channel本身,传递的数据,channel的状态, future等等一起打包,在调用org.jboss.netty.channel.Channels类的各个静态的fire方式中产生,然后在channelpipe中的sendUpsteamsendDownStream中传递。

l  ChannelSink:处理pipelinedownstream结束后的事件。

 

3、      handler:

所有需要调用的handler都被包装成ChannelHandlerContext,注册到channelpipeline的一个map 通过两个指针:headtail保证map中的handle的调用顺序。处理upstream时,通过head指针从前往后依次调用实现ChannelUpstreamHandler接口的handle.   downstream处理通过tail指针,从后往前依次调用实现ChannelDownstreamHandler接口的handle  downsreamchannelpipeline传送完后,ChannelSinkeventSunk方法完成对系统底层的调用处理。(ChannelSinkchannel是通过attach的方式绑定到channelpipeline上)

Netty中已经提供的handler的种类如下:

l  codec handle。包括  64位机器的编码、解码,   字符集转化,压缩,http请求编码、解码; 序列化对象的编码、解码等等。通过codec handle我们可以直接往channel中写java 对象。

l  Timeout handler通过jboss.netty.util.Timer来对读写超时或者闲置链接的通知,handle中创建一个time对象,这个time对象包含一个定时器线程Work进程,在handle第一次被触发时,启动一个Work线程:监控超时事件。

l  Stream handler  用于异步处理大数据传递。通过将java.io.file对象包装成ChunkedFile对象,进行传递,ChunkedFile的底层实现是RandomAccessFile.

l  Queue handler: 用户将接受到的数据或需要发送的数据先存储到一个queue队列中,然后一次性的读和写。  包括BlockingReadHandlerBufferedWriteHandler. 注意在BlockingReadHandlerreceivemessage存储入queue,其后的handler将不再处理 messageReceived,exceptionCaught channelClosed事件,因此BlockingReadHandler必须放在channelpipeline的最后。  同理BufferedWriteHandler

 

4、      其他

l  org.jboss.netty.container 各种容器的兼容 Microcontainer OSGi Spring framework 整合接口

l  Bootstrap 启动类: BootStrap: TCP服务器端启动; ClientBootStrap:Tcp client端启动和ConnectionlessBootstrap  UDP启动。

 

二、服务器的启动和客服端connect的过程

 

1 、服务器启动

 bootstrap.bind()-> 触发ServerSocketChannel.open()的事件(sendupstream->捕捉open事件,channel.bind-> Channels.bind( 发起bind命令(sendDownstream-> PipelineSink进行处理-> 使用socket进行bind,启动boss进程。

 Boostrap.bind 方法包含两个参数 NioServerSocketChannelFactoryChannelPipelineFactoryNioServerSocketChannelFactory包含连个线程池bossExecutorworkerExecutorworkerExecutor 包含缺省为处理器个数×2NioWorker进程。

 2、服务器处理连接

 Boss启动后,在监听accept事件, 将捕获到的事件作为一个task放到一个niowork进程

registerTaskQueue队列中。

3、服务器端接收并处理数据

  NioWorker.run()->nioworker. processSelectedKeys()->Nioworker. Read()将从SocketChannel读取的数据封装成ChannelBuffer ->调用fireMessageReceived(channel,buffer)产生upstream事件 –> 由注册到Pipeline中的Hanlder进行处理

4、客户端connection

同服务器启动一样也需要创建一个NioClientSocketChannelFactory和一个ChannelPipelineFactory  同服务器端不同的是client端的boss进程不要监听,它将本地发出的建立的链接的请求封装成task放入一个registerTaskQueueboss负责消费Queue队列中的消息。

 

 

参考:

http://rdc.taobao.com/team/jm/archives/423 淘宝netty代码分析

http://www.cnblogs.com/NanguoCoffee/archive/2010/12/10/1902491.html

 

 

转:http://blog.csdn.net/north_eagle/article/details/6545357

分享到:
评论
1 楼 萨琳娜啊 2018-07-10  
Java读源码之Netty深入剖析
网盘地址:https://pan.baidu.com/s/11kYm2fhJg5CkxIkv0Etvbw 密码: kipg
备用地址(腾讯微云):https://share.weiyun.com/5Bs3HcR 密码:uu95be

JavaCoder如果没有研究过Netty,那么你对Java语言的使用和理解仅仅停留在表面水平,如果你要进阶,想了解Java服务器的深层高阶知识,Netty绝对是一个必须要过的门槛。

本课程带你从一个Socket例子入手,一步步深入探究Netty各个模块的源码,深入剖析Netty的工作流程和源码设计,让你不但“真懂”也要“会用”

相关推荐

Global site tag (gtag.js) - Google Analytics