apache mina: 对SEDA架构实现详解


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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值