1 -主线程阶段:
在主线程调用NioSocketAcceptor.bind()方法时,主线程创建AcceptorOperationFuture 对象,并把AcceptorOperationFuture 对象放到队列中。
protected final Set<SocketAddress> bindInternal(List<? extends SocketAddress> localAddresses) throws Exception {
// Create a bind request as a Future operation. When the selector
// have handled the registration, it will signal this future.
AcceptorOperationFuture request = new AcceptorOperationFuture(localAddresses);
// adds the Registration request to the queue for the Workers
// to handle
registerQueue.add(request);
// creates the Acceptor instance and has the local
// executor kick it off.
startupAcceptor();
}
private final Queue<AcceptorOperationFuture> registerQueue = new ConcurrentLinkedQueue<AcceptorOperationFuture>();
此时,启动acceptor线程池,把acceptor线程交由线程池管理。任务交由registerQueue 队列来完成。
2 -Acceptro线程阶段:
Acceptor为单线程阻塞模式。通过select()事件来驱动程序。
/**
* This method will process new sessions for the Worker class. All
* keys that have had their status updates as per the Selector.selectedKeys()
* method will be processed here. Only keys that are ready to accept
* connections are handled here.
* <p/>
* Session objects are created by making new instances of SocketSessionImpl
* and passing the session object to the SocketIoProcessor class.
*/
@SuppressWarnings("unchecked")
private void processHandles(Iterator<H> handles) throws Exception {
while (handles.hasNext()) {
H handle = handles.next();
handles.remove();
// Associates a new created connection to a processor,
// and get back a session
S session = accept(processor, handle);
if (session == null) {
continue;
}
initSession(session, null, null);
// add the session to the SocketIoProcessor
session.getProcessor().add(session);
}
}
}
/** A Session queue containing the newly created sessions */
private final Queue<S> newSessions = new ConcurrentLinkedQueue<S>();
Acceptor处理新连接socket,并把新建立的IoSession加入到newSessions队列中。并启动IoProcessor线程。
此时,newSessions队列中待处理的IoSession处于悬空状态,mina框架上尚未对IoSession处理。
3 -Processor 线程阶段:
在Processor线程阶段,首先处理在newSessions队列中的IoSession.
/**
* Loops over the new sessions blocking queue and returns the number of
* sessions which are effectively created
*
* @return The number of new sessions
*/
private int handleNewSessions() {
int addedSessions = 0;
for (S session = newSessions.poll(); session != null; session = newSessions.poll()) {
if (addNow(session)) {
// A new session has been created
addedSessions++;
}
}
return addedSessions;
}
在IoServiceListenerSupport 类中,处于活动状态的IoSession才被监管起来。
/** Tracks managed sessions. */
private final ConcurrentMap<Long, IoSession> managedSessions = new ConcurrentHashMap<Long, IoSession>();
/** A counter used to store the maximum sessions we managed since the listenerSupport has been activated */
private volatile int largestManagedSessionCount = 0;
/** A queue used to store the sessions to be flushed */
private final Queue<S> flushingSessions = new ConcurrentLinkedQueue<S>();
NioProcessor(AbstractPollingIoProcessor<S>).flush(long) 此时,统一把待写出flushingSessions队列中IoSession中数据写入到通道中。
/**
* Write all the pending messages
*/
private void flush(long currentTime) {
if (flushingSessions.isEmpty()) {
return;
}
do {
//在待写出数据的IoSession队列中处理消息
S session = flushingSessions.poll(); // the same one with firstSession
if (session == null) {
// Just in case ... It should not happen.
break;
}
// Reset the Schedule for flush flag for this session,
// as we are flushing it now
session.unscheduledForFlush();
//IoSession状态
SessionState state = getState(session);
switch (state) {
case OPENED:
try {
boolean flushedAll = flushNow(session, currentTime);
if (flushedAll && !session.getWriteRequestQueue().isEmpty(session)
&& !session.isScheduledForFlush()) {
scheduleFlush(session);
}
} catch (Exception e) {
scheduleRemove(session);
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireExceptionCaught(e);
}
break;
case CLOSING:
// Skip if the channel is already closed.
break;
case OPENING:
// Retry later if session is not yet fully initialized.
// (In case that Session.write() is called before addSession()
// is processed)
scheduleFlush(session);
return;
default:
throw new IllegalStateException(String.valueOf(state));
}
} while (!flushingSessions.isEmpty());
}
所以,在对mina进行监控时,可以监控flushingSessions 的大小,如果对于每一个IoSession进行监控,必须监控IoSession中的writeRequestQueue 写队列进行监控。