apache mina: 对SEDA架构实现详解

来源:互联网 发布:手机淘宝举报有用吗 编辑:程序博客网 时间:2024/05/19 12:13


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;


在写出数据过程中,当调用IoSession.write(Object msg)方法时,创建一个WriteRequestQueue对象,并把IoSession加入到flushingSessions队列中。

    /** 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 写队列进行监控。




0 0