当前位置:文档之家› Nginx源代码分析

Nginx源代码分析

Nginx源代码分析
Nginx源代码分析

Nginx源代码分析

1.Nginx代码的目录和结构

nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清晰,是一个大型服务端软件构建的一个范例。以下是源码目录结构说明:

├─auto 自动编译安装相关目录

│├─cc 针对各种编译器进行相应的编译配置目录,包括Gcc、Ccc等

│├─lib 程序依赖的各种库,包括md5,openssl,pcre等

│├─os 针对不同操作系统所做的编译配置目录

│└─types

├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等

├─contrib

├─html index.html

└─src 源码目录

├─core 核心源码目录,包括定义常用数据结构、体系结构实现等

├─event 封装的事件系统源码目录

├─http http服务器实现目录

├─mail 邮件代码服务器实现目录

├─misc 该目录当前版本只包含google perftools包

└─os nginx对各操作系统下的函数进行封装以及实现核心调用的目录。2.基本数据结构

2.1.简单的数据类型

在core/ngx_config.h 目录里面定义了基本的数据类型的映射,大部分都映射到c语言自身的数据类型。

typedef intptr_t ngx_int_t;

typedef uintptr_t ngx_uint_t;

typedef intptr_t ngx_flag_t;

其中ngx_int_t,nginx_flag_t,都映射为intptr_t;ngx_uint_t映射为uintptr_t。

这两个类型在/usr/include/stdint.h的定义为:

/* Types for `void *' pointers. */

#if __WORDSIZE == 64

# ifndef __intptr_t_defined

typedef long int intptr_t;

# define __intptr_t_defined

# endif

typedef unsigned long int uintptr_t;

#else

# ifndef __intptr_t_defined

typedef int intptr_t;

# define __intptr_t_defined

# endif

typedef unsigned int uintptr_t;

#endif

所以基本的操作和整形/指针类型的操作类似。

2.2.字符串的数据类型

nginx对c语言的字符串类型进行了简单的封装,core/ngx_string.h/c里面包含这些封装的内容。

其中定义了ngx_str_t,ngx_keyval_t,ngx_variable_value_t这几个基础类型的定义如下:

typedef struct{

size_t len;

u_char *data;

} ngx_str_t;

typedef struct{

ngx_str_t key;

ngx_str_t value;

} ngx_keyval_t;

typedef struct{

unsigned len:28;

unsigned valid:1;

unsigned no_cacheable:1;

unsigned not_found:1;

unsigned escape:1;

u_char *data;

} ngx_variable_value_t;

可以看出ngx_str_t 在原有的uchar* 的基础上加入的字符串长度的附加信息,初始化使用ngx_string宏进行,他的定义为:

#define ngx_string(str){sizeof(str)-1,(u_char *) str }

2.3.内存分配相关

(1)系统功能封装

内存相关的操作主要在os/unix/ngx_alloc.{h,c} 和core/ngx_palloc.{h,c} 下。

其中os/unix/ngx_alloc.{h,c} 封装了最基本的内存分配函数,是对c原有的malloc/free/memalign 等原有的函数的封装,对应的函数为:

?ngx_alloc 使用malloc分配内存空间

?ngx_calloc 使用malloc分配内存空间,并且将空间内容初始化为0

?ngx_memalign 返回基于一个指定的alignment大小的数值为对齐基数的空间

?ngx_free 对内存的释放操作

(2)Nginx的内存池

为了方便系统模块对内存的使用,方便内存的管理,nginx自己实现了进程池的机制来进行内存的分配和释放,首先nginx会在特定的生命周期帮你统一建立内存池,当需要进行内存分配的时候统一通过内存池中的内存进行分配,最后nginx会在适当的时候释放内存池的资源,开发者只要在需要的时候对内存进行申请即可,不用过多考虑内存的释放等问题,大大提高了开发的效率。

内存池的主要结构为:

//ngx_palloc.h

struct ngx_pool_s {

ngx_pool_data_t d;

size_t max;

ngx_pool_t *current;

ngx_chain_t *chain;

ngx_pool_large_t *large;

ngx_pool_cleanup_t *cleanup;

ngx_log_t *log;

};

//ngx_core.h

typedef struct ngx_pool_s ngx_pool_t;

typedef struct ngx_chain_s ngx_chain_t;

下面解释一下主要的几个操作:

// 创建内存池

ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);

大致的过程是创建使用ngx_alloc 分配一个size大小的空间, 然后

将 ngx_pool_t* 指向这个空间,并且初始化里面的成员, 其中

p->https://www.doczj.com/doc/1d4029930.html,st=(u_char *) p +sizeof(ngx_pool_t);// 初始指向ngx_pool_t 结构体后面

p->d.end=(u_char *) p + size;// 整个结构的结尾后面

p->max =(size < NGX_MAX_ALLOC_FROM_POOL)? size : NGX_MAX_ALLOC_FROM_POOL;

// 最大不超过NGX_MAX_ALLOC_FROM_POOL,也就是getpagesize()-1 大小

其他大都设置为null或者0

// 销毁内存池

void ngx_destroy_pool(ngx_pool_t *pool);

遍历链表,所有释放内存,其中如果注册了clenup(也是一个链表结构),会一次调用clenup 的handler 进行清理。

// 重置内存池

void ngx_reset_pool(ngx_pool_t *pool);

释放所有large段内存,并且将d->last指针重新指向ngx_pool_t 结构之后(和创建时一样)

// 从内存池里分配内存

void*ngx_palloc(ngx_pool_t *pool, size_t size);

void*ngx_pnalloc(ngx_pool_t *pool, size_t size);

void*ngx_pcalloc(ngx_pool_t *pool, size_t size);

void*ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);

ngx_palloc的过程一般为,首先判断待分配的内存是否大于pool->max的大

小,如果大于则使用ngx_palloc_large 在large 链表里分配一段内存并返回,如果小于测尝试从链表的pool->current 开始遍历链表,尝试找出一个可以分配的内存,当链表里的任何一个节点都无法分配内存的时候,就调用ngx_palloc_block 生成链表里一个新的节点,并在新的节点里分配内存并返回,同时,还会将pool->current 指针指向新的位置(从链表里面pool->d.failed小于等于4的节点里找出),其他几个函数也基本上为ngx_palloc 的变种,实现方式大同小异

// 释放指定的内存

ngx_int_t ngx_pfree(ngx_pool_t *pool,void*p);

这个操作只有在内存在large链表里注册的内存在会被真正释放,如果分配的是普通的内存,则

会在destory_pool的时候统一释放.

// 注册cleanup回叫函数(结构体)

ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);

这个过程和我们之前经常使用的有些区别,他首先在传入的内存池中分配这个结构的空间(包括data段),然后将为结构体分配的空间返回,通过操作返回的ngx_pool_cleanup_t结构来添加回叫的实现。(这个过程在nginx里面出现的比较多,也就是xxxx_add 操作通常不是实际的添加操作,而是分配空间并返回一个指针,后续我们还要通过操作指针指向的空间来实现所谓的add)

2.4.Nginx的基本容器

(1)ngx_array

对应的文件为core/ngx_array.{c|h}

