MINA常见问题


MINA是什么意思?

MINA是:

  • 'Multipurpose Infrastructure for Network Applications' 的缩写;
  • 女孩的名字;
  • 日本的'南部';
  • 西班牙语和葡萄牙语的'Mine';

查看Wikipedia获取更多含义。

MINA支持什么传输?

MINA当前支持基于Java NIO API的TCP和UDP协议,提供串口通信的支持,以及基于Apache Portable Runtime的传输。

如何执行MINA?

总所周知和C/C++服务一样执行。请参考性能测试报告客户评价

我应该使用MINA的哪个版本?

使用2.0最后的发布版本。1.0和1.1不再维护了。

构建/运行MINA有什么要求?

构建MINA需要JDK1.5或以上版本。但是MINA可以在JDK1.4上完美运行,如果不适用SSLFilter。这意味着使用SSL的情况下需要JDK1.5或以上版本。

MINA核心模块依赖两个类库,SLF4J和backport-util-concurrent(1.0):

SLF4J(Simple Logging Facade for Java)Log4j作者的日志框架。SLF4j类似于Commons-Lgging,但是他不会引起任何类加载器问题。SLF4J提供Log4J、JDK1.4日志API、和NLog4J的绑定。请放置你喜欢的日志框架合适的SLF4J JAR文件。

Spring框架JZlib还需要构建integration-spring和filter-compression模块。

我怎么才能获得帮助?

获取帮助的主要来源是用户指南。你还可以通过各种渠道询问MINA问题或为它做些贡献。

我怎么才能贡献?

你可以贡献与MINA相关的任何事情:实例、有用的编解码器、教程、功能改进、BUG修复、测试基准等等。请马上联系我们

MINA可以...?

我可以使用MINA创建客户端(或服务端)应用吗?

可以。你可以使用MINA创建客户端和服务端应用。请看一看IoConnector和IoAcceptor。

MINA可以处理像HTTP这样的文本协议吗?

可以。请看一看HTTP服务实例。AsyncWeb是一个基于MINA的HTTP服务实现。

MINA可以处理像LDAP这样的复杂二进制协议吗?

可以。请看一下SumUp实例。还没有完整的ASN.1支持,但是我们将来会实现,并且你可以参与贡献使他更快实现。

我可以使用MINA实现保持连接存活的协议吗?

可以。MINA不关闭任何连接,除非你调用IoSession.close()或由远端关闭。

MINA支持开箱即用的SSL/TLS和SASL吗?

我们支持开箱即用的SSL/TLS。请参考SSLFilter。它还支持实现StartTLS的方式。JDK1.5提供完整的SASL支持,它在MINA中运行良好。

需要我处理IoHandler线程安全吗?

这依赖于你的实现。如果你访问多个会话共享的资源,你需要使它线程安全。如果资源不是共享的,并且只是一个session访问,你不需要使他线程安全。这是因为所有由MINA生成的事件按顺序传输到你的处理器,并且相同会话的老事件还没返回的时候,不会处理新事件。

除了TCP/IP和UDP/IP,MINA还可以支持什么传输类型?

几乎所有的传输类型。MINA API被设计成独立传输。你可以实现任何传输类型支持,只要你遵守MINA API。支持Pre-1.4 I/O、可靠的多路传输、Java通讯API、以及文件I/O。

MINA支持多路传输吗?

还不支持。JAVA NIO还不支持多路传输。对于NIO的多路传输将在Java SE7中支持。我们认真的考虑使用pre-1.4 Java API实现多路传输。

我如何?

我怎么存储指定的session信息?

Session有自定义属性的能力,你可以随时添加和移除。这些自定义的属性不在session之间共享;它的目的是存储session指定的信息。

在我实现复杂业务逻辑的时候怎么拆分一个事件处理器到多个处理器?

请参考DemuxingIoHandler。

怎么close我的session以及怎么dispose我的Connector?

你需要两个步骤:首先关闭你的session,然后dispose connector。当然,如果你先dispose你的Connector,然后所有的session将会被关闭。下面是代码:

ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 8080));
// Get the close future for this session
CloseFuture closeFuture = cf.getSession().getCloseFuture();
// Adding a listener to this close event
closeFuture.addListener((IoFutureListener<?>) new IoFutureListener<IoFuture>() {
       @Override
       public void operationComplete(IoFuture future) {
           System.out.println("The session is now closed");
       }
});
// Do the close requesting that the pending messages are sent before
// the session is closed
closeFuture.getSession().close(false);
// Now wait for the close to be completed
closeFuture.awaitUninterruptibly();
// We can now dispose the connector
connector.dispose();

