Nginx源码分析(6)

Nginx具有一系列的模块,包括HTTP模块,核心模块和mail模块等。简要分析一下一些具有代表性模块的原理。


event模块

event模块的主要功能是监听accept后建立的连接,对读写事件进行添加删除。事件处理模型和Nginx的非阻塞IO模型结合在一起使用。当IO可读可写的时候,相应的读写时间就会被唤醒,此时就会去处理事件的回调函数。

对于Linux,Nginx使用的是epollepollpoolselect的增强版本。

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符(fd),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

所以epoll本质是同步IO + 阻塞的(其实从其它角度看也可以算非阻塞,因为不是所有的数据到达后才返回)。

select模型的调用流程如下:

epoll对select模型和poll模型有诸多改进。主要改进就是引入notify机制mmap机制

  • mmap将内核空间的一段内存区域映射到进程内存中,相当于内核空间和用户空间共享内存。当epoll回调上层的callback函数来处理socket数据时, 数据已经从内核层自动映射到了用户空间。

  • select用O(n)的效率不断地去查看那些fd,效率太低。而epoll通过在内核中提供callback机制的方式,在内部使用链表把O(n)降到了O(1),讨论参见SO

我们看看怎么实现callback机制的。

当为一个用户建立一个socket连接时,调用epoll的current进程会加入到驱动的wait_queue中。当其它用户连接时,进行同样的处理。所以current进程在所有驱动的等待队列中。

当IO没有就绪,调用read函数会阻塞在这一步。一旦只要有一个用户连接的IO就绪,current进程就会被唤醒。

与select相比,epoll加入了callback这个hock,记录了这个唤醒者,避免了在current进程醒着的时候查询到底是谁唤醒了我。


##timer模块 先看一段代码,timer什么时候起作用。

void Request::run()
{
    keep_alive_timer = new QTimer();
    if (s_keep_alive_enable)
    {
        keep_alive = s_keep_alive_default;
        keep_alive_timeout = s_keep_alive_timeout * 1000;// the wait time
        connect(keep_alive_timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
        keep_alive_timer->setSingleShot(true);
        keep_alive_timer->setInterval(keep_alive_timeout);
        keep_alive_timer->start();
    }
    //a new thread
    socket = new QTcpSocket();
    if (!socket->setSocketDescriptor(socketDescriptor))
        return;
    connect(socket, SIGNAL(readyRead()), this, \
    SLOT(onReadyRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, \
    SLOT(onDisconnected()), Qt::DirectConnection);
    exec();
}

代码出自一个简单的http服务器。它新建了一个定时器,然后计算自连接开始后的时间。主要用来判断连接是否timeout。

Nginx使用红黑树来构造定时器。定时器的机制就是,二叉树的值是其超时时间,每次查找二叉树的最小值,如果最小值已经过期,就删除该节点,然后继续查找,直到所有超时节点都被删除。我们知道,自平衡二叉搜索树rbtree的树节点中,最左边叶子节点(或根节点)所代表的那个定时器的超时时间是最小的,因此只需要O(1)时间删除它就可以。


##参考

http://www.cnblogs.com/Anker/p/3265058.html

http://www.cnblogs.com/Anker/p/3254269.html

http://www.pento.cn/pin/31146170

http://blog.csdn.net/ce123_zhouwei/article/details/8459730

http://blog.csdn.net/v_july_v/article/details/6105630

http://rango.swoole.com/archives/381

http://www.smithfox.com/?e=191

http://nieyong.github.io/wiki_cpu/mmap%E8%AF%A6%E8%A7%A3.html



Previous     Next
tuzhi /
Published under (CC) BY-NC-SA in categories 服务器  tagged with