ngx_array是nginx内部封装的使用ngx_pool_t对内存池进行分配的数组容器,其中的数据是在一整片内存区中连续存放的。更新数组时只能在尾部压入1个或多个元素。

数组的实现结构为:

struct ngx_array_s {

void*elts;

ngx_uint_t nelts;

size_t size;

ngx_uint_t nalloc;

ngx_pool_t *pool;

};

其中elts 为具体的数据区域的指针,nelts 为数组实际包含的元素数量,

size为数组单个元素的大小,nalloc为数组容器预先(或者重新)分配的内存大小,pool 为分配基于的内存池

常用的操作有:

// 创建一个新的数组容器

ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);

// 销毁数组容器

void ngx_array_destroy(ngx_array_t *a);

// 将新的元素加入数组容器

void*ngx_array_push(ngx_array_t *a);

void*ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);//返回n个元素的指针

这里需要注意的是,和之前的ngx_pool_cleanup_add一样,ngx_array_push 只是进行内存分配的操作,我们需要对返回的指针指向的地址进行赋值等操作来实现实际数组值的添加。

具体一点的push操作的实现为:

1.首先判断nalloc是否和nelts相等,即数组预先分配的空间已经满了,

如果没满则计算地址直接返回指针

2.如果已经满了则先判断是否我们的pool中的当前链表节点还有剩余的空

间,如果有则直接在当前的pool链表节点中分配内存,并返回

3.如果当前链表节点没有足够的空间则使用ngx_palloc重新分配一个2倍于

之前数组空间大小的数组,然后将数据转移过来,并返回新地址的指针

(2)ngx_queue

ngx_queue.{c,h} 实现了一个队列的操作逻辑,队列的基本结构为一个双向队列

基础的数据结构为:

typedef struct ngx_queue_s ngx_queue_t;

struct ngx_queue_s {

ngx_queue_t *prev;

ngx_queue_t *next;

};

注意nginx的队列操作和结构只进行指针的操作,不负责节点内容空间的分配和保存,所以在定义自己的队列节点的时候,需要自己定义数据结构以及分配空间,并包含一个ngx_queue_t类型的成员, 需要获得原始的数据节点的时候需要使用ngx_queue_data宏:

#define ngx_queue_data(q, type, link)\

(type *)((u_char *) q - offsetof(type, link))

另外,整个queue结构中包含一个sentinel(哨兵)节点,他指向队列的头和尾。

(3)ngx_hash

ngx_hash.{c|h} 实现了nginx里面比较重要的一个hash结构,这个在模块配置解析里经常被用到。该hash 结构是只读的,即仅在初始创建时可以给出保存在其中的key-val 对,其后就只能查询而不能进行增删改操作了。

下面是简单hash 结构的内存布局:

虽然代码理解起来比较混乱,但是使用还是比较简单的,常用的有创建hash 和在hash 中进行查找两个操作,对于创建hash的操作,过程一般为:

1.构造一个ngx_hash_key_t 为成员的数组,包含key, value 和使用key

计算出的一个hash值

2.构建一个ngx_hash_init_t结构体的变量,其中包含了ngx_hash_t 的成

员,为hash的结构体,还包括一些其他初始设置,如bucket的大小,内存池等

3.调用ngx_hash_init 传入ngx_hash_init_t 结构,ngx_hash_key_t 的数组,

和数组的长度,进行初始化,这样ngx_hash_init_t的hash成员就是我

们要的hash结构

查找的过程很简单

1.计算key 的hash值

2.使用ngx_hash_find 进行查找,需要同时传入hash值和key ,返回的就是

value的指针

需要注意的是,nginx 的hash 在查找时使用的是分桶后线性查找法,因此当分桶数确定时查找效率同其中的总key-val 对数量成反比。

(4)ngx_list

ngx_list 的结构并不复杂,ngx为我们封装了ngx_list_create, ngx_list_init, 和ngx_list_push等(建立,初始化,添加)操作,但是对于我们来说最常用的是遍历操作,下面是nginx的注释里面提到的遍历的例子

part =&list.part;

data = part->elts;

for(i =0;; i++){

if(i >= part->nelts){

if(part->next== NULL){

break;

}

part = part->next;

data = part->elts;

i =0;

}

... data[i]...

}

(5)ngx_buf

对应的文件为core/ngx_buf.{c|h}

buf分为两种类型,一种是file,一种是memory.因此这里会有文件的一些操作域。

可以看到buf相对于pool多了一个pos域(file_pos).这里我们要知道我们发送往套接字异或者其他的设备,我们这里会现将数据放到buf中,然后当设备或者套接字准备好了,我们就会从buf中读取,因此这里pos指针就是放到buf中的已经被执行的数据(也就是已经送往套接字)的位置。

struct ngx_buf_s {

///pos表示已经执行的数据的位置。

u_char *pos;

///last和上面内存池中last一样,也就是使用的内存的最后一个字节的指针u_char *last;

///文件指针

off_t file_pos;

off_t file_last;

///buf的开始指针

u_char *start; /* start of buffer */

u_char *end; /* end of buffer */

///这里表示这个buf从属于那个模块。

ngx_buf_tag_t tag;

ngx_file_t *file;

ngx_buf_t *shadow;

///一些标记

/* the buf's content could be changed */

unsigned temporary:1;

///在内存中是不能改变的。

unsigned memory:1;

///是否是mmap的内存

unsigned mmap:1;

unsigned recycled:1;

///是否文件。

unsigned in_file:1;

unsigned flush:1;

unsigned sync:1;

unsigned last_buf:1;

unsigned last_in_chain:1;

unsigned last_shadow:1;

unsigned temp_file:1;

/* STUB */ int num;

};

3.nginx的core module 的结构和运行机制

3.1.ngx_init_cycle

其中一个比较重要的函数调用是,ngx_init_cycle, 这个是使用kscope输出的他的调用关系,他被main, ngx_master_process_cycle,ngx_single_process_cycle 调用,其中后两者是在reconfigure的时候被调用的

他主要做了如下几件事情:

初始化cycle是基于旧有的cycle进行的,比如这里的init_cycle,会继承old cycle的很多属性,比如log等,但是同时会对很多资源重新分配,比如pool, shared mem, file handler, listening socket 等,同时清除旧有的cycle的资源

另外,ngx_master/single_process_cycle 里面会对init_process进行调用,并且循环调用ngx_process_events_and_timers ,其中里面会调用

ngx_process_events(cycle, timer, flags); 对事件循环进行polliing 时间一般默认为500 ms。

Nginx的OS module的结构和运行机制

4.nginx的http module 的结构和运行机制

HTTP相关的Module都在src/http 目录和其子目录下,其中src/http 下的文件为http模块的核心文件,src/http/modules 下的文件为http模块的扩展模块。

4.1.ngx_http.[c|h]

ngx_http.c 中,注册了http 这个指令的处理模块,对应ngx_http_block函数

static ngx_command_t ngx_http_commands[]={

{ ngx_string("http"),

NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,

ngx_http_block,

0,

0,

NULL },

ngx_null_command

};

这个函数里面会进行一些conf资源分配/Merge,配置文件解析等工作。这里面有个一比较重要的工作是注册了nginx http 的phase handler

if(ngx_http_init_phase_handlers(cf, cmcf)!= NGX_OK){

return NGX_CONF_ERROR;

}

