nginx 学习笔记

23 篇文章 0 订阅

内存池

struct mp_large_s {
	struct mp_large_s *next;
	void *alloc;
};

struct mp_node_s {

	unsigned char *last;
	unsigned char *end;
	
	struct mp_node_s *next;
	size_t failed;
};

struct mp_pool_s {

	size_t max;

	struct mp_node_s *current;
	struct mp_large_s *large;

	struct mp_node_s head[0]; //零长数组

};

内存池维护节点(node)和大块内存链表,每个节点维护一块固定大小为block_size的内存,节点的end-last为当前节点剩余可分配的内存。初始化的时候,先用posix_memalign分配一块sizeof(struct mp_pool_s) + sizeof(struct mp_node_s)+block_size 的内存, 并转为pool指针。因为pool里的head是一个节点类型的零长数组,它会自动把sizeof(struct mp_pool_s)到sizeof(struct mp_pool_s)+sizeof(struct mp_node_s)这一段的内存当做一个节点。

当我们想从pool中取出一段小于block_size的内存时,需要通过节点的next指针,从当前current节点开始,遍历并找到第一个剩余内存够的节点。若找不到则在尾端插入一个新节点。为了减少遍历的节点数,如果current节点在以前的查找中已经访问了4次,则跳过他使它的next节点为current节点,下次遍历从这个节点开始。

http 入口

ngx_string(“http”)
ngx_http_block
ngx_http_optimize_servers
ngx_http_init_listening
ngx_http_add_listening
ngx_http_init_connection(handler)
ngx_http_wait_request_handle(handler)
ngx_http_process_request_line
ngx_http_process_request_headers
ngx_http_process_request
ngx_http_handler
ngx_http_core_run_phases

在这里插入图片描述

phase

11个阶段处理HTTP请求

/**
 * 11个阶段处理HTTP请求
 */
void
ngx_http_core_run_phases(ngx_http_request_t *r)
{
    ngx_int_t                   rc;
    ngx_http_phase_handler_t   *ph;
    ngx_http_core_main_conf_t  *cmcf;
 
    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
 
    ph = cmcf->phase_engine.handlers;
 
    /* 遍历解析和处理各个阶段的HTTP请求 如果返回rc==NGX_AGAIN 则交由下一个阶段处理;返回OK则返回结果  */
    while (ph[r->phase_handler].checker) {
 
		rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
 
        if (rc == NGX_OK) {
            return;
        }
    }
}
 
/**
 * 内容接收阶段
 */
ngx_int_t
ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
{
    ngx_int_t  rc;
 
    /*
     * generic phase checker,
     * used by the post read and pre-access phases
     */
 
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "generic phase: %ui", r->phase_handler);
 
    /* handler 回调函数*/
    rc = ph->handler(r);
 
    /* 本阶段处理完成,跳转到下一个阶段处理 */
    if (rc == NGX_OK) {
        r->phase_handler = ph->next;
        return NGX_AGAIN;
    }
 
    /* 本阶段当前的回调函数处理完成,继续执行本阶段其他回调函数 */
    if (rc == NGX_DECLINED) {
        r->phase_handler++;
        return NGX_AGAIN;
    }
 
    if (rc == NGX_AGAIN || rc == NGX_DONE) {
        return NGX_OK;
    }
 
    /* rc == NGX_ERROR || rc == NGX_HTTP_...  */
 
    ngx_http_finalize_request(r, rc);
 
    return NGX_OK;
}

挂载自定义模块

    /**
     * 模块初始化
     */
    static ngx_int_t
    ngx_http_static_init(ngx_conf_t *cf)
    {
        ngx_http_handler_pt        *h;
        ngx_http_core_main_conf_t  *cmcf;
     
        cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
        /* 注册到NGX_HTTP_CONTENT_PHASE阶段 */
        h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
        if (h == NULL) {
            return NGX_ERROR;
        }
     
        /* 设置阶段回调函数 */
        *h = ngx_http_static_handler;
     
        return NGX_OK;
    }

惊群

Nginx中使用mutex互斥锁解决这个问题,具体措施有使用全局互斥锁,每个子进程在epoll_wait()之前先去申请锁,申请到则继续处理,获取不到则等待,并设置了一个负载均衡的算法(当某一个子进程的任务量达到总设置量的7/8时,则不会再尝试去申请锁)来均衡各个进程的任务量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值