客户端session关闭之后怎么重新连接服务器?

下面是实例代码:

public void sessionClosed( IoSession session ) throws Exception {
   // Wait for five seconds before reconnecting.
   Thread.sleep( 5000 );
   // Reconnect.
   connector.connect( session.getRemoteAddress(), this );
}

或许更好的方法是提取这些代码到一个reconnect方法,在其他地方可以复用。

我应该什么时候使用过滤器实现我的协议处理器?

IoFilter通常可复用,就像Servlet过滤器。请实现常用的业务逻辑,如权限验证和日志。如果你只实现复杂的多层协议,如kerberos,你可以考虑使用org.apache.mina.handler.chain包。

怎么检查远端不再响应消息?

这里你不能简单的使用sessionIdle事件。你必须使用java.util.concurrent.ScheduleExecutor。为每个请求消息安排执行一个超时任务,并当接受到响应消息时退出。

怎么使用我喜欢的日志框架记录MINA信息?

请参考SLF4J手册的'在部署时交互实现'章节。

故障排除

负载较重的情况下得到OutOfMemoryErro或响应超时和连接重置。

我们建议切换默认的buffer类型为'heap',在启动服务之前插入下面的代码:

ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());

如果你喜欢直接缓冲区为堆缓冲区,JVM可能耗尽直接内存。请尝试增加最大直接内存大小,使用-XX:MaxDirectMemorySize选项(如-XX:MaxDirectMemorySize=128M)

没有数据写到session,即使buffer非空。

请确认写buffer之前是否调用ByteBuffer.flip(),投掷buffer。这是初学者的常见错误。

我用MINA创建了一个SSL客户端,但是在session打开之后没有初始化任何握手。

请确认在初始化连接之前调用了SSLFilter.setUseClientMode(true)。服务端开发者还要通过设置IoSession.readerIdleTime断开没有初始化SSL握手的连接,并在IoHandler.sessionIdle()里关闭session。

SocketConnector发生若干消息为什么作为一条消息?

例如,我尝试使用SocketConnector发生'abc'和'def',但是他发送'abcdef'。是MINA的bug吗?

不是的,这是由于你的操作系统尝试更有效率的发送包。你可以通过调用SocketSessionConfig.setTcpNoDelay(),启用/关闭nagle的算法。例如:

((SocketSessionConfig) connector.getSessionConfig()).setTcpNoDelay(false)

然而,即使你这么做,你也不能期望MINA里的一个session.write(bytes)对应一个TCP包。你很可能需要实现你自己的编解码器,处理传入的字节装配为消息对象。如果你正实现一个基于文本行的协议,TextLineCodec是个不错的选择。更多有用的实例请看一下MINA发布包里的SumUp实例。

我得到InvalidClassChangeError。

请确认你是否使用合适的SLF4J版本。如果你使用过时的SLF4J版本,你会得到InvalidClassChangeError。

我的服务故障:java.net.SocketException:Too many files open

网络socket像对待文件一样,你的操作系统有可管理的文件句柄数限制。缺乏文件句柄通常应归于太多的客户端连接数,并且频繁的断开。按照TCP,关闭socket之后还要一些额外的时间保持在TIME_WAIT状态。原因是保证延迟的数据包道德正确的socket。在Windows,默认的TIME_WAIT超时时间是4分钟,在Linux是60秒。

在Windows里改变超时时间

  1. 运行regedit打开注册表
  2. 定位下面的key:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters
  3. 添加一个TcpTimedWaitDelay的新值为一个小时,并且设置期望的超时时间秒数(30-300)
  4. 重新启动

在Linux里改变超时时间

更新配置,通过运行(本实例里是30秒):

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

重启网络组建,例如通过运行:

/etc/init.d/networking restart

service network restart

 

原创文章,转载请注明出处:转载自小马过河 - MINA常见问题


Jbone

Spring Cloud实战项目jbone正在开发中, jbone功能包括服务管理、单点登录、系统管理平台、内容管理平台、电商平台、支付平台、工作流平台等子系统。欢迎关注!

GitHub 码云
马军伟
关于作者 马军伟
写的不错,支持一下

先给自己定个小目标,日更一新。