MINA 学习笔记 (version MIAN - 2.0)
写在前头:
本文档为学习 MINA 官方文档中的摘抄和记录,所有记录都是一些关键点,或比较重要的、有代表性的地方。
学习目的:
以计算机网络、Java NIO、Java 并发机制 为基础,以 MINA 为开发框架,最终实现文本、图片、语音、视频的高效传输。
学习资源:
官方首页 -- http://mina.apache.org/
文档首页 -- http://mina.apache.org/documentation.html
一、 ACUS2007.pdf
================================================================================
1. 特性:
1) 基于 Java NIO,因此具有 非阻塞、异步、事件驱动 的特性
2) 对 NIO 包装和提供了方便的访问方法,包括:auto-expanding, string encoding
3) allocate from the Heap or Stack
2. 结构
1) IoService
|--- IoAcceptor (act as a server)
|--- IoConnector (act as a client)
|--- IoSession (for a Connection)
work for a session is serialized
2) IoProcessor (one thread default)
you can add more IoProcessor Threads,
at least one per CPU core
3) IoFilter chain
4) IoHandler
3. 应用模式建议
• use ExecutorFilter as first in chain
unless you need really low latency
• use ProtocolCodecFilter
convert the wire protocol into a Java representation
• put application logic into an IoHandler
• store state in the IoSession
• minimum of Java 5
java.util.concurrent rocks!
二、JavaOne2008.pdf
================================================================================
1. MINA结构图
2. 异步的消息发送(IoSession & IoBuffer)
/******* e.g *******/
CharsetEncoder encoder = Charset.forName(System.getProperty("file.encoding")).newEncoder();
IoSession session = ...
IoBuffer buffer = IoBuffer.allocate(BUFFER_SIZE);
buffer.setAutoExpand(true)
.putString("It is ", encoder)
.putString(new Date().toString(), encoder)
.putString(" now.\r\n", encoder).flip();
//异步的消息发送。 为什么?
session.write(buffer);
3. IoHandler
实现IoHandler接口,添加自己的业务逻辑
/******* e.g *******/
public class EchoHandler implements IoHandler {
public void messageReceived(IoSession session, Object msg) {
IoBuffer buffer = (IoBuffer)msg;
session.write(buffer);
}
public void exceptionCaught(IoSession session, Throwable e) {
session.close();
}
public void sessionOpened(IoSession session) {...}
public void sessionIdle(IoSession session, IdleStatus stat) {...}
public void sessionClosed(IoSession session) {...}
public void messageSent(IoSession session, Object msg) {..}
}
4. IoService --> IoAcceptor (as a Server)
public class Main {
public static void main(String[] args) {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.setHandler(new EchoHandler());
acceptor.bind(new InetSocketAddress(8080);
...
acceptor.unbind(new InetSocketAddress(8080);
}
}
5. IoService --> IoConnector (as a Client)
public class Main {
public static void main(String[] args) {
IoConnector connector = new NioSocketConnector();
connector.setHandler(new MyHandler());
ConnectFuture future = connector.connect(
new InetSocketAddress("localhost", 8080));
IoSession session = future.await().getSession();
session.write(...).await();
session.close().await();
6. IoFilterChain & IoFilter
// Enable Loggin.
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
// Enable SSL.
acceptor.getFilterChain().addLast("ssl", new SslFilter());
// Enable Compression for an individual session
acceptor.getFilterChain().addBefore("ssl", "compressor", new CompressorFilter());
// Clear all of them
acceptor.getFilterChain().clear();
7. ProtocolCodecFilter
[ProtocolCodecFactory]
|--------------------------| [IoFilterChain]
| POJO --> IoBuffer | |----------------------------|
| ProtocolEncoder | | |
| ----------------------- =======> ProtocolCodecFilter |
| ProtocolDecoder | | |
| IoBuffer --> POJO | |----------------------------|
|--------------------------|
1) TextLineCodecFactory
public class EchoHandler extends IoHandlerAdapter {
public void messageReceived(IoSession s, Object m) {
s.write((String) m); // 由于 Filter 已将内容转化为 String
}
...
}
...
acceptor.getFilterChain().addLast(new ProtocolCodecFilter(new TextLineCodecFactory()));
2) HttpCodecFactory (略)
3) ExecutorFilter
acceptor.getFilterChain().addLast("executor", new ExecutorFilter(
new OrderedThreadPoolExecutor()));
//or new UnorderedThreadPoolExecutor()));
8. << Management >> using JMX
public class EchoHandler extends IoHandlerAdapter {
public void messageReceived(IoSession s, Object m) {
s.write((String) m);
}
...
}
9. For More Information
Vibrant community – that's what we are.
WWW – MINA.apache.org
E-mail – users@mina.apache.org
trustin@apache.org
三、MINA in Real Life.pdf
================================================================================
1. MINA结构图 (注意 Session 的位置从 IoHandler 换到了 IoService)
2. 工作流程图
3. A more complex Use Case
Apache Directory Server, it's include some features below:
1) TCP and UDP
2) Simple or Two levels protocols
3) Binary messages
4) Multiple handlers
5) Potentially hundred of thousands connections
4. Do's and Don'ts
Do's !!!
• Follow the KISS principle
• Keep the chain short
• Do not use an executor if not needed
• Tune the number of IoProcessors
• Use only one codec filter
• If you have a problem, then your codec/handler probably sucks...
DON'Ts !!!
• Don't use the logging filter. Use Log4j.
• Your filter must be threadsafe
• Don't expect that you will receive data in one single block
• Don't forget about the negative impact Nagle's algorithm has on performance
• Don't use Direct buffers unless absolutely needed