phase handler的类型在ngx_http_core_module 这里定义:

typedef enum{

NGX_HTTP_POST_READ_PHASE =0,

NGX_HTTP_SERVER_REWRITE_PHASE,

NGX_HTTP_FIND_CONFIG_PHASE,

NGX_HTTP_REWRITE_PHASE,

NGX_HTTP_POST_REWRITE_PHASE,

NGX_HTTP_PREACCESS_PHASE,

NGX_HTTP_ACCESS_PHASE,

NGX_HTTP_POST_ACCESS_PHASE,

NGX_HTTP_TRY_FILES_PHASE,

NGX_HTTP_CONTENT_PHASE,

NGX_HTTP_LOG_PHASE

} ngx_http_phases;

每一个phase的handlers 都是一个数组,里面可以包含多个元素,通过ngx_array_push 添加新的handler。

其中每个phase的处理大都包含了对ngx_request_t 的write 或者read event的改写,其中在ngx_http_core_content_phase 里面,有对location handler 的调用,其中的r->content_handler 就是运行时刻从location handler中注册的,

if(r->content_handler){

r->write_event_handler = ngx_http_request_empty_handler;

ngx_http_finalize_request(r, r->content_handler(r));/*实际的请求发送处理*/

return NGX_OK;

}

其中,在各个phase的结束阶段,一般都是调用

r->phase_handler++;

return NGX_AGAIN;

移动request 中phase_handler的指针,并且示意主程序继续进行。

这里,无论是phase handler,还是location handler,我们都是可以在程序里进行注册的。

另外,ngx_http_block 里面调用了ngx_http_optimize_servers ,这个函数对listening和connection相关的变量进行了初始化和调优,并最终在

ngx_http_add_listening (被ngx_http_add_listening调用)中注册了listening 的handler 为ngx_http_init_connection

ls->handler = ngx_http_init_connection;

ngx_http_init_connection 在ngx_http_request.c中定义,后续会进行详细的介绍。

4.2.ngx_http_request.[c|h]

这里面,ngx_http_init_connection 注册了connection事件的读操作的回叫函数,并将写操作设置为空函数

rev = c->read;

rev->handler = ngx_http_init_request;

c->write->handler = ngx_http_empty_handler;

当新的连接进入的时候,就执行到ngx_http_init_request, 开始对后面的流程进行处理,主要是将rev的handler 设置为ngx_http_process_request_line ,然后ngx_http_process_request_line 会先后有调度到

ngx_http_process_request_headers 和ngx_http_process_request 函数对读取过来的event进行处理,其中,ngx_http_process_request_headers 里面会对http 的请求头进行解析,ngx_http_process_request 设置event handler 到

ngx_http_request_handler ,ngx_http_request_handler 中会根据事件可能是读取还是写入的操作分别调用request 的read_event_handler 和

write_event_handler ,所以后续程序对request 的read/writeevent_handler 调整本质上类似对rev 和wev的handler的调整,只是回叫函数的参数变更为了ngx_request_t 而不是之前的ngx_event_t

c->read->handler = ngx_http_request_handler;

c->write->handler = ngx_http_request_handler;

r->read_event_handler = ngx_http_block_reading;

根据上面代码可以看出,模块开始使用ngx_http_block_reading 这个

handler对后续的读请求进行处理

在注册完事件后,ngx_http_process_request 会分别调用下面的两个函数

ngx_http_handler(r);

ngx_http_run_posted_requests(c);

其中,ngx_http_handler 在ngx_http_core_module中定义,处理程序的主请求,ngx_http_run_posted_requests 在ngx_http_request.c 里定义,处理所有提交的子请求数据的输出。

4.3.ngx_http_core_module.[c|h]

对于ngx_http_core_module 是http 模块中比较重要的模块,他本身是一个NGX_HTTP_MODULE (不同于ngx_http_module, ngx_http_module本质上是一个NGX_CORE_MODULE。

这里面对http block下面的一些指令进行了处理,比如server, location 等,同时,上面提到的ngx_http_handler 也在这里面。

ngx_http_handler 所作的最核心的工作就是在最后调用并将write event

设置为ngx_http_core_run_phases,开始依次处理各个阶段的handler。

当handler处理完成后,http的处理流程也就基本上完成了:

while(ph[r->phase_handler].checker){

rc = ph[r->phase_handler].checker(r,&ph[r->phase_handler]);

if(rc == NGX_OK){

return;

}

}

run_phases 的过程实际上非常简单,一次的运行每一个handler, 当任意一个handler返回ok或者所有handler执行完成后,整个流程结束。

这里需要注意的是,ph的下标变化是根据r->phase_handler 变量决定的,所以在每个handler内部,如果想要让主程序继续处理下一个handler,需要手动的r->phase_handler++ ,将phase handler数组的下标转移到下一个成员。

4.4.subrequest

在ngx_http_core_module 里面,我们可以看到一些subrequest的函数,根据evan miller 的文章,我们知道subrequest是在主请求的基础上发起的子请求,subrequest返回的内容会被附加到自请求上面,他的实现方法就是调用

ngx_http_subrequest 函数,subrequest函数的圆形是

ngx_int_t

ngx_http_subrequest(ngx_http_request_t *r,

ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,

ngx_http_post_subrequest_t *ps, ngx_uint_t flags)

在里面,在这个函数里,他会

1)创建新的request变量,根据主request的值去填充这个变量

2)注册新的变量的write event handler

sr->read_event_handler = ngx_http_request_empty_handler;

sr->write_event_handler = ngx_http_handler;

3) 并且把subrequet 的request 注册到主request的posted_requests 变量里

for(p =&r->main->posted_requests;*p; p =&(*p)->next){/* void */}也就是说,一但调用了ngx_http_subrequest 只后,subrequest已经已经注册到了nginx的事件循环中,和主循环并行进行处理,所以根据evan miller的文章里我们也可以看到,subrequest的串行处理是比较困难的。

4.5.internal redirect

nginx的internal redirect 有两种方式,一个是调用

ngx_http_internal_redirect 命令,一个是使用X-Accel-Redirect 头,其中

X-Accel-Redirect 头是交由upstream模块进行的,在

ngx_http_upstream_process_headers函数中,我们可以看到

if(u->headers_in.x_accel_redirect

&&!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT)) {

.....

.....

ngx_http_internal_redirect(r, uri,&args);

return NGX_DONE;

}

也就是说,本质上,这两种方法都是通过ngx_http_internal_redirect 的函数实现的,而ngx_http_internal_redirect 函数又做了些什么呢?

r->internal=1;

ngx_http_handler(r);

return NGX_DONE;

可以看到,其实它只是简单的修改request结构体,并通过ngx_http_handler 重新进行http处理流程而已。

关于internal redirect 和subrequest,他们有类似的地方,都是在最后调用ngx_http_handler 重新开始对request的处理,但是不同的地方我想主要是subrequest会新建立一个request结构,原来的request处理并不会结束,而internal redirect会结束当前的请求处理,使用嗯但前的request结构体来发起请求。

4.6.upstream

