Skip to content

Commit 43eeabf

Browse files
committed
✨ ngx_listening_s && ngx_cycle_t
1 parent 71dbed9 commit 43eeabf

File tree

4 files changed

+51
-35
lines changed

4 files changed

+51
-35
lines changed

src/core/nginx.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ main(int argc, char *const *argv)
299299
// slab 初始化
300300
ngx_slab_sizes_init();
301301

302-
// 创建监听套接字
302+
// 创建监听套接字,核心函数
303303
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
304304
return 1;
305305
}
@@ -503,15 +503,19 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
503503
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
504504
"using inherited sockets from \"%s\"", inherited);
505505

506-
// cycle->listening 是一个 ngx_array_t 结构体变量,而 ngx_array_t 其实是一个动态数组。这里初始化的时候给了 10 个容量,后续如果需要的话,
507-
// cycle->listening 也能够动态扩容
506+
/*
507+
* cycle->listening 是一个 ngx_array_t 结构体变量,而 ngx_array_t 其实是一个动态数组,在这里保存的时 ngx_listening_t 对象,即监听端口对象
508+
* 这里初始化的时候给了 10 个容量,后续如果需要的话,cycle->listening 也能够动态扩容。
509+
* 这里没明白的是 ngx_listening_t 包含了一个 previous 指针,表示指向前一个 ngx_listening_t 对象,这个指针在何处有使用?
510+
*/
508511
if (ngx_array_init(&cycle->listening, cycle->pool, 10,
509512
sizeof(ngx_listening_t))
510513
!= NGX_OK)
511514
{
512515
return NGX_ERROR;
513516
}
514517

518+
// TODO: 这一段 for 循环看的云里雾里的,到时候 DEBUG 跟踪一下
515519
for (p = inherited, v = p; *p; p++) {
516520
if (*p == ':' || *p == ';') {
517521
s = ngx_atoi(v, p - v);
@@ -525,13 +529,15 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
525529

526530
v = p + 1;
527531

532+
// 在 cycle->listening 的动态数组中新增一个元素,并返回新增元素的地址。这种方式在 ngx_list_t 中也有使用
528533
ls = ngx_array_push(&cycle->listening);
529534
if (ls == NULL) {
530535
return NGX_ERROR;
531536
}
532537

533538
ngx_memzero(ls, sizeof(ngx_listening_t));
534539

540+
// 这里保存的是 socket 描述符
535541
ls->fd = (ngx_socket_t) s;
536542
ls->inherited = 1;
537543
}

src/core/ngx_connection.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
172172
ls[i].socklen = sizeof(ngx_sockaddr_t);
173173
}
174174

175+
// 协议族选取
175176
switch (ls[i].sockaddr->sa_family) {
176177

177178
#if (NGX_HAVE_INET6)
@@ -188,6 +189,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
188189
break;
189190
#endif
190191

192+
// 大部分的代码运行会走到这里
191193
case AF_INET:
192194
ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
193195
len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
@@ -214,10 +216,14 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
214216

215217
ls[i].addr_text.len = len;
216218

219+
// 默认为 511
217220
ls[i].backlog = NGX_LISTEN_BACKLOG;
218221

219222
olen = sizeof(int);
220223

224+
// 下面的代码都是在获取监听 socket 的一些状态,或者说属性,然后赋值到 ls 数组中的 ngc_listening_t 对象的成员中
225+
226+
// 获取 socket 类型
221227
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type,
222228
&olen)
223229
== -1)
@@ -230,6 +236,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
230236

231237
olen = sizeof(int);
232238

239+
// 获取 socket 接收缓冲区大小
233240
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
234241
&olen)
235242
== -1)
@@ -243,6 +250,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
243250

244251
olen = sizeof(int);
245252

253+
// 获取 socket 发送缓冲区大小
246254
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
247255
&olen)
248256
== -1)
@@ -296,6 +304,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
296304

297305
#else
298306

307+
// 注意,SO_REUSEPORT 和 SO_REUSEADDR 这两个 socket 属性是完全不相同的概念
299308
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
300309
(void *) &reuseport, &olen)
301310
== -1)

src/core/ngx_connection.h

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,23 @@ typedef struct ngx_listening_s ngx_listening_t;
1717

