《nginx入门到精通》读书笔记

从实践入门介绍nginx(•̀⌄•́)
                              —— By Jihan


在线阅读
主题: nginx模块开发和原理解析
类别:计算机->实用性+理论性论述书->nginx
概要:从模块开发了解nginx的使用以及nginx整体结构。从源码原理解析了解nginx底层设计和各种优化操作。
这个玩意儿太监了,没有写完,很多东西都只有大纲。

前言

作者想通过文章帮助人们了解nginx的模块开发,和其内部实现原理。
而我也想进行nginx源码学习,了解其中的实现原理和架构,以及一些实现亮点。
为了更深入学习,需要将nginx源码和书结合起来看,虽然书中选择了1.2的版本,为了降低难度,我选择了nginx-1.0.15版本。

主旨

文章的核心内容

核心内容,主要观点,支持什么,反对什么,主要依据,依据是否真实可靠。

整本书的架构

作者怎么样突出的主旨,使用了什么手法,逻辑顺序如何,怎样让核心内容更加夯实。

问题处理

作者想解决什么样的问题,是否解决,还有没有未解决的?未解决问题中,哪些是作者认为无法解决,哪些又需要你从其他地方去找到答案。

章节

nginx模块开发

该模块主要进行nginx整体架构的初步介绍,并指导进行相关的实践操作,进行相关模块开发。

nginx架构

先上一幅nginx架构图:

这幅图很明显的说明了nginx的大架构,其中:
master:负责接收外部控制信号,管理work进程
worker:负责处理请求连接,每个worker之间平等竞争连接。
优势:

  1. work使用进程,而不是线程(虽然也支持线程模式),是为了最大限度避免线程切换开销,并且work数量一般和cpu数量相同,减少cpu上下文切换。
  2. 事件处理采用了异步非阻塞形式,使进程处理请求时不会阻塞。
    而通常web服务器事件分为三类:网络事件,信号(信号事件如何处理???)和定时器。而nginx的这三个事件处理方式可以用一段伪代码表示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
while (true) {
//执行事件
for t in run_tasks:
t.handler();
update_time(&now);
timeout = ETERNITY;
//处理定时器
for t in wait_tasks: /* 已经排序,依次取出超时最小定时器 */
if (t.time <= now) {
t.timeout_handler();
} else {
timeout = t.time - now;
break;
}
//网络事件触发,或者定时器到期
nevents = poll_function(events, timeout);
for i in nevents:
task t;
if (events[i].type == READ) {
t.handler = read_handler;
} else { /* events[i].type == WRITE */
t.handler = write_handler;
}
run_tasks_add(t);
}

nginx基础概念

connection:对tcp链接的封装,其中包括socket,读写事件。
connection生命周期:master读取配置文件,建立监听并获得fd->fork子进程,获得该fd->竞争获取链接,并建立链接->客户端或者服务端完成时间后断开。
链接竞争机制伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//此处的设计是为了避免某些进程已经没有剩余链接却还能竞争到锁,
//而有剩余链接的进程却竞争不到。
//当前进程总连接数/8 - 当前剩余连接数
ngx_accept_disabled = ngx_cycle->connection_n / 8
- ngx_cycle->free_connection_n;

if (ngx_accept_disabled > 0) {
ngx_accept_disabled--; //(有必要???每次该值都会被上面覆盖)

} else {//尝试竞争锁
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return;
}

if (ngx_accept_mutex_held) {
flags |= NGX_POST_EVENTS;

} else {
if (timer == NGX_TIMER_INFINITE
|| timer > ngx_accept_mutex_delay)
{
timer = ngx_accept_mutex_delay;
}
}
}

request
很明显,这就是表示一个http的请求,其生命周期如下图(细节code???):

keepalive
链接跟踪,在接收到第一个http请求后,不断开连接,如果一定时间内没有接到该客户端的后续请求再断开连接。对于大多数网页访问来说,keepalive是很有必要的。

pipeline
同时可以接收两个请求,即当客户端不用等到第一个请求完再发第二个请求。有点类似http2的处理方式。

lingering_close
在出现服务端错误的情况下,服务端返回错误信息,write到tcp的write buffer里,然后直接close。如果这个时候该链接的read buffer里还有数据,则会直接返回reset,丢弃write buffer里的内容。如果没有,则等write buffer里数据发送了再close。而lingering_close的作用,就是在出错write数据后,等一段时间再close,这段时间内仍然读取read buffer里的数据扔掉即可。

基础数据结构

ngx_str_t:具体参考源码,并且自己进行相关调用。
ngx_pool_t:

nginx原理

从架构深入到内部实现,讲解nginx源码的各个模块的关键设计。需要配合源码来进行阅读。

结语

所得

作者所提出的问题,是否就是你真正想问的问题?而他所提出的答案你是否赞成?如果有不赞成,说明原因。是否还有你想问的问题在书中没有提及,或者你又有了新的疑问书中没有给出答案?

所想

看完这本书,有什么感想,有什么值得学习的,这里就可以随便写了。

相关

可以列出相关的看过的书籍,或者问题参考链接网页一类的。

-------------本文结束感谢您的阅读-------------