upstream是nginx里面非常重要的一种处理模式,nginx的很多模块都是使用他来完成的,upstream和普通的handler有很大的不同,比如nginx的location handler 和phase handler, 他们的处理模式非常类似apache的handler,就是获取后同步的进行处理,但是对于有些场合,比如proxy或者fastcgi, nginx进程需要和上游的服务(http,或者php-cgi)进行交互,并且将结果返回给客户端,在交互的过程中,由于后端服务的响应时间各异,如果后端服务的响应时间过长,nginx 等待后端服务响应的过程一之同步阻塞在这里是不现实的,所以nginx采用了异步的方案,每当上游服务器有响应的时候才进行处理,并将处理结果返回给前端,这样nginx在处理上游请求的时候,可以同时注册多个io时间,使用

epoll_wait(linux下默认) 也就是nginx的主事件循环进行处理,大大提高了nginx 的并发能里,每个进程可以处理多个连接,不会因为一个上游连接阻塞整个nginx进程,当然这也有依赖于你程序的实现方式。

关于upstream的使用方式,evan miller的文章里已经说的很清楚了,就是可以在location handler里(或者其它插入点中)注册upstream的一些callback

u->conf =&plcf->upstream;

/* attach the callback functions */

u->create_request = ngx_http_proxy_create_request;

u->reinit_request = ngx_http_proxy_reinit_request;

u->process_header = ngx_http_proxy_process_status_line;

u->abort_request = ngx_http_proxy_abort_request;

u->finalize_request = ngx_http_proxy_finalize_request;

r->upstream = u;

并且最后在调用ngx_http_read_client_request_body 中传入

ngx_http_upstream_init 作为callback function 参数初始化upstream流程, 在ngx_http_upsteam_init 里面,会调用ngx_http_upstream_connect建立连接,并注册读写的event handler

/* event handler 最终会根据读/或者写的请求调用write_event_handler和read_event_handler ,也就是 ngx_http_upstream_send_request_handler和

ngx_http_upstream_process_header */

c->write->handler = ngx_http_upstream_handler;

c->read->handler = ngx_http_upstream_handler;

u->write_event_handler = ngx_http_upstream_send_request_handler;

u->read_event_handler = ngx_http_upstream_process_header;

这里需要注意的是,在处理上游请求的时候,由于是异步的事件,所以每次上游服务器在调用callback的时候并不一定返回的是全部数据,process_header 函数必须根据判断每次返回的数据包是否完成,如果没有处理完成则返回NGX_AGAIN,来指示nginx需要重新进入process_header函数进行处理,并知道处理完成的时候返回NGX_OK 来指示nginx完成处理。具体的例子可以参考fastcgi 模块的ngx_http_fastcgi_process_header函数。

另外,nginx可以针对上游服务的响应body进行处理,通过注册

u->pipe->input_filter 这个回叫来实现,同样可以参考fastcgi模块,下面是例子/* 这里注册对于响应体的处理*/

u->pipe->input_filter = ngx_http_fastcgi_input_filter;

u->pipe->input_ctx = r;

通常在处理的过程中需要自己创建状态机来处理请求的不同状态,对于一些请求相关的信息,可以自己创建结构体,通过

#define ngx_http_get_module_ctx(r,module)(r)->ctx[module.ctx_index]

#define ngx_http_set_ctx(r, c,module) r->ctx[module.ctx_index]= c;

这两个宏进行读取和存储。

nginx源码分析

nginx源码分析 nginx源码分析(1)- 缘起 nginx是一个开源的高性能web服务器系统,事件驱动的请求处理方式和极其苛刻的资源使用方式,使得nginx成为名副其实的高性能服务器。 nginx的源码质量也相当高,作者“家酿”了许多代码,自造了不少轮子,诸如内存池、缓冲区、字符串、链表、红黑树等经典数据结构,事件驱动模型,http解析,各种子处理模块,甚至是自动编译脚本都是作者根据自己的理解写出来的,也正因为这样,才使得nginx比其他的web服务器更加高效。 nginx 的代码相当精巧和紧凑,虽然全部代码仅有10万行,但功能毫不逊色于几十万行的apache。不过各个部分之间耦合的比较厉害,很难把其中某个部分的实现拆出来使用。对于这样一个中大型的复杂系统源码进行分析,是有一定的难度的,刚开始也很难找到下手的入口,所以做这样的事情就必须首先明确目标和计划。 最初决定做这件事情是为了给自己一些挑战,让生活更有意思。但看了几天之后,觉得这件事情不该这么简单看待,这里面有太多吸引人的东西了,值得有计划的系统学习和分析。首先这个系统中几乎涵盖了实现高性能服务器的各种必杀技,epoll、kqueue、master-workers、pool、 buffer……,也涵盖了很多web服务开发方面的技术,ssi、ssl、proxy、gzip、regex、load balancing、reconfiguration、hot code swapping……,还有一些常用的精巧的数据结构实现,所有的东西很主流;其次是一流的代码组织结构和干净简洁的代码风格,尤其是整个系统的命名恰到好处,可读性相当高,很kiss,这种风格值得学习和模仿;第三是通过阅读源码可以感受到作者严谨的作风和卓越的能力,可以给自己增加动力,树立榜样的力量。 另一方面,要达到这些目标难度很高,必须要制定详细的计划和采取一定有效的方法。 对于这么大的一个系统,想一口气知晓全部的细节是不可能的,并且nginx 各个部分的实现之间关系紧密,不可能做到窥一斑而知全身,合适的做法似乎

手把手教你开发Nginx模块

手把手教你开发Nginx模块 前面的哪些话 关于Nginx模块开发的博客资料,网上很多,很多。但是,每篇博客都只提要点,无法"step by step"照着做,对于初次接触Nginx开发的同学,只能像只盲目的蚂蚁瞎燥急!该篇文章没有太多技术深度,只是一步一步说明白Nginx模块的开发过程。 开发环境搭建 工欲善其事,必先利其器。个人推荐Eclipse CDT 作为IDE,原因很简单,代码提示与补全功能很全,完胜Codeblock这类...相信与否,试过就知道。 在ubuntu下搭建开发环境: 安装GCC编译器 apt-get install build-essential 安装pcre/openssl/zlib开发库 apt-get install libpcre3-dev apt-get install libssl-dev apt-get install libzip-dev 必需安装nginx核心模块依赖的pcre,openssl,zilib开发库 安装JRE/Eclipse CDT apt-get install openjdk-8-jre wget http://ftp.yz.yamagata-u.ac.jp/pub/eclipse//technology/epp/downloads/release/neon/R/eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz && tzr -xzvf eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz 下载nginx源码 wget https://www.doczj.com/doc/1d4029930.html,/download/nginx-1.10.1.tar.gz && tar -xzvf nginx-1.10.1.tar.gz 配置CDT Build Environment 添加变量,值Nginx src下各模块路径,用冒号分隔,例如: /root/Workspace/nginx-1.10.1/src/core:/root/Workspace/nginx-1.10.1/src/event:/root/Workspace/nginx-1.10.1/src/http:/root/Workspace/nginx-1.10.1/src/mail:/root/Workspace/n ginx-1.10.1/src/stream:/root/Workspace/nginx-1.10.1/src/os/unix 添加环境变量,创建C项目时自动作为-I选项 image image Nginx模块编译流程 Nginx使用configure脚本分析环境,自动生成objs结果。哪么configure如何编译第三方模块?答案是--add-module指定第三方模块目录,并将目录存为$ngx_addon_dir环境变量。执行$ngx_addon_dir/config脚本,读取模块配置。在config中的环境变量分为2种:小写的本地环境变量,大写的全局环境变量。例如: ngx_addon_name=ngx_http_mytest_module

