@@ -117,36 +117,69 @@ ngx_module_t ngx_events_module = {
117
117
static ngx_str_t event_core_name = ngx_string ("event_core" );
118
118
119
119
120
+ // 事件模块需要做的事情,以下内容按照顺序进行创建,简单的来说就是从 events 配置项中提取出响应的配置,然后进行相关内容的初始化
121
+ /*
122
+ * 例如:
123
+ * events {
124
+ * accept_mutex on; # 设置网路连接序列化,防止惊群现象发生,默认为on
125
+ * multi_accept on; # 设置一个进程是否同时接受多个网络连接,默认为off
126
+ * use epoll; # 事件驱动模型,select|poll|kqueue|epoll|eventport
127
+ * worker_connections 1024; # 最大连接数,默认为512
128
+ * }
129
+ */
120
130
static ngx_command_t ngx_event_core_commands [] = {
121
131
132
+ // 创建 worker 连接池,也就是 worker_connections 中所定义的配置项,根据服务器并发数量决定
122
133
{ ngx_string ("worker_connections" ),
123
134
NGX_EVENT_CONF |NGX_CONF_TAKE1 ,
124
135
ngx_event_connections ,
125
136
0 ,
126
137
0 ,
127
138
NULL },
128
139
140
+ // 确定哪个事件驱动模块作为事件驱动机制,Linux 上一般为 epoll
129
141
{ ngx_string ("use" ),
130
142
NGX_EVENT_CONF |NGX_CONF_TAKE1 ,
131
143
ngx_event_use ,
132
144
0 ,
133
145
0 ,
134
146
NULL },
135
147
148
+ // 表示是否配置一次性尽可能多的建立 TCP 连接。对于 epoll 来说,
149
+ // 意味着在接收到一个新的连接事件时,调用 accept() 以尽可能多地接收连接
136
150
{ ngx_string ("multi_accept" ),
137
151
NGX_EVENT_CONF |NGX_CONF_FLAG ,
138
152
ngx_conf_set_flag_slot ,
139
153
0 ,
140
154
offsetof(ngx_event_conf_t , multi_accept ),
141
155
NULL },
142
156
157
+
158
+ /*
159
+ * nginx 惊群现象的解决方式。由于 nginx 是一个 master-worker 模型,master 进行作为管理者不进行 accept(),所以会有多个 worker 进行
160
+ * 在同一个端口上进行 accept(),那么假如有新的连接建立时,很可能会出现所有的 worker 都去争抢这个新的连接。
161
+ *
162
+ * Linux 本身的 accept() 惊群效应:
163
+ * 假如父进程创建了一个 listening socket,并且 bind 了相应的端口,同时 fork 出了多个子进程的话,子进程将会继承父进程的 listening socket,
164
+ * 也就是说,多个子进程可以在同一个监听 socket 上调用 accept() 方法接收并处理新的连接:
165
+ * - Linux 2.6 版本之前,监听同一个 socket 的进程会挂在同一个等待队列上,当请求到来时,会唤醒所有等待的进程。
166
+ * - Linux 2.6 版本之后,通过引入一个标记位 WQ_FLAG_EXCLUSIVE,解决掉了 accept 惊群效应。
167
+ * 所以,Linux 上父子进程的惊群效应其实已经被解决了,但是 epoll 的惊群效应则更为复杂。
168
+ *
169
+ * epoll 的惊群问题并不是出现在 accept() 上,而是出现在其它工作场景中,比如定时器事件、信号事件
170
+ *
171
+ * 因此,需要使用进程锁来解决 epoll 产生的惊群问题
172
+ *
173
+ * 是否使用 accept_mutex 进程锁来解决惊群问题,默认开启
174
+ */
143
175
{ ngx_string ("accept_mutex" ),
144
176
NGX_EVENT_CONF |NGX_CONF_FLAG ,
145
177
ngx_conf_set_flag_slot ,
146
178
0 ,
147
179
offsetof(ngx_event_conf_t , accept_mutex ),
148
180
NULL },
149
181
182
+ // 当启用了 accept_mutex 以后,延迟 accept_mutex_delay 毫秒后再试图处理新的连接
150
183
{ ngx_string ("accept_mutex_delay" ),
151
184
NGX_EVENT_CONF |NGX_CONF_TAKE1 ,
152
185
ngx_conf_set_msec_slot ,
0 commit comments