`
uniseraph
  • 浏览: 83580 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[mina指南]mina中Half Sync/Half Async模式

阅读更多
在解释Half Sync/Half Async模式之前,先介绍一个亲身经历的项目。曾经使用一个通讯支撑模块EMF,该模块完成了底层的socket通讯功能,和外部应用建立长连接,同时为上层应用提供一个回调接口如下:


public interface Hook {
          void call(Message msg);
}



上层应用可以根据自己业务逻辑的需要,实现该接口。


class MyHook implements Hook{
          public void callback(Message msg){
                    //应用的业务逻辑
          }

}

  然后应用可以将该实现注册到通讯支撑模块中。

//注册应用的回调实现
EmfHook hook = new MyHook();
EmfService.regist(hook);


在EMF的实现中负责将受到的socket数据拼装成应用需要的消息结构,然后在一定的匹配规则,找到一个应用的Hook,回调之(其实是多个hook,有可能多个应用对同一种消息感兴趣,简化之)。


//从socket上收到数据,
Byte[] buf=.....;

//将数据解析成应用的消息结构
Message msg=parse(buf);

//根据消息内容查找相应的EmfHook
EmfHook  hook = findHook(msg);

//调用应用的实现
hook.callback(msg);


一开始,这个模块运行的很好,性能不错,应用扩展也很方便,大家都很是满意,看来这个月的kpi一定不错,呵呵。然有一天,在做压力测试的时候发现,性能很差了,好久才能处理一条消息,数据吞吐量非常小,cpu却也不忙。这是怎么回事哪?


后来发现问题在于EMF的socket数据读取并解析工作和上层应用的hook操作是在一个线程中的,而某些应用的Hook实现有一些比较耗时操作,而所以导致在执行上层应用操作的时候,EMF并没有去进行I/O操作,读取数据,整个系统停在哪儿了。


最后稍作改动,将hook.callback(data)放在另外一个线程池中,这样EMF的线程和应用逻辑的线程就不再相互干扰,性能大大的提供。


从这个项目中得到的一个教训是:[size=small;]I/O密集操作的线程应该和业务逻辑的线程尽量分开[/size]。



再后来看POSA2,发现这不就是一个Half Sync/Half Async模式吗?

POSA2中写道
引用

半同步半异步(Half Sync/Half Async)体系结构模式将并发系统中的异步和同步服务分开,简化了编程,同时又没有降低性能。



通俗一点说,Half Sync/Half Async模式其实就是将异步请求排队到一个同步队列中,然后再从队列中取出请求处理,其实就是一个扩大的生产者/消费者问题。在socket编程的关键在于,将业务逻辑操作和底层的io操作分散到不同的线程中,避免业务逻辑操作可能导致整个线程的堵塞。


在mina中也存在Half Sync/Half Async模式,在默认情况下,mina的业务逻辑处理接口IoHandler的实现类就是在NioProcessor 的worker现在中执行的(NioProcessor的执行机制请参考)。如果业务逻辑接口堵塞或者耗时都将导致NioProcessor线程无法充分利用。


 

  ExecutorFilter

        IoAcceptor acceptor = new NioSocketAcceptor();
        
        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
        acceptor.getFilterChain().addLast("executor", new ExecutorFilter());

        acceptor.setHandler(  new TimeServerHandler() );

        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        
        acceptor.bind( new InetSocketAddress(PORT) );
        


如上述代码,通过在FilterChain中增加一个ExecutorFilter,mina将NioProcessor的IO操作线程和TimeServerHandler的业务处理线程分开了。在上述例子中,当NioProcessor收到socket上的数据,filter和handler的执行顺序为:logger->codec->executor->TimeServerHandler(有关IoFilter内容具体请参考http://uniseraph.iteye.com/blog/228194)。


其中logger->codec就在NioProcessor的工作者线程worker中,而executor和TimeServerHandler则是在executorFilter的线程池中。具体参考代码如下:

 private ExecutorFilter(Executor executor, boolean createdExecutor, IoEventType... eventTypes) {
        if (executor == null) {
            throw new NullPointerException("executor");
        }/*这里将evenType初始化为所有事件类型的集合*/
        if (eventTypes == null || eventTypes.length == 0) {
            eventTypes = new IoEventType[] { IoEventType.EXCEPTION_CAUGHT,
                    IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT,
                    IoEventType.SESSION_CLOSED, IoEventType.SESSION_IDLE,
                    IoEventType.SESSION_OPENED, };
        }
        //下面省略
    }
    public final void messageReceived(NextFilter nextFilter, IoSession session,
            Object message) {
    /*executorFilter对该事件有效*/   if (eventTypes.contains(IoEventType.MESSAGE_RECEIVED)) {
            fireEvent(new IoFilterEvent(nextFilter,
                    IoEventType.MESSAGE_RECEIVED, session, message));
        } else {
            nextFilter.messageReceived(session, message);
        }
    } 
    protected void fireEvent(IoFilterEvent event) {
        getExecutor().execute(event);
    } 


由上可知,如果executorFilter对某个事件有效,那么将在线程池中执行该事件,如果无效则在原有的NioProcessor.Worker线程中执行下一个IoFilter或者IoHandler。


当然也可以不用ExecutorFilter,而是在IoHandler的实现类中放一个线程池,但是多数情况下是没有这样的必要。








分享到:
评论
1 楼 xiaopeng187 2014-10-23  
I/O密集操作的线程应该和业务逻辑的线程尽量分开,mina中是通过ExecutorFilter实现的,但是在项目中ExecutorFilter的线程池大小应该配置为多大才合适呢?

相关推荐

    Apache MINA 2.0 用户指南中英文对照阅读版[带书签]

    中英文版的 pdf 均带有书签,方便读者朋友查阅。 mina_2.0_user_guide_cn.pdf 内容预览: 第一章:入门 第二章:基础知识 第三章:IO 服务 第四章:会话 第五章:过滤器 第六章:传输 第七章:事件处理器 第八章:...

    基于 MINA 的 TLS/SSL NIO Socket 实现(二)

    在本篇博文中,我们将深入探讨如何利用Apache MINA库实现基于TLS/SSL的NIO(非阻塞I/O)Socket通信。MINA是一个高度可扩展的网络应用框架,广泛用于构建高性能、高并发的网络应用程序,如服务器端的TCP和UDP服务。...

    Apache_MINA_2_用户指南.pdf

    Apache MINA 2 用户指南 Apache MINA 2 是一个基于 Java 语言的网络应用框架,旨在帮助开发者快速构建高性能、可靠、可扩展的网络应用程序。该框架提供了一个灵活的架构,使得开发者可以轻松地构建各种类型的网络...

    apache-mina-2.0.4架包及源码各pdf学习教程

    当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中。不管是新手还是老手,还是很有学习参考价值的。

    MINA_API+MINA_DOC+mina

    这个压缩包包含了MINA API文档、自学手册以及开发指南,对于学习和理解MINA框架有极大的帮助。 首先,`MINA-2.0.0-API.chm` 文件是MINA 2.0版本的API帮助文档,它是以CHM(Compiled Help Manual)格式编译的Windows...

    apache-mina-2.0.4.rar_apache mina_mina

    1. **Filter Chain**:Mina的核心设计模式之一是过滤器链。每个连接都有一系列过滤器,它们按照顺序处理入站和出站事件。过滤器可以实现特定功能,如数据编码解码、安全验证、性能监控等。 2. **Session**:Session...

    MINA2.0用户手册中文随笔翻译

    MINA2.0 用户手册中文随笔翻译 MINA 是一个基于 NIO(Non-Blocking I/O)的网络框架,提供了统一的接口来处理 TCP、UDP 和其他机制的通信。MINA 的主要特点是能够处理大量的 socket 连接,并提供了一个高层接口来...

    mina的高级使用,mina文件图片传送,mina发送文件,mina报文处理,mina发送xml和json

    在本文中,我们将深入探讨Mina的高级使用,特别是在文件图片传送、文件发送、XML和JSON报文处理方面的实践。 1. **Mina的高级使用** Mina的核心在于其异步事件驱动的模型,这使得它在处理大量并发连接时表现出色。...

    mina中文开发手册

    - **事件驱动与异步处理**:Mina采用了事件驱动的设计模式,并基于Java NIO(非阻塞I/O)实现了异步处理机制。这种方式提高了系统的响应能力和吞吐量。 - **高级API**:提供了一组易于使用的API,使得开发者可以专注...

    Apache MINA 2.0 用户指南( 缺第一章节)

    ### Apache MINA 2.0 用户指南:基础知识 #### 基础概念介绍 Apache MINA 2.0 是一款高性能且易于使用的网络应用程序框架,它简化了开发人员在网络编程方面的负担,允许开发者专注于应用程序的核心功能,而不是底层...

    mina连接 mina心跳连接 mina断线重连

    在本文中,我们将深入探讨Mina的核心概念,包括连接管理、心跳机制以及断线重连策略。 首先,让我们理解"Mina连接"。在Mina中,连接是指客户端与服务端之间建立的通信链路。它支持多种传输协议,如TCP/IP(Socket)...

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    给予mina 协议进行大数据传输

    标题中的“给予mina协议进行大数据传输”指的是一种基于Java的网络通信框架——Apache MINA(Model-View-Controller for Network Applications)。MINA是Apache软件基金会的一个项目,它提供了一个高度可扩展和高...

    Mina+Socket通信

    Mina和Socket是两种常见的网络通信框架和技术,它们在Java编程环境中被广泛使用。本篇文章将深入探讨如何使用Mina与Socket实现通信,并提供客户端和服务端的实现代码概述。 Mina(全称“MINA: Minimalistic ...

    mina2.0用户指南

    本指南主要介绍了MINA 2.0的基本使用方法,包括NIO的介绍、MINA框架的核心组件以及与传统BIO(Blocking I/O)模式的对比。 NIO(New I/O),顾名思义,是Java提供的一个新I/O标准,它从Java 1.4版本开始引入,主要...

    Mina2中文文档

    - **会话管理**:介绍如何使用Mina中的Session来管理客户端连接,包括Session的生命周期管理、状态维护等功能。 #### Chapter 5 - Filter(过滤器) - **过滤器体系**:Mina提供了一套基于过滤器的机制来处理网络...

    MINA中文官方教程

    这种模式使得MINA在处理网络I/O时更加灵活,可以实现低延迟和高吞吐量。 在实际开发中,MINA提供了多种预定义的过滤器,例如,TCP心跳检测过滤器、日志过滤器等,开发者可以通过组合这些过滤器来构建自己的网络应用...

    Apache MINA框架相关资料

    标题中的“Apache MINA框架相关资料”涵盖了对MINA框架的全面学习材料,包括中文参考手册、源码分析、API文档和与Spring框架的整合指南。 1. **中文参考手册**(Apache_Mina_Server_2.0中文参考手册V1.0.pdf):这...

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    总结来说,本教程将引导你从理论到实践,掌握Java NIO的基本原理,理解Mina框架的使用,以及如何在SpringBoot环境中整合Mina实现高效的网络通信。通过这些知识的学习,你将具备开发高并发、高性能网络应用的能力。

    Mina 2.0 User Guide(Mina 2.0 用户指南)

    MINA 2.0 User Guide Part I - Basics Chapter 1 - Getting Started Chapter 2 - Basics Chapter 3 - Service Chapter 4 - Session Chapter 5 - Filters Chapter 6 - Transports Chapter 7 - Handler Part II - ...

Global site tag (gtag.js) - Google Analytics