基于Nginx的Session-sticky技术的软件负载均衡方案原理和实施步骤v1.0-20130929

基于Nginx的Session-sticky技术的软件负载均衡方案原理和实施步骤 [一]、综述 (1)实现原理:用户请求到nginx,基于nginx的nginx-sticky-module模块的session sticky(会话粘滞)实现后端应用服务器的路由选择,再将用户请求提交到后端的tomcat/weblogic/websphere 应用处理并逆向反馈响应。 (2)技术选型: Nginx+ nginx-sticky-module+J2EE中间件(容器)。 (3)应用场景: 本解决方案是基于浏览器的Cookie机制,通过nginx的反向代理机制,将浏览器与后端应用服务器的访问映射关系,作为前端请求转发到实现某个会话内所有用户的请求都访问当相同的后端服务器。 [二]、安装步骤 创建www用户和组,以及主机需要的目录,日志目录 groupadd www useradd -g www www 一、依赖的程序 1. gzip module requires zlib library 2. rewrite module requires pcre library 3. ssl support requires openssl library 二、依赖的程序的安装的方法 1、zlib 现在最新的版本是zlib-1.2.5 官网下载地址:https://www.doczj.com/doc/1d4029930.html,/zlib-1.2.5.tar.gz $tar -xvzf zlib-1.2.5.tar.gz 2、 pcre现在的最新版本是pcre-8.02.tar.gz 官网下载地址:ftp://https://www.doczj.com/doc/1d4029930.html,/pub/software/programming/pcre/pcre- 8.02.tar.gz $tar -xvzf pcre-8.02.tar.gz $cd pcre-8.02 $./configure --prefix=/usr/local/pcre --enable-utf8 --enable-unicode-properties $ make && make install 3、openssl现在最新版本是openssl-1.0.0a.tar.gz 官网下载地址:https://www.doczj.com/doc/1d4029930.html,/source/openssl-1.0.0a.tar.gz $tar zvxf openssl-1.0.0.tar.gz $cd openssl-1.0.0 $./config --prefix=/usr/local/ssl-1.0.0 shared zlib-dynamic enable-camellia $make && make install 4、安装Nginx 1.0.0,这种方法./configure 要带很多参数,大家要注意。 官网下载地址:https://www.doczj.com/doc/1d4029930.html,/ $tar zvxf Nginx 1.0.0.tar.gz $cd Nginx 1.0.0 $./configure --prefix=/usr/local/nginx --with-http_gzip_static_module

Eclipse + nginx module + debug

Liunx下使用Eclipse 开发nginx module,进行单步调试 Author: chuantong.huang@https://www.doczj.com/doc/1d4029930.html, Date:2010-10-26 1)取Nginx最新代码: wget https://www.doczj.com/doc/1d4029930.html,/download/nginx-0.7.67.tar.gz tar -xvf nginx-0.7.67.tar.gz cd nginx-0.7.67 2)建立模块目录与代码 pwd # 进入Nginx源代码目录,如: /home/toon/workspace/nginx-0.7.67 mkdir ngx_module_echo vim ngx_module_echo/config 其内容为: ngx_addon_name=ngx_module_echo HTTP_MODULES="$HTTP_MODULES ngx_module_echo" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_module_echo.c" CORE_LIBS="$CORE_LIBS " vim ngx_module_echo/ngx_module_echo.c 其内容: 参考nginx的echo模块代码,自己google下,或参考以下: https://www.doczj.com/doc/1d4029930.html,/p/ngx_ext.html 3)建立Makefile 利用nginx提供的configrue脚本生成Makefile文件: ./configure --without-http_rewrite_module --without-http-cache --add-module=/home/toon/workspace/nginx-0.7.67/ngx_module_echo/ --with-debug 注意:这里要指定moduel目录(与Nginx源码目录下),还要指定debug编译. BTW:Eclipse 中执行Build project时会执行make clean all,会删除Makefile,故此时应该再执行configure生成Makefile 可以先make一次,编译出objs/nginx文件。

nginx-0.8.38源码探秘

nginx-0.8.38源码探秘 先推荐几个研究nginx源码的好网址: https://www.doczj.com/doc/1d4029930.html,/kenbinzhang/category/603177.aspx https://www.doczj.com/doc/1d4029930.html,/p/nginxsrp/wiki/NginxCodeReview https://www.doczj.com/doc/1d4029930.html,/langwan/blog/category/%D4%B4%C2%EB%B7%D6%CE%F6 网上分析nginx源码的文章很多,但感觉分析的不够具体和完整,而且都是比较老的nginx版本。本源码分析基于nginx-0.8.38版本,力求做到更具体和更完整,这是一种自我学习,希望和对此有兴趣的朋友一起探讨,有不正确的地方,也请各位指正。 那么一切从main开始吧! ngx_get_options函数是main调用的第一个函数,比较简单,它负责分析命令行参数,将相应的值赋给对应的全局变量,其中: 1.ngx_prefix表示nginx的路径前缀,默认为/usr/local/nginx; 2.ngx_conf_file表示nginx配置文件的路径,默认为 /usr/local/nginx/conf/nginx.conf; 3.ngx_test_config表示是否开启测试配置文件,如配置文件的语法是否正确,配置文件是否可正确打开。 ngx_time_init函数格式化nginx的日志时间,包括 ngx_cached_err_log_time,ngx_cached_http_time, ngx_cached_http_log_time,ngx_cached_time。主要操作在ngx_time_update 内,先获取系统当前时间,与之前保存的时间比较(注意slot),如果已经过

nginx配置解析详解(一)

