Skip to content

Commit d0d5a95

Browse files
committed
ngx_event_accept
1 parent 3255a87 commit d0d5a95

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

nginx/src/core/ngx_connection.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,13 @@ struct ngx_connection_s {
168168
ngx_socket_t fd;
169169

170170
// 接收数据的函数指针
171+
// ngx_event_accept.c:ngx_event_accept()里设置为ngx_recv
172+
// ngx_posix_init.c里初始化为linux的底层接口
171173
ngx_recv_pt recv;
172174

173175
// 发送数据的函数指针
176+
// ngx_event_accept.c:ngx_event_accept()里设置为ngx_send
177+
// ngx_posix_init.c里初始化为linux的底层接口
174178
ngx_send_pt send;
175179

176180
ngx_recv_chain_pt recv_chain;
@@ -213,7 +217,9 @@ struct ngx_connection_s {
213217
// 复用连接对象
214218
ngx_queue_t queue;
215219

216-
// 连接使用次数
220+
// 连接创建的计数器
221+
// ngx_event_accept.c:ngx_event_accept()
222+
// c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
217223
ngx_atomic_uint_t number;
218224

219225
// 处理的请求次数

nginx/src/event/ngx_event.c

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ ngx_uint_t ngx_use_accept_mutex;
7070
ngx_uint_t ngx_accept_events;
7171
ngx_uint_t ngx_accept_mutex_held;
7272
ngx_msec_t ngx_accept_mutex_delay;
73+
74+
// ngx_accept_disabled是总连接数的1/8-空闲连接数
75+
// 也就是说空闲连接数小于总数的1/8,那么就暂时停止接受连接
7376
ngx_int_t ngx_accept_disabled;
7477

7578

nginx/src/event/ngx_event.h

+8
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,16 @@ extern ngx_module_t ngx_event_core_module;
611611

612612

613613

614+
// 监听端口上收到连接请求时的回调函数,即事件handler
615+
// 从cycle的连接池里获取连接
616+
// 关键操作 ls->handler(c);调用其他模块的业务handler
614617
void ngx_event_accept(ngx_event_t *ev);
618+
619+
// 尝试获取负载均衡锁,监听端口
620+
// 如未获取则不监听端口
621+
// 内部调用ngx_enable_accept_events/ngx_disable_accept_events
615622
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
623+
616624
u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
617625

618626

nginx/src/event/ngx_event_accept.c

+40-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
2020
static void ngx_close_accepted_connection(ngx_connection_t *c);
2121

2222

23+
// 监听端口上收到连接请求时的回调函数,即事件handler
24+
// 从cycle的连接池里获取连接
25+
// 关键操作 ls->handler(c);调用其他模块的业务handler
2326
void
2427
ngx_event_accept(ngx_event_t *ev)
2528
{
@@ -37,6 +40,7 @@ ngx_event_accept(ngx_event_t *ev)
3740
static ngx_uint_t use_accept4 = 1;
3841
#endif
3942

43+
// 事件已经超时
4044
if (ev->timedout) {
4145
// 遍历监听端口列表,加入epoll连接事件
4246
if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
@@ -48,15 +52,22 @@ ngx_event_accept(ngx_event_t *ev)
4852

4953
ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
5054

55+
// rtsig在nginx 1.9.x已经删除
5156
if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
5257
ev->available = 1;
5358

5459
} else if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
60+
// epoll是否允许尽可能接受多个请求
5561
ev->available = ecf->multi_accept;
5662
}
5763

64+
// 事件的连接对象
5865
lc = ev->data;
66+
67+
// 事件对应的监听端口对象
5968
ls = lc->listening;
69+
70+
// 此时还没有数据可读
6071
ev->ready = 0;
6172

6273
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
@@ -65,6 +76,7 @@ ngx_event_accept(ngx_event_t *ev)
6576
do {
6677
socklen = NGX_SOCKADDRLEN;
6778

79+
// 调用accept接受连接,返回socket对象
6880
#if (NGX_HAVE_ACCEPT4)
6981
if (use_accept4) {
7082
s = accept4(lc->fd, (struct sockaddr *) sa, &socklen,
@@ -76,6 +88,7 @@ ngx_event_accept(ngx_event_t *ev)
7688
s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
7789
#endif
7890

91+
// 接受连接出错
7992
if (s == (ngx_socket_t) -1) {
8093
err = ngx_socket_errno;
8194

@@ -117,6 +130,7 @@ ngx_event_accept(ngx_event_t *ev)
117130
}
118131
}
119132

133+
// 系统的文件句柄数用完了
120134
if (err == NGX_EMFILE || err == NGX_ENFILE) {
121135
// 遍历监听端口列表,删除epoll监听连接事件,不接受请求
122136
if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle)
@@ -125,29 +139,36 @@ ngx_event_accept(ngx_event_t *ev)
125139
return;
126140
}
127141

142+
// 解锁负载均衡,允许其他进程接受请求
128143
if (ngx_use_accept_mutex) {
129144
if (ngx_accept_mutex_held) {
130145
ngx_shmtx_unlock(&ngx_accept_mutex);
131146
ngx_accept_mutex_held = 0;
132147
}
133148

149+
//未持有锁,暂时不接受请求
134150
ngx_accept_disabled = 1;
135151

136152
} else {
153+
// 不使用负载均衡
154+
// 等待一下,再次尝试接受请求
137155
ngx_add_timer(ev, ecf->accept_mutex_delay);
138156
}
139157
}
140158

141159
return;
142-
}
160+
} // 接受连接出错
143161

