`
longxiaoyan
  • 浏览: 77327 次
  • 性别: Icon_minigender_1
  • 来自: 桂-京
社区版块
存档分类
最新评论

MINA源代码分析之启动与绑定(转)

    博客分类:
  • Mina
 
阅读更多
最近认真看了看MINA的源代码,阅读代码过程中学到了不少新东西,对于多线程和NIO有了更深的了解。鉴于在网上无法找到相关的源代码分析,
让我在刚开始看时走了不少弯路,因此在看代码时特意做笔记。
以下便是我的笔记,主要讲述了MINA的启动与绑定SocketAddress时其内部实际做的工作。
对于其中一些并不重要的部分在这边略去了,对于消息到达后最终如何流转到IoHandler部分在这次里面并没有涉及,这部分下次再谈。
在看源代码的过程中,有一个小小的心得,采用Debug的方式来看处理流程比直接看代码要有效的多!
当然Debug时,也得记下执行的路径。在Debug过程中,顺便复习了一下类的装载和初始化过程。
下面是笔记的具体内部:
MINA初始化调用过程  -- 对应于NioAcceptor acceptor = new NioAcceptor(); 语句。
1.AbstractIoService的<clinit>方法, (最先初始化继承树中最顶层super class,先调用<clinit>方法)
2.初始化DefaultSocketSessionConfig对象,先调<clinit>初始化所有类变量,再调用构造方法
3.执行AbstractPollingIoAcceptor初始化
    3.1初始化SimpleProcessorPool,生成一个若干的IoProcessor对象
        3.1.1 初始化SimpleProcessorPool中的实例变量,执行初始化方法<init>,生成Executor对象
        3.1.2 通过reflection 调用 newInstance方法初始化IoProcessor,具体过程如下:
            3.1.2.1 执行AbstractPollingIoProcessor的<clinit>方法初始化类变量
            3.1.2.2 执行<init>方法,初始化各实例变量,包括如下Queue:          
newSessions,removingSessions,flushingSessions,trafficControllingSessions,disposalFuture。
            3.1.2.3 执行构造方法AbstractPollingIoProcessor(Executor executor),初始化threadName,设置executor对象。
            3.1.2.4 执行NioProcessor构造方法  Selector.open();
    3.2 调用AbstractIoService的初始化方法,先初始化各实例对象,包括IoServiceListener(用于监听
future),IoFilterChainBuilder,IoSessionDataStructureFactory,IoServiceStatistics,IoServiceListenerSupport,
创建Executor对象。
    3.3 调用AbstractIoAcceptor的初始化方法<init>
        3.3.1 初始化LocalAddresses队列,boundAddresses Set(管理请求绑定的SocketAddress的容器),以及绑定的对象锁
    3.4 调用AbstractPollingIoAcceptor的<init>方法,执行初始化
        3.4.1 初始化registerQueue(注册请求队列),cancelQueue(取消请求队列),boundHandles(socketAddress,ServerSocketChannel的Map)。
        3.4.2 关联IoProcessor对象
        3.4.3 初始化Selector  Selector.open(),并将selectable设置为true
3.5 执行NioSocketAcceptor的构造方法中其它的操作,调用DefaultSocketSessionConfig的init方法。
绑定SocketAddress过程  -- 对应于代码中的  acceptor.bind(new SocketAddress(null,80));
1 调用AbstractIoAcceptor类中的bind方法,
    调用AbstractPollingIoAcceptor中的bind0方法,bind0过程如下:
    a.创建新的AcceptorOperationFuture对象的实例
    b.将这个实例放到registerQueue中,供后面的方法处理
    c.startupAcceptor 创建一个新的线程,具体的工作为inner class Acceptor, Acceptor处理过程下面讲述。
    d.selector.wakeup 继续select操作
    e.返回已经绑定的Set<SocketAddress>
2.绑定成功后触发fireServiceActivated事件。
AbstractPollingIoAcceptor.Acceptor类处理流程
    1 先select
    2 处理注册绑定请求 registerHandles(),该方法在AbstractPollingIoAcceptor中。
        a.从registerQueue中取出future
        b.通过Future中的取出的SocketAddress创建ServerSocketChannel,并绑定。
        c.以SocketAddress为key将绑定后的ServerSocketChannel放到Map中,供后面处理。
        d.该Future设置为done,并将Selector wakeup.
    3 判断是否有SelectionKey需要处理,如果需要,则进行处理,processHandles() 方法:
        a.通过NioSocketAcceptor.accept得到一个SocketChannel,生成一个NioSocketSession对象。
        b.finishSessionInitialization,设置该NioSocketSession的属性,
        c.包括AbstractIoSession中的WriteRequestQueue,
        d.调用AbstractPollingIoProcessor.add()方法,将该Session添加到newSessions容器中, 通过Executor对象创建一个新的线程处理,具体处理类
AbstractPollingIoProcessor.Process类。Process线程处理流程下面详细描述。
    4 处理取消请求,unregisterHandles()方法,从cancelQueue中取数据进行处理,关闭ServerSocketChannel,SelectionKey.cancel()。
    5 判断是否仍有在监听的请求,如是没有,释放相关资源,并退出。
AbstractPollingIoProcessor.Processor处理流程
    1、调用NioProcess中的selector进行select操作,
    2、处理newSessions中的IoSession对象 (AbstractPollingIoProcessor.add())
        a.从newSessions中得到session,为这些session注册READ事件
        b.为每个个session创建filter chain
        c.触发IoServiceListenerSupport的sessionCreate事件。
    3、为SocketChannel注册合适的事件  updateTrafficMask()方法
        a.根据SelectionKey的状态注册该Session感兴趣的事件
        b.read事件注册时,判断是否已经注册过,如果没有,则注册。
        c.调用setInterestedInWrite方法通过该session的writeQueue中的请求,注册WRITE事件。
    4、如果之前select有数据,则处理session,process()方法,具体处理如下:
        如果是读,用read()方法处理
            a.读取数据,并触发filterChain的messageReceived方法,将数据通过filterChain流转到最后的Handler去处理。
            b.如果没有可读数据,将session对象放入removeSessiong队列。
        如果是写出,用write()方法处理,直接放入flushingSessions队列,由后面步骤进行处理。
    5、处理flushingSessions队列中的请求,将数据写到SocketChannel中,并触发FilterChain中的fireMessageSent事件。
    6、处理removeSessiong队列中的请求,将不需要的session Close掉,如果session在还有数据,则触发FilterChain的fireMessageSent方法。
关闭SocketChannel连接,distory掉IoSession,并触发fireSessionDestroyed事件。
    7、notifyIdleSessions方法,最终调用filterChain的fireSessionIdle方法。
    8、判断是否仍然存在打开的session,如果没有则做退出操作。
通过MINA的启动和流程可以看到,在多线程环境中应用了大量的Queue,Set,Map的对象来存储需要接下来进行的操作,这样做的原因应
该是出于性能考虑。也有利于子线程与父线程之间的通信,有利于减少代码之间的依赖。其中还存在大量的子线程回调父线程的方法来完成一些操作,和平时用到的
直接生成一个新的工作线程去处理,之后便不管有非常大的区别。这种模式下,死锁的问题的判断就显得很重要。
由于代码量比较大,超过了我的理解范围,在很多时候仍然没有把这个框架完全吃透。
分享到:
评论

相关推荐

    Apache mina源代码框架解析

    在这个文档中,我们将简要分析Mina 2.0框架的源代码,并通过一个简单的时钟服务器示例来了解其工作原理。 首先,我们来看`MinaTimeServer`类。这个类是Mina服务器的主入口点,它创建了一个`NioSocketAcceptor`实例...

    一个Apache MINA使用案例源代码ApacheMina

    4. **Service启动与配置**: 源代码中应包含如何创建和启动MINA服务的代码。这通常涉及到设置服务器端口、配置IoAcceptor、添加过滤器到过滤器链,以及绑定IoHandler。 5. **Client连接**: 如果源代码包含了客户端...

    NIO_MINA学习例子_源代码

    4. **MINA服务端口**:查看服务端口的绑定和监听代码,理解如何启动一个MINA服务器,并接受客户端连接。 5. **异步编程模式**:理解非阻塞I/O如何提高系统的并发处理能力,以及如何通过MINA的事件驱动模型来实现。 ...

    Mina2.0.7原代码,去掉slf4j代码

    在研究Mina源代码时,你可以深入了解其内部工作原理,这对于理解网络编程、优化性能或者扩展功能都非常有帮助。同时,去除了第三方日志库的依赖,使得Mina更轻量级,更容易被嵌入到其他项目中。不过,这也意味着你...

    mina 2.0.4

    在学习MINA 2.0.4时,首先需要理解上述核心概念,然后通过阅读源代码,分析其内部实现,熟悉过滤器链的工作流程,以及如何自定义过滤器和处理程序。同时,通过创建简单的MINA应用,如TCP服务器或客户端,可以加深对...

    mina服务器简单代码示例

    压缩包文件`minaTestServer`可能包含了整个项目的源代码,包括`MinaTimeServer`类和相关的配置文件。通过查看源码,你可以更深入地理解Mina服务器的工作原理和使用方法。 总之,Mina服务器提供了一种简洁的方式来...

    apache-mina-2.0.16

    描述中的"apache-mina-2.0.16.zip"是指这个版本的源代码或二进制库被打包成ZIP文件供用户下载。ZIP文件是常见的压缩格式,用于减少文件的存储空间和便于传输。 标签"2.0.16"强调了这个特定的版本号。在软件开发中,...

    maven_spring mvc_mina dome

    在项目中,文件"maven_spring_mina"可能是整个项目的源代码包,包含了pom.xml文件(Maven的配置文件),Spring MVC的配置文件(如servlet-context.xml),Mina的相关配置和实现类,以及可能的测试代码。通过解压并...

    JAVA上百实例源码以及开源项目源代码

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    Mina实现长连接和短连接实例

    4. `src`:源代码目录,通常包含`main/java`和`test/java`子目录,分别存放主代码和测试代码。 5. `lib`:第三方库文件夹,可能包含Mina库和其他必要的依赖。 在Mina项目中,我们还需要了解如何配置`...

    mina test实例一个

    2. **源代码**:包括服务器端的 Acceptor 实现、Handler 实现、Filter 配置等。 3. **测试代码**:验证 Mina 实例是否按预期工作。 4. **文档**:可能有README或其他说明文件,解释项目结构和使用方法。 综上所述,...

    mina实例1mina实例1

    通过深入研究这些源代码,我们可以了解如何将MINA框架应用于实际项目,学习如何设计和实现网络协议、过滤器以及事件处理器。同时,对于Java NIO的理解也会进一步加深,因为MINA在底层大量使用了NIO机制。

    Mina入门程序

    在实际使用中,我们首先需要配置Mina,创建Acceptor并绑定到指定端口,然后启动监听。客户端则创建连接并发送数据。服务器端接收到数据后,通过解码器解析数据,然后由处理器进行业务逻辑处理,最后可能需要编码并...

    微信小程序 Web MINA框架下载.rar

    在下载的压缩包“codesc.net”中,你可以找到源代码的`node_modules`文件夹,这里包含了MINA框架的依赖库。这些库通常包括了微信小程序开发所需的各个功能模块,例如: - **网络模块**:提供了HTTP和WebSocket接口...

    mina入门程序

    通过分析这个源代码,你可以更好地理解Mina的工作原理和使用方式。学习和实践这个入门程序,将有助于你快速掌握Mina框架,并能应用于实际的网络服务开发中。 总结来说,Apache Mina是一个强大的网络通信框架,通过...

    mina:Apache MINA的镜像

    在"mina-trunk"这个文件夹中,可能包含了MINA项目的源代码树。通常,"trunk"指的是版本控制系统中的主分支,代表项目的最新开发版本。通过查看这些源代码,开发者可以深入了解MINA的工作原理,学习如何定制和扩展...

    MINA:微信小程序原始码

    在`MINA-master`这个压缩包中,很可能是包含了MINA框架的源代码和相关示例项目,开发者可以通过研究源代码了解其内部工作原理,并根据需要自定义和扩展框架功能。对于想要深入学习微信小程序开发或对MINA框架感兴趣...

    微信聊天微信小程序源码.rar

    微信聊天微信小程序源码是一个包含了开发微信小程序所需全部代码的压缩包。这个源码可能用于构建一个类似微信内部聊天功能的应用,让开发者可以学习、研究或定制自己的微信小程序。源码通常包括前端用户界面(UI)...

    微信小程序源码_今日更新选课投票.zip

    "微信小程序源码_今日更新选课投票.zip"是一个包含微信小程序开发源代码的压缩包,其中可能包含了一个用于选课投票的应用示例。在深入探讨之前,我们先来了解一下微信小程序的基本架构和开发流程。 微信小程序的...

    智慧书房微信小程序wisdomStudyMina-master.zip

    智慧书房微信小程序“wisdomStudyMina-master.zip”是一个包含源代码和资源的压缩包,专为构建微信平台上的互动阅读应用而设计。这个小程序基于微信开发者工具支持的Mina框架,它允许开发者利用微信的生态系统,为...

Global site tag (gtag.js) - Google Analytics