nginx配置解析详解(一) 现在针对nginx源码分析的blog和文章已经很多了,之前我也看过不少,大家的分析都很不错。太多重复的内容就不写了,主要想针对在我分析代码和查阅blog的过程中,发现的一些比较晦涩或者某些细节有待展开讨论的地方,给出我的自己理解和看法,希望跟大家交流和学习。 使用的nginx版本是nginx-1.0.6,我最开始看的代码是0.7.62,新的版本在功能和稳定性上做了很多的工作。在分析的时候,我尽量简单明了,不太重要的地方一带而过,具体地大家可以去读代码。相对复杂或者晦涩的地方,将详细展开。 首先我们从配置文件开始,下面的分析是建立在网友对nginx的配置文件结构有大概熟悉为前提,这样才可以很好的理解代码。这里有必要提醒一点:原始代码目录中 ngx_modules这个结构,是找不到它的定义和初始化,要看到它,你必须执行configure,make,在原来的代码目录下会出现一个objs文件夹,里面的3个文件ngx_auto_config.h,ngx_auto_headers.h,ngx_modules.c,需要在建source insight工程时也包含进去,这样有利于我们把握整个代码结构。有意思的是,nginx的configure文件是作者手工写的,里面有许多管理代码工程的方法,有时间的话,也是值得学习下的。 1.ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle); 配置文件的解析相关的处理主要在ngx_init_cycle函数中被调用。既然如此,我们就先说说ngx_init_cycle函数吧。 它需要一个参数类型为ngx_cycle_t *,返回值也是一个ngx_cycle_t*,与此同时我们注意到参数名为old_cycle,那么这个函数的作用是啥呢?很明显是由old得到一个new。其中ngx_cycle_t的结构保存一些全局的配置和信息。 这个函数具体作用将在reconfig(重读配置文件)的时候得到体现,可以理解为old_cycle 是当前正在使用的配置信息,当配置文件做了某些修改之后,ngx_init_cycle通过old_cycle 中的一些数据,对new_cycle进行一些设置,在经过进一步的配置解析之后,就可以得到一个new cycle。 2.char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) 当我们使用sourceinsight查看这个函数的调用情况时,会发现调用它的地方很多。其实,入口点就在ngx_init_cycle中对ngx_conf_parse调用,后面的所有的调用可以看作是在此之后的递归调用。为什么会是这个样子呢?原因在于nginx是一边读取配置信息,一边解析执行相关的处理,具体一点讲,就是“读一行,执行一行”,一行的定义在这里是指以分号或者是“{”和“}”等结尾的一行,例如:我们解析到http {},我们就调用针对httpblock的处理,在处理的时候我们又会碰到server {},自然就会调用server block的处理。。。以此类推!。

Nginx反向代理服务器的工作原理

最近有打算研读nginx源代码,看到网上介绍nginx可以作为一个反向代理服务器完成负载均衡。所以搜罗了一些关于反向代理服务器的内容,整理综合。 一概述 反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。 通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。 图1 反向代理服务器的基本原理 二反向代理服务器的工作原理 反向代理服务器通常有两种模型,它可以作为内容服务器的替身,也可以作为内容服务器集群的负载均衡器。 1,作内容服务器的替身 如果您的内容服务器具有必须保持安全的敏感信息,如信用卡号数据库,可在防火墙外部设置一个代理服务器作为内容服务器的替身。当外部客户机尝试访问内容服务器时,会将其送到代理服务器。实际内容位于内容服务器上,在防火

墙内部受到安全保护。代理服务器位于防火墙外部,在客户机看来就像是内容服务器。 当客户机向提出请求时,请求将转到代理服务器。然后,代理服务器通过防火墙中的特定通路,将客户机的请求发送到内容服务器。内容服务器再通过该通道将结果回传给代理服务器。代理服务器将检索到的信息发送给客户机,好像代理服务器就是实际的内容服务器(参见图 2)。如果内容服务器返回错误消息,代理服务器会先行截取该消息并更改标头中列出的任何 URL,然后再将消息发送给客户机。如此可防止外部客户机获取内部内容服务器的重定向 URL。 这样,代理服务器就在安全数据库和可能的恶意攻击之间提供了又一道屏障。与有权访问整个数据库的情况相对比,就算是侥幸攻击成功,作恶者充其量也仅限于访问单个事务中所涉及的信息。未经授权的用户无法访问到真正的内容服务器,因为防火墙通路只允许代理服务器有权进行访问。 图2 反向代理服务器作为内容服务器的替身 可以配置防火墙路由器,使其只允许特定端口上的特定服务器(在本例中为其所分配端口上的代理服务器)有权通过防火墙进行访问,而不允许其他任何机器进出。 2,作为内容服务器的负载均衡器 可以在一个组织内使用多个代理服务器来平衡各 Web 服务器间的网络负载。在此模型中,可以利用代理服务器的高速缓存特性,创建一个用于负载平衡的服务器池。此时,代理服务器可以位于防火墙的任意一侧。如果 Web 服务器每天都会接收大量的请求,则可以使用代理服务器分担 Web 服务器的负载并提高网络访问效率。 对于客户机发往真正服务器的请求,代理服务器起着中间调停者的作用。代理服务器会将所请求的文档存入高速缓存。如果有不止一个代理服务器,DNS 可

NGINX 介绍

优点 Nginx性能概述 常见问题(FAQ) 安装Nginx 优点 Nginx性能概述 常见问题(FAQ) 安装Nginx 展开 nginx map Nginx 可以在大多数Unix like OS 上编译运行,并有Windows 移植版。目前Nginx 的1.0.0稳定版已发布,开发版本为0.9.x,稳定版为0.8.x,历史稳定版为 0.7.x,建议使用0.8系列作为生产版本。 Nginx 的源代码使用2-clause BSD-like license。 Nginx 是一个很牛的高性能Web和反向代理服务器,它具有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx 在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高

达50,000 个并发连接数的响应,感谢Nginx为我们选择了epoll and kqueue作为开发模型。 Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持Rails 和PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比Perlbal 要好很多。 作为邮件代理服务器:Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last. fm 描述了成功并且美妙的使用经验。 Nginx 是一个安装非常的简单,配置文件非常简洁(还能够支持perl 语法),Bugs非常少的服务器:Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。 编辑本段Nginx性能概述 HTTP基础功能 处理静态文件,索引文件以及自动索引; 反向代理加速(无缓存),简单的负载均衡和容错; FastCGI,简单的负载均衡和容错; 模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI过滤器中,到同一个proxy 或者FastCGI 的多个子请求并发处理; SSL 和TLS SNI 支持; IMAP/POP3 代理服务功能: 使用外部 HTTP 认证服务器重定向用户到 IMAP/POP3 后端; 使用外部 HTTP 认证服务器认证用户后连接重定向到内部的SMTP 后端; 其他HTTP功能 基于名称和基于IP的虚拟服务器; Keep-alive and pipelined connections support;保持活动和支持管线连接; Flexible configuration;灵活的配置; Reconfiguration and online upgrade without interruption of the client processing;重构,未经客户处理中断在线升级;

nginx,开源协议

竭诚为您提供优质文档/双击可除 nginx,开源协议 篇一:开源协议 一.每个协议分别找出一个使用该协议的开源软件。 1.gpl,全称gnugeneralpubliclicense。它的主要内容为:只要在一个软件中使用(“使用”指类库引用或者修改后的代码)gpl协议的产品,则该软件产品必须也采用gpl协议,既必须也是开源和免费。这个协议就不太适合商用软件,或者准备使用gpl开源组件的商用项目。基于这个协议的项目,极大的提高了开源软件的数量。 采用这个协议的开源软件有:linux、mysql。 2.lgpl,全称gnulessergeneralpubliclicense次通用公共许可协议。lgpl允许商业软件通过引用类库的方式使用lgpl组件(不直接使用源代码),这样可以不需要开源商业软件的代码。但是如果要修改原始组件的代码,则涉及修改部分的代码和基于原来代码衍生的代码都必须采用lgpl协议。lgpl不适合以lgpl协议为基础的代码进行二次开发的商业软件,但是商用软件可以采用编译后的类库引用就不需要公开源代码了。