144162
#if (NGX_STAT_STUB)
145163
(void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
146164
#endif
147165

166+
// ngx_accept_disabled是总连接数的1/8-空闲连接数
167+
// 也就是说空闲连接数小于总数的1/8,那么就暂时停止接受连接
148168
ngx_accept_disabled = ngx_cycle->connection_n / 8
149169
- ngx_cycle->free_connection_n;
150170

171+
// 从全局变量ngx_cycle里获取空闲链接,即free_connections链表
151172
c = ngx_get_connection(s, ev->log);
152173

153174
if (c == NULL) {
@@ -163,12 +184,14 @@ ngx_event_accept(ngx_event_t *ev)
163184
(void) ngx_atomic_fetch_add(ngx_stat_active, 1);
164185
#endif
165186

187+
// 创建连接使用的内存池
166188
c->pool = ngx_create_pool(ls->pool_size, ev->log);
167189
if (c->pool == NULL) {
168190
ngx_close_accepted_connection(c);
169191
return;
170192
}
171193

194+
// 拷贝客户端sockaddr
172195
c->sockaddr = ngx_palloc(c->pool, socklen);
173196
if (c->sockaddr == NULL) {
174197
ngx_close_accepted_connection(c);
@@ -185,6 +208,7 @@ ngx_event_accept(ngx_event_t *ev)
185208

186209
/* set a blocking mode for aio and non-blocking mode for others */
187210

211+
// 设置socket为非阻塞
188212
if (ngx_inherited_nonblocking) {
189213
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
190214
if (ngx_blocking(s) == -1) {
@@ -208,6 +232,10 @@ ngx_event_accept(ngx_event_t *ev)
208232

209233
*log = ls->log;
210234

235+
// 连接的收发数据函数
236+
// #define ngx_recv ngx_io.recv
237+
// #define ngx_recv_chain ngx_io.recv_chain
238+
// ngx_posix_init.c里初始化为linux的底层接口
211239
c->recv = ngx_recv;
212240
c->send = ngx_send;
213241
c->recv_chain = ngx_recv_chain;
@@ -216,6 +244,7 @@ ngx_event_accept(ngx_event_t *ev)
216244
c->log = log;
217245
c->pool->log = log;
218246

247+
// 设置其他的成员
219248
c->socklen = socklen;
220249
c->listening = ls;
221250
c->local_sockaddr = ls->sockaddr;
@@ -234,11 +263,14 @@ ngx_event_accept(ngx_event_t *ev)
234263
}
235264
#endif
236265

266+
// 连接相关的读写事件
237267
rev = c->read;
238268
wev = c->write;
239269

270+
// 建立连接后是可写的
240271
wev->ready = 1;
241272

273+
// rtsig在nginx 1.9.x已经删除
242274
if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) {
243275
/* rtsig, aio, iocp */
244276
rev->ready = 1;
@@ -263,6 +295,7 @@ ngx_event_accept(ngx_event_t *ev)
263295
* or protection by critical section or light mutex
264296
*/
265297

298+
// 连接计数器增加
266299
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
267300

268301
#if (NGX_STAT_STUB)
@@ -364,12 +397,18 @@ ngx_event_accept(ngx_event_t *ev)
364397
log->data = NULL;
365398
log->handler = NULL;
366399

400+
// 接受连接,收到请求的回调函数
401+
// 在http模块里是http.c:ngx_http_init_connection
367402
ls->handler(c);
368403

404+
// epoll不处理
369405
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
370406
ev->available--;
371407
}
372408

409+
// 如果ev->available = ecf->multi_accept;
410+
// epoll尽可能接受多个请求
411+
// 否则epoll只接受一个请求后即退出循环
373412
} while (ev->available);
374413
}
375414

0 commit comments

Comments
 (0)