Reactor

约 371 字大约 1 分钟

Reactor

之前写作将Reactor模型放到Netty目录下,当时只学习了Netty源码,认为其思想主要是应用Jetty、Undertow、Tomcat,现在看当时眼光太低,像redis,nginx优秀框架都是使用这种思想(事件驱动代替父子进程、C10K问题)。

Redis ae.copen in new window

核心代码如下,关注wfileProcwfileProc

int aeProcessEvents(aeEventLoop *eventLoop, int flags)
{
        // 删除其他代码
        /* Call the multiplexing API, will return only on timeout or when
         * some event fires. */
        numevents = aeApiPoll(eventLoop, tvp);
        // 删除其他代码
        /* After sleep callback. */
        if (eventLoop->aftersleep != NULL && flags & AE_CALL_AFTER_SLEEP)
            eventLoop->aftersleep(eventLoop);
        for (j = 0; j < numevents; j++) {
            int fd = eventLoop->fired[j].fd;
            aeFileEvent *fe = &eventLoop->events[fd];
            int mask = eventLoop->fired[j].mask;
            int fired = 0; /* Number of events fired for current fd. */
            int invert = fe->mask & AE_BARRIER;
            // read
            if (!invert && fe->mask & mask & AE_READABLE) {
                fe->rfileProc(eventLoop,fd,fe->clientData,mask);
                fired++;
                fe = &eventLoop->events[fd]; /* Refresh in case of resize. */
            }
            // wrtie
            if (fe->mask & mask & AE_WRITABLE) {
                if (!fired || fe->wfileProc != fe->rfileProc) {
                    fe->wfileProc(eventLoop,fd,fe->clientData,mask);
                    fired++;
                }
            }
            if (invert) {
                fe = &eventLoop->events[fd]; /* Refresh in case of resize. */
                if ((fe->mask & mask & AE_READABLE) &&
                    (!fired || fe->wfileProc != fe->rfileProc))
                {
                    fe->rfileProc(eventLoop,fd,fe->clientData,mask);
                    fired++;
                }
            }
            processed++;
        }
    }
    if (flags & AE_TIME_EVENTS)
        processed += processTimeEvents(eventLoop);
    return processed; /* return the number of processed file/time events */
}

nginx Workers Modelopen in new window

架构图中如下:

An image

可以查看work模型,使用的是事件通知,基本与Reactor模型相等。

An image

从图中可以看到master职责主要负责创建、绑定、关闭网络连接。work池负责接受、处理请求。

总结

Reactor模型是一个网络高并发常用模型,需要用心和时间去学习。