采用这个协议的开源软件有:jboss、Fckeditor、hibernate。3.bsd,全称berkeleysoftwaredistribution。这个协议允许使用者修改和重新发布代码,也允许使用或在bsd代码基础上开发商业软件发布和销售,因此是适用于商业软件的。 使用时还必须做到满足三个条件: 1)如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的bsd协议。 2)如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的bsd协议。3)不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 适用bsd协议的开源软件有:nginx、cruisecontrol、Redis。 4mit,源自麻省理工学院(massachusettsinstituteoftechnology,mit),又称x11 协议。mit与bsd类似,但是比bsd协议更加宽松,是目前最少限制的协议。这个协议唯一的条件就是在修改后的代码或者发行包包含原作者的许可信息。适用商业软件。使用mit 的软件项目有:jquery、node.js。 5.apachelicencevesion2.0,这个协议除了为用户提供版权许可之外,还有专利许

nginx中文解释

Nginx 常见应用技术指南[Nginx Tips] 第二版 作者:NetSeek https://www.doczj.com/doc/1d4029930.html, (I T运维专家网|集群架构|性能调优) 欢迎转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明. 首发时间: 2008-11-25 更新时间:2009-1-14 目录 一、Nginx 基础知识 二、Nginx 安装及调试 三、Nginx Rewrite 四、Nginx Redirect 五、Nginx 目录自动加斜线: 六、Nginx Location 七、Nginx expires 八、Nginx 防盗链 九、Nginx 访问控制 十、Nginx日志处理 十一、Nginx Cache 十二、Nginx 负载均衡 十三、Nginx简单优化 十四、如何构建高性能的LEMP环境 十五、Nginx服务监控 十六、常见问题与错误处理. 十七、相关资源下载 【前言】: 编写此技术指南在于推广普及NGINX在国内的使用,更方便的帮助大家了解和掌握NGINX 的一些使用技巧。本指南很多技巧来自于网络和工作中或网络上朋友们问我的问题.在此对 网络上愿意分享的朋友们表示感谢和致意!欢迎大家和我一起丰富本技术指南提出更好的建 议!请朋友们关注: https://www.doczj.com/doc/1d4029930.html, 技术分享社区! 互想学习共同进步! 一、Nginx 基础知识 1、简介 Nginx ("engine x") 是一个高性能的HTTP 和反向代理服务器,也是一个IMAP/POP3/SMTP 代理服 务器。Nginx 是由Igor Sysoev 为俄罗斯访问量第二的Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。尽管还是测试版,但是,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。 更多的请见官方wiki: https://www.doczj.com/doc/1d4029930.html,/ 2、Nginx的优点 nginx做为HTTP服务器,有以下几项基本特性: 1) 处理静态文件,索引文件以及自动索引;打开文件描述符缓冲. 2) 无缓存的反向代理加速,简单的负载均衡和容错. 3) FastCGI,简单的负载均衡和容错. 4) 模块化的结构。包括gzipping, byte ranges, chunked responses, 以及SSI-filter等filter。 如果由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理可以并行运行,而不 需要相互等待。 5) 支持SSL 和 TLS SNI. Nginx专为性能优化而开发,性能是其最重要的考量, 实现上非常注重效率。它支持内核Poll模型, 能经受高负载的考验, 有报告表明能支持高达50,000 个并发连接数。 Nginx具有很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时, 也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这 样的攻击对nginx来说基本上是毫无用处的。就稳定性而言, nginx比lighthttpd更胜一筹。 Nginx支持热部署。它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不 需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。 Nginx采用master-slave模型, 能够充分利用SMP的优势,且能够减少工作进程在磁盘I/O的阻 塞延迟。当采用select()/poll()调用时,还可以限制每个进程的连接数。 Nginx代码质量非常高,代码很规范,手法成熟,模块扩展也很容易。特别值得一提的是强大

Nginx安装学习使用详细记录

前言: 选择Nginx的优点: Nginx 可以在大多数 Unix like OS 上编译运行,并有 Windows 移植版。 Nginx 的1.4.0稳定版已经于2013年4月24日发布,一般情况下,对于新建站点,建议使用最新稳定版作为生产版本,已有站点的升级急迫性不高。Nginx 的源代码使用 2-clause BSD-like license。 Nginx 是一个很强大的高性能Web和反向代理服务器,它具有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。 1.1 执行安装 1.tar -xvf nginx-1.4. 2.tar.gz 2.cd nginx-1.4.2 3../configure --prefix=/usr/nginx --with-http_stub_status_module --with-debug --with -http_realip_module --with-http_ssl_module 4. 5. 6.[root@localhost nginx-1.4.2]# make install 7....... 8.test-d \'/usr/nginx/logs\'|| mkdir -p \'/usr/nginx/logs\' 9.test-d \'/usr/nginx/logs\'|| mkdir -p \'/usr/nginx/logs\' 10.test-d \'/usr/nginx/html\'|| cp -R html \'/usr/nginx\' 11.test-d \'/usr/nginx/logs\'|| mkdir -p \'/usr/nginx/logs\' 1.2 查看进程数 进程数是与top出来的cpu数量是一样的。在/usr/local/nginx/conf/nginx.conf配置文件里面的worker_processes参数。 worker_processes指明了nginx要开启的进程数,据官方说法,一般开一个就够了,多开几个,可以减少机器io带来的影响。据实践表明,nginx的这个参数在一般情况下开4个或8个就可以了,再往上开的话优化不太大。据另一种说法是,nginx开启太多的进程,会影响主进程调度,所以占用的cpu会增高。 1.[root@lb-net-2 ~]# ps -eaf|grep nginx 2.root 2221 1382 0 18:06 pts/0 00:00:00 grep nginx 3.root 16260 1 0 Jun18 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx 4.nobody 16261 16260 0 Jun18 ? 00:01:26 nginx: worker process 5.nobody 16262 16260 0 Jun18 ? 00:01:32 nginx: worker process 6.nobody 16263 16260 0 Jun18 ? 00:01:25 nginx: worker process 7.nobody 16264 16260 0 Jun18 ? 00:01:33 nginx: worker process 8.nobody 16265 16260 0 Jun18 ? 00:01:32 nginx: worker process 9.nobody 16266 16260 0 Jun18 ? 00:01:24 nginx: worker process 10.nobody 16267 16260 0 Jun18 ? 00:01:32 nginx: worker process 11.nobody 16268 16260 0 Jun18 ? 00:01:23 nginx: worker process

Nginx源代码分析

Nginx源代码分析 1.Nginx代码的目录和结构 nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清晰,是一个大型服务端软件构建的一个范例。以下是源码目录结构说明: ├─auto 自动编译安装相关目录 │├─cc 针对各种编译器进行相应的编译配置目录,包括Gcc、Ccc等 │├─lib 程序依赖的各种库,包括md5,openssl,pcre等 │├─os 针对不同操作系统所做的编译配置目录 │└─types ├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等 ├─contrib ├─html index.html └─src 源码目录 ├─core 核心源码目录,包括定义常用数据结构、体系结构实现等 ├─event 封装的事件系统源码目录 ├─http http服务器实现目录 ├─mail 邮件代码服务器实现目录 ├─misc 该目录当前版本只包含google perftools包 └─os nginx对各操作系统下的函数进行封装以及实现核心调用的目录。2.基本数据结构 2.1.简单的数据类型 在core/ngx_config.h 目录里面定义了基本的数据类型的映射,大部分都映射到c语言自身的数据类型。 typedef intptr_t ngx_int_t; typedef uintptr_t ngx_uint_t; typedef intptr_t ngx_flag_t; 其中ngx_int_t,nginx_flag_t,都映射为intptr_t;ngx_uint_t映射为uintptr_t。 这两个类型在/usr/include/stdint.h的定义为: /* Types for `void *' pointers. */ #if __WORDSIZE == 64 # ifndef __intptr_t_defined

