存档

文章标签 ‘web server’

mochiweb源码分析(二)

2012年5月30日 没有评论

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

本文链接地址: mochiweb源码分析(二)

这次主要来看mochiweb如何处理http协议以及如何将外部模块加载到mochiweb框架中。

首先在上一篇的分析最后,我们知道当accept句柄之后,mochiweb最终会调用call_loop方法,那么我们就从call_loop开始

call_loop({M, F}, Socket) ->
    M:F(Socket);
call_loop({M, F, [A1]}, Socket) ->
    M:F(Socket, A1);
call_loop({M, F, A}, Socket) ->
    erlang:apply(M, F, [Socket | A]);
call_loop(Loop, Socket) ->
    Loop(Socket).

阅读全文…

Share

nginx中cache的设计和实现(一)

2012年3月21日 没有评论

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

本文链接地址: nginx中cache的设计和实现(一)

Nginx的cache实现比较简单,没有使用内存,全部都是使用文件来对后端的response进行cache,因此nginx相比varnish以及squid之类的专门做cache的server,可能效果不会那么好。特别如果cache内容比较大的话。不过还有一种折衷的处理,那就是挂载一个内存盘,然后让nginx cache到这个盘。

我这里的看的代码是1.1.17.

首先来看Nginx中如何开启cache,http cache主要是应用在upstream中的,因此upstream对应的两个命令来启用cache,一个是xxx_cache_path(比如proxy_cache_path),它主要是用来创建管理cache的共享内存数据结构(红黑树和队列).一个是xxx_cache,它主要是使用前面创建的zone。

先来看第一个命令,xxx_cache_path,它会调用ngx_http_file_cache_set_slot函数,在看这个函数之前,先来看ngx_http_file_cache_t这个数据结构,它主要用来管理所有的cache文件,它本身不保存cache,只是保存管理cache的数据结构。每一个xxx_cache_path都会创建一个ngx_http_file_cache_t.
阅读全文…

Share
分类: nginx, server 标签: , ,

nginx中upstream的设计和实现(五)

2011年8月17日 2 条评论

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

本文链接地址: nginx中upstream的设计和实现(五)

这次主要来分析upstream中的发送数据给client, 以及当buf不足,将一部分写到temp file的部分,他们对应的函数分别是ngx_event_pipe_write_to_downstream和ngx_event_pipe_write_chain_to_temp_file.

先来看ngx_event_pipe_write_to_downstream,这个函数顾名思义,就是写buf到临时文件。而所写的buf就是p->in,也就是将要发送给client的数据。
这个函数,它会处理两类的情况,一类是cache打开,一类是cache未打开。我们这里主要来分析cache关闭的情况。

首先来看这个函数的第一部分的代码,这部分代码主要是遍历p->in,然后计算能写多少buf到文件(temp file的size是有限制的).

//out就是将要保存到file的数据
    if (p->buf_to_file) {
//cache打开的情况
        fl.buf = p->buf_to_file;
        fl.next = p->in;
        out = &fl;

    } else {
//得到数据
        out = p->in;
    }
//如果cache没有打开
    if (!p->cacheable) {

        size = 0;
        cl = out;
        ll = NULL;

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
                       "pipe offset: %O", p->temp_file->offset);
//开始遍历out
        do {
//计算大小
            bsize = cl->buf->last - cl->buf->pos;
.....................................................
//看是否超过限制限制
            if ((size + bsize > p->temp_file_write_size)
               || (p->temp_file->offset + size + bsize > p->max_temp_file_size))
            {
                break;
            }

            size += bsize;
            ll = &cl->next;
            cl = cl->next;

        } while (cl);

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "size: %z", size);

        if (ll == NULL) {
            return NGX_BUSY;
        }
//cl存在则说明只有一部分buf能够写入到temp file,此时p->in保存剩下的chain
        if (cl) {
           p->in = cl;
           *ll = NULL;

        } else {
//否则说明所有的buf都写入到了temp file,此时p->in则设置为空
           p->in = NULL;
           p->last_in = &p->in;
        }

    } else {
//cache打开的情况,可以看到和上面类似.
        p->in = NULL;
        p->last_in = &p->in;
    }

阅读全文…

Share
分类: nginx, server 标签: , ,

nginx中upstream的设计和实现(二)

2011年4月14日 没有评论

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

本文链接地址: nginx中upstream的设计和实现(二)

这次主要来看upstream的几个相关的hook函数。

首先要知道,对于upstream,同时有两个连接,一个时client和nginx,一个是nginx和upstream,这个时候就会有两个回调,然后上篇blog中,我们能看到在upstream中,会改变read_event_handler和write_event_handler,不过这里有三个条件,分别是
1 没有使用cache,
2 不忽略client的提前终止
3 不是post_action

//条件赋值
    if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
//然后给读写handler赋值
        r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
        r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
    }

阅读全文…

Share

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的启动流程分析(二)

2011年1月21日 1 条评论

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

本文链接地址: nginx的启动流程分析(二)

接上篇,这篇主要来看nginx的网络部分的初始化

首先是ngx_http_optimize_servers函数,这个函数是在ngx_http_block中被调用的,它的主要功能就是创建listening结构,然后初始化。这里ngx_listening_t表示一个正在监听的句柄以及它的上下文。

static ngx_int_t
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
    ngx_array_t *ports)
{
    ngx_uint_t             p, a;
    ngx_http_conf_port_t  *port;
    ngx_http_conf_addr_t  *addr;

    if (ports == NULL) {
        return NGX_OK;
    }

    port = ports->elts;
    for (p = 0; p < ports->nelts; p++) {
..................................................
//初始化listen结构
        if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}

阅读全文…

Share