1818
// ngx_listening_t 表示着 Nginx 的一个监听端口,通常会有 2 个,一个是 80 端口,另一个则是 443 端口
1919
struct ngx_listening_s {
20-
// 监听套接字的 socket fd
21-
ngx_socket_t fd;
2220

23-
// 监听套接字的监听地址
24-
struct sockaddr *sockaddr;
25-
// sockaddr 的长度
26-
socklen_t socklen; /* size of sockaddr */
21+
ngx_socket_t fd; // 监听套接字的 socket fd
22+
23+
struct sockaddr *sockaddr; // 监听套接字的监听地址
24+
socklen_t socklen; // sockaddr 的长度
2725
size_t addr_text_max_len;
2826

29-
// 字符串形式所保存的 ip 地址
30-
ngx_str_t addr_text;
27+
ngx_str_t addr_text; // 字符串形式所保存的 ip 地址
3128

32-
// 监听套接字类型,通常为 SOCK_STREAM
33-
int type;
29+
int type; // 监听套接字类型,通常为 SOCK_STREAM
3430

35-
// 已完成连接队列的最大长度
36-
int backlog;
31+
int backlog; // 已完成连接队列的最大长度
3732

38-
// socket 接收缓冲区的大小
39-
int rcvbuf;
40-
// socket 发送缓冲区的大小
41-
int sndbuf;
33+
int rcvbuf; // socket 接收缓冲区的大小
34+
int sndbuf; // socket 发送缓冲区的大小
4235
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
43-
// 下面是 TCP Keep-Alive 选项
44-
int keepidle;
36+
int keepidle; // TCP Keep-Alive 选项
4537
int keepintvl;
4638
int keepcnt;
4739
#endif
@@ -55,8 +47,7 @@ struct ngx_listening_s {
5547
ngx_log_t log;
5648
ngx_log_t *logp;
5749

58-
// 内存池大小
59-
size_t pool_size;
50+
size_t pool_size; // 内存池大小
6051
/* should be here because of the AcceptEx() preread */
6152
// TODO: 暂时不知道这个参数是干嘛的,后续再填坑
6253
size_t post_accept_buffer_size;
@@ -66,7 +57,7 @@ struct ngx_listening_s {
6657

6758
// ngx_connection_t 可以好好说道说道,ngx_connection_t 表示一个 TCP 连接,或者说一个感兴趣的事件,不管是监听套接字,还是连接套接字,都会
6859
// 使用 ngx_connection_t 来进行表示,这里面保存了相当丰富的信息,比如对端的 IP 地址、端口号,所接收的数据,等等等等。该结构与 nginx epoll 模型
69-
// 有着千丝万缕的关系,同样是 nginx 的核心结构之一
60+
// 有着千丝万缕的关系,同样是 nginx 的核心结构之一,定义在 ngx_core.h 中,从文件名就可以看出其重要性了
7061
ngx_connection_t *connection;
7162

7263
// 红黑树的结构,暂时也不知道是干啥的

src/core/ngx_cycle.h

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,36 @@ struct ngx_shm_zone_s {
3737

3838

3939
struct ngx_cycle_s {
40+
41+
// 4 个 * 看着都头晕。conf_ctx 是一个数组,每一个数组成员又是一个指针,该指针指向另一个存储着指针的数组,所以是 4 个指针
4042
void ****conf_ctx;
41-
ngx_pool_t *pool;
43+
ngx_pool_t *pool; // nginx 内存池,ngx_list_t 中的内存就是由 ngx_pool_t 所分配的
4244

43-
ngx_log_t *log;
44-
ngx_log_t new_log;
45+
ngx_log_t *log; // 初始化完成前的日志对象指针
46+
ngx_log_t new_log; // 初始化完成后的日志对象
4547

4648
ngx_uint_t log_use_stderr; /* unsigned log_use_stderr:1; */
4749

4850
ngx_connection_t **files;
51+
52+
/* 可用空闲连接指针,free_connections 和下面的 connections 共同组成一个 TCP 连接池。其中 connections 指向整个连接池数组的首地址,
53+
* free_connections 则指向一个可用的空闲连接,nginx 在启动时就会初始化 connections 数组。当有新的 TCP 连接建立时,nginx 从 free_connections
54+
* 取出一个空闲连接,并将 free_connections 指向单向链表的下一个节点。当连接关闭需要归还连接时,将其插入到 free_connections 的头结点即可
55+
*/
4956
ngx_connection_t *free_connections;
50-
ngx_uint_t free_connection_n;
57+
ngx_uint_t free_connection_n; // 空闲连接数量,也就是还能够分配出多少个连接出去
5158

5259
ngx_module_t **modules;
5360
ngx_uint_t modules_n;
5461
ngx_uint_t modules_used; /* unsigned modules_used:1; */
5562

56-
ngx_queue_t reusable_connections_queue;
57-
ngx_uint_t reusable_connections_n;
63+
ngx_queue_t reusable_connections_queue; // 双向链表实现的队列,表示可重复使用的连接池对象
64+
ngx_uint_t reusable_connections_n; // 可复用连接池对象的大小
5865
time_t connections_reuse_time;
5966

60-
ngx_array_t listening;
61-
ngx_array_t paths;
67+
ngx_array_t listening; // 动态数组,里面儿保存的其实是 ngx_listening_t 对象,表示监听端口
68+
69+
ngx_array_t paths; // nginx 所要操作的目录路径
6270

6371
ngx_array_t config_dump;
6472
ngx_rbtree_t config_dump_rbtree;
@@ -67,10 +75,12 @@ struct ngx_cycle_s {
6775
ngx_list_t open_files;
6876
ngx_list_t shared_memory;
6977

70-
ngx_uint_t connection_n;
71-
ngx_uint_t files_n;
78+
ngx_uint_t connection_n; // 初始化时 connection_n == free_connection_n,表示连接池总大小
79+
ngx_uint_t files_n; // 单个进程能够打开的最大文件数量
80+
81+
ngx_connection_t *connections; // 连接池首地址,与 free_connections 搭配使用
7282

73-
ngx_connection_t *connections;
83+
// TODO: 这两个事件数组还没整明白
7484
ngx_event_t *read_events;
7585
ngx_event_t *write_events;
7686

0 commit comments

Comments
 (0)