nginx错误处理方法

Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,也是一个IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。Nginx 超越 Apache 的高性能和稳定性。 Nginx+Tomcat是目前主流的Java web架构,很多公司在使用,Nginx+Tomcat通过简单的配置,可以实现高性能的负载均衡,通过本文学习,可以实现Nginx+Tomcat 负载均衡。 工具资源 1、Java运行环境,JDK 2、压缩版下载 3、稳定版下载 本文基于win10进行配置 配置步骤 1、JDK环境配置略 2、Tomcat安装配置 请参考:一台服务器安装运行多个Tomcat及注册服务 本测试安装两个Tomcat,端口分别是8801和8802 安装配置完成后请确保每一个Tomcat可以正常访问 为了区分两个Tomcat,本文将第二个Tomcat的页面名称改为:Apache Tomcat/、Nginx配置 1.解压Nginx到D盘根目录

2. 3.修改Nginx配置 #user nobody; worker_processes 1; #工作进程的个数 #error_log logs/; #error_log logs/ notice; #error_log logs/ info; #pid logs/; events { worker_connections 1024; #单个进程最大连接数 } http { include ; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型 #access_log logs/ main;

NginWEB服务器架构设计解决方案精修订

N g i n W E B服务器架构设计解决方案 集团标准化工作小组 #Q8QGGQT-GX8G08Q8-GNQGJ8-MHHGN#

Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”,是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.Nginx是由俄罗斯人 Igor Sysoev 为俄罗斯访问量第二的站点开发的,它已经在该站点运行超过两年半了。Igor Sysoev在建立的项目时,使用基于BSD许可。 据说他当初是F5的成员之一,英文主页:。 俄罗斯的一些大网站已经使用它超过两年多了,一直表现不凡,相信想了解nginx的朋友都读过阿叶大哥的利用nginx实现负载均衡.直到2007年4月,俄罗斯大约有20%左右的虚拟主机是由nignx服务或代理的。Google在线安全博客中统计nginx服务或代理了大约所有Internet虚拟主机的 4%。而netcraft的统计显示,nginx服务的主机在过去的一年里以四倍的速度增长。短短的几年里,它的排名已跃进第9。(参见: Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配 Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题,而且Lighttpd的mod_proxy也有一些问题并且很久没有更新。 因此我打算用其替代Apache应用于Linux服务器上。但是Nginx并不支持cgi方式运行,原因是可以减少因此带来的一些程序上的漏洞。那么我们必须使用FastCGI方式来执行PHP程序。 现在,Igor将源代码以类BSD许可证的形式发布。Nginx因为它的稳定性、丰富的模块库、灵活的配置和低系统资源的消耗而闻名.业界一致认为它是+mod_proxy_balancer的轻量级代替者,不仅是因为响应静态页面的速度非常快,而且它的模块数量达到Apache的近 2/3。对proxy 和 rewrite模块的支持很彻底,还支持mod_fcgi、ssl、vhosts ,适合用来做mongrel clusters的前端HTTP 响应。 nginx做为HTTP服务器,有以下几项基本特性: 处理静态文件,索引文件以及自动索引;打开文件描述符缓冲. 无缓存的反向代理加速,简单的负载均衡和容错. FastCGI,简单的负载均衡和容错. 模块化的结构。包括gzipping, byte ranges, chunked responses,以及 SSI-filter等filter。如果由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理可以并行运行,而不需要相互等待。 支持SSL 和 TLSSNI. Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率。它支持内核Poll模型,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。 Nginx具有很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的 CPU

Nginx源码分析

Nginx源代码分析 l00117893 1.Nginx代码的目录和结构 nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清晰,是一个大型服务端软件构建的一个范例。以下是源码目录结构说明: ├─auto 自动编译安装相关目录 │├─cc 针对各种编译器进行相应的编译配置目录,包括Gcc、Ccc等 │├─lib 程序依赖的各种库,包括md5,openssl,pcre等 │├─os 针对不同操作系统所做的编译配置目录 │└─types ├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等 ├─contrib ├─html index.html └─src 源码目录 ├─core 核心源码目录,包括定义常用数据结构、体系结构实现等 ├─event 封装的事件系统源码目录 ├─http http服务器实现目录 ├─mail 邮件代码服务器实现目录 ├─misc 该目录当前版本只包含google perftools包 └─os nginx对各操作系统下的函数进行封装以及实现核心调用的目录。2.基本数据结构 2.1.简单的数据类型 在core/ngx_config.h 目录里面定义了基本的数据类型的映射,大部分都映射到c语言自身的数据类型。 typedef intptr_t ngx_int_t; typedef uintptr_t ngx_uint_t; typedef intptr_t ngx_flag_t; 其中ngx_int_t,nginx_flag_t,都映射为intptr_t;ngx_uint_t映射为uintptr_t。

LNMP源码安装详细笔记(Linux+Nginx+Mysql+php)

LNMP安装笔记 环境:mysql-5.1.59.tar.gz pcre-8.12.tar.gz nginx-1.1.6.tar.gz php-5.2.17.tar.gz php-5.2.17-fpm-0.5.14.diff.gz 首先安装编译环境 yum –y install gcc gcc-c++ autoconf automake一般装完系统的都会有的 然后安装Nginx需要的一些库文件 Yum –y install zlib zlib-devel openssl openssl-devel pcre pcre-devel 如果装系统的时候安装了开发库,,这些装完系统就会有的 不过系统自带的pcre版本比较老,需要重新安装一下新的版本 1.首先安装Mysql Tar –zxvf mysql-5.1.59.tar.gz ./configure –prefix=/usr/local/mysql –with-charset=gbk –with-xcharset=all Make && make install Useradd mysql /usr/local/mysql/bin/mysql_install_db --user=mysql chown -R mysql /usr/local/mysql/var /usr/local/mysql/bin/mysqld_safe & /usr/local/mysql/bin/mysqladmin -u root password 123456 Cp support-files/https://www.doczj.com/doc/1d4029930.html,f /etc/https://www.doczj.com/doc/1d4029930.html,f Vim /etc/https://www.doczj.com/doc/1d4029930.html,f 在[client]下面加入 default-character-set=utf8 这样Mysql就能完全支持中文了 echo "/usr/local/mysql/bin/mysqld_safe &" >>/etc/rc.local 2.安装Nginx 安装Nginx之前,需要重新安装一下PRCE Tar –zxvf pcre-8.12.tar.gz ./configure Make && make install 开始安装Nginx Tar –zxvf nginx-1.1.6.tar.gz ./configure –prefix=/usr/local/nginx Make && make install echo "/usr/local/nginx/sbin/nginx" >>/etc/rc.local 这个时候Nginx就装好了,打开http://localhost测试 出现Welcome to nginx! 表示安装成功! 3.安装PHP

相关主题
文本预览
相关文档 最新文档