存档

文章标签 ‘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配置文件解析详解

2012年4月28日 1 条评论

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

本文链接地址: Nginx配置文件解析详解

Nginx的配置解析相关的部分比较绕,比如为何要有4重指针,比如NGX_MAIN_CONF , loc_conf,NGX_DIRECT_CONF有什么区别呢?这些我前面的blog都有些涉及,这次主要是把配置这块完全拿出来然后来分析下。

首先来看配置解析时的数据结构,这里主要是ngx_conf_t,这个结构保存了解析配置文件所需要的一些域,这个是非常重要的一个数据结构,我们详细来看这个结构:

struct ngx_conf_s {
//当前解析到的命令名
    char                 *name;
//当前命令的所有参数
    ngx_array_t          *args;

//使用的cycle
    ngx_cycle_t          *cycle;
//所使用的内存池
    ngx_pool_t           *pool;
//这个pool将会在配置解析完毕后释放。
    ngx_pool_t           *temp_pool;
//这个表示将要解析的配置文件
    ngx_conf_file_t      *conf_file;
//配置log
    ngx_log_t            *log;

//主要为了提供模块的层次化(后续会详细介绍)
    void                 *ctx;
//模块类型
    ngx_uint_t            module_type;
//命令类型
    ngx_uint_t            cmd_type;

//模块自定义的handler
    ngx_conf_handler_pt   handler;
//自定义handler的conf
    char                 *handler_conf;
};

阅读全文…

Share

hotwheels源码剖析

2012年4月8日 1 条评论

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

本文链接地址: hotwheels源码剖析

在霸爷的推荐下,看了hotwheels的代码,接下来我就来分析下hotwheels的代码(主要是server端代码),hotwheels是干吗的呢,介绍在这里:
https://github.com/tolbrino/hotwheels

Janus is a messaging server optimized to unicast over TCP to thousands of clients subscribed to topics of interest.

The ultimate goal is to maintain a latency of less than 2 seconds for 20 thousand clients on Amazon EC2 (small instance).

首先来看janus.app:

{application, janus,
 [{description, "Janus"},
  {vsn, "0.0.1"},
  {id, "janus"},
  {modules, [barrier,
             bin,
             bot,
             client_proxy,
             common,
             flashbot,
             histo,
             janus,
             janus_acceptor,
             janus_admin,
             janus_app,
             janus_flash,
             launcher,
             mapper,
             pubsub,
             topman,
             t,
             transport,
             util
            ]},
  {registered, [janus_sup, 
                janus_topman_sup,
                janus_proxy_mapper_sup,
                janus_transport_sup,
                janus_listener]},
  {applications, [kernel, 
                  stdlib, 
                  mnesia,
                  inets
                 ]},
  {mod, {janus_app, []}},
  {env, []}
 ]
}.

阅读全文…

Share
分类: erlang, 源码阅读 标签: ,

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中request buf的设计和实现

2011年2月9日 没有评论

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

本文链接地址: nginx中request buf的设计和实现

在nginx中request的buffer size我们能够通过两个命令进行设置,分别是large_client_header_buffers和client_header_buffer_size。这两个是有所不同的。
在解析request中,如果已经读取的request line 或者 request header大于lient_header_buffer_size的话,此时就会重新分配一块大的内存,然后将前面未完成解析的部分拷贝到当前的大的buf中,然后再进入解析处理,这部分的buf也就是large_client_header_buffers,也叫做large hader的处理。接下来我会通过代码来详细的分析这个过程。
阅读全文…

Share
分类: nginx, server 标签: ,

nginx中http request处理的流程

2011年1月25日 2 条评论

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

本文链接地址: nginx中http request处理的流程

这次主要来看nginx如何处理一个http的流程,也就是接收请求,解析,然后接收完毕,然后开始发送数据,这一系列是如何流转起来的,通过上2篇,我们知道了nginx初始化完毕之后会休眠在epoll(或者kqueue等等).
下面就是nginx的事件处理流程图.

ngx_request
阅读全文…

Share
分类: nginx, server 标签: ,

nginx的启动流程分析(一)

2011年1月6日 1 条评论

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

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

这篇我们会主要来分析配置文件相关的一些初始化,而在下一篇我们会详细分析http协议相关,以及socket的初始化信息。

nginx启动最重要的部分是在ngx_init_cycle中,我们接下来就会详细的分析这个函数,以及相关的函数.

下面就是ngx_init_cycle的流程图
nginx_cycle
阅读全文…

Share
分类: nginx, server, 源码阅读 标签: ,

nginx对静态文件cache的处理

2010年10月20日 2 条评论

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

本文链接地址: nginx对静态文件cache的处理

nginx中对静态文件进行了cache,对应的命令就是open_file_cache,open_file_cache_min_uses以及open_file_cache_valid。这次我就来分析下nginx如何对静态文件进行cache的。

要注意一个就是open_file_cache的 inactive表示文件多久不被访问就会从cache中删除.

首先来描述一下linux下是如何做的,因为这里nginx对于bsd版本有一个不同的做法,这是因为bsd中可以给kqueue监听文件改变的事件。而linux下,nginx并没有使用inotify,而是每次都会判断文件的st_ino来得到文件是否被修改,不过这样会有个缺点就是如果你是使用open,然后write来修改文件的话,文件其实是相同的,因此st_ino是相同的,此时nginx是无法知道的,因此修改的话,最好使用会先删除再覆盖的命令(比如cp)。

首先,nginx的cache只是cache句柄,因为静态文件的发送,一般来说,nginx都是尽量使用sendfile进行发送的,因此之需要cache句柄就够了。

所有的cache对象包含在两个数据结构里面,整个机制最关键的也是这两个东西,一个是红黑树,一个是一个队列,其中红黑树是为了方便查找(需要根据文件名迅速得到fd),而队列为了方便超时管理(按照读取顺序插入,在头的就是最近存取的文件),由于所有的句柄的超时时间都是一样的,因此每次只需要判断最后几个元素就够了,因为这个超时不需要那么实时.

假设现在客户端请求是GET test.html HTTP/1.1 ,则nginx是这么处理的,如果test.html在cache中存在,则从cache中取得这个句柄,然后正常返回,如果test.html不存在,则是打开这个文件,然后插入到cache中。不过这里有很多细节都需要处理,比如超时,比如红黑树的插入等等,接下来,我们就对照着代码来看这些都是如何处理的。

阅读全文…

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

nginx 0.8.x稳定版对linux aio的支持

2010年9月29日 4 条评论

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

本文链接地址: nginx 0.8.x稳定版对linux aio的支持

前几天nginx的0.8.x正式成为stable,然后看了下代码,发现0.8加入了linux native aio的支持,我们知道在linux下有两种aio,一种是glibc实现的aio,这个比较烂,它是直接在用户空间用pthread进行模拟的。还有一种就是内核实现的aio,这些系统调用是以io_xxx开始的,而在nginx的0.8 中使用的是后一种,下面我们简称后一种为native aio.这里注意native aio只支持direct io。
阅读全文…

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