存档

文章标签 ‘服务器设计’

nginx中if命令的设计和实现

2011年3月13日 没有评论

原创文章,转载请注明: 转载自pagefault

本文链接地址: nginx中if命令的设计和实现

先看这篇文章:http://wiki.nginx.org/IfIsEvil,这篇文章只是简单的介绍了if使用中一些很恶心的地方,接下来我会通过代码来看if为什么是 evil的。

if是rewrite模块里面的一个命令,因此if部分的执行也是在rewrite的phase执行的,下面就来简要的描述下rewrite模块是如何运行的。

这里有一个很关键的函数就是ngx_http_script_code_p,它的原型如下:

typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);

在rewrite模块中,所有将要在rewrite phase执行的代码的函数都会是一个ngx_http_script_code_pt类型的函数(比如rewrtie的正则匹配,比如if指令等等,而当进入rewrite handler的时候,将会依次执行这些函数,这些函数都是保存在ngx_http_script_engine_t中,下面我们来看这个结构。

typedef struct {
//这个指针指向了所有的需要执行的函数(ngx_http_script_code_pt)数组的首地址.
    u_char                     *ip;
    u_char                     *pos;
    ngx_http_variable_value_t  *sp;
...............................................................
//表示执行完对应的函数之后的返回值.
    ngx_int_t                   status;
    ngx_http_request_t         *request;
} ngx_http_script_engine_t;

阅读全文…

Share

nginx对TCP_CORK/TCP_NOPUSH的使用

2011年2月23日 没有评论

原创文章,转载请注明: 转载自pagefault

本文链接地址: nginx对TCP_CORK/TCP_NOPUSH的使用

在nginx中使用了send_file 并且配合TCP_CORK/TCP_NOPUSH进行操作,我们一般的操作是这样子的,首先调用tcp_cork,阻塞下层的数据发送,然后调用send_file发送数据,最后关闭TCP_CORK/TCP_NOPUSH.而在nginx中不是这样处理的,前面两步都是一样的,最后一步,它巧妙的利用的http的特性,那就是基本都是短连接,也就是处理完当前的request之后,就会关闭当前的连接句柄,而在linux中,如果不是下面两种情况之一,那么关闭tcp句柄,就会发送完发送buf中的数据,才进行tcp的断开操作(具体可以看我以前写的那篇 “linux内核中tcp连接的断开处理”的 blog) :

1 接收buf中还有未读数据。
2 so_linger设置并且超时时间为0.

而如果调用shutdown来关闭写端的话,就是直接发送完写buf中的数据,然后发送fin。

ok,通过上面我们知道每次处理完请求,都会关闭连接(keepalive 会单独处理),而关闭连接就会帮我们将cork拔掉,所以这里就可以节省一个系统调用,从这里能看到nginx对细节的处理到了一个什么程度。

接下来还有一个单独要处理的就是keepalive的连接,由于keepalive是不会关闭当前的连接的,因此这里就必须显式的关闭tcp_cork。
阅读全文…

Share