1. 定义ngx_clone_listening 函数 定义在 ./nginx-1.24.0/src/core/ngx_connection.cngx_int_tngx_clone_listening(ngx_cycle_t*cycle,ngx_listening_t*ls){#if(NGX_HAVE_REUSEPORT)ngx_int_tn;ngx_core_conf_t*ccf;ngx_listening_tols;if(!ls-reuseport||ls-worker!0){returnNGX_OK;}ols*ls;ccf(ngx_core_conf_t*)ngx_get_conf(cycle-conf_ctx,ngx_core_module);for(n1;nccf-worker_processes;n){/* create a socket for each worker process */lsngx_array_push(cycle-listening);if(lsNULL){returnNGX_ERROR;}*lsols;ls-workern;}#endifreturnNGX_OK;}ngx_clone_listening 函数的作用是 当启用 SO_REUSEPORT 时 ngx_clone_listening 为每个 worker 进程克隆一份监听套接字对象 以便后续每个 worker 都能独立创建监听 socket实现内核级连接分发。2. 详解1. 函数签名ngx_int_tngx_clone_listening(ngx_cycle_t*cycle,ngx_listening_t*ls)参数 ngx_cycle_t *cycle: nginx 核心的周期对象包含当前配置、连接池、监听数组等信息。 ngx_listening_t *ls: 指向原始监听套接字对象的指针。返回值 NGX_OK 表示成功即使没有克隆 NGX_ERROR 表示失败内存分配失败。2. 逻辑流程1. 局部变量 2. 检查 3. 保存原始监听对象 4. 获取核心配置 5. 循环为每个 worker 创建克隆 6. 返回值1. 局部变量{#if(NGX_HAVE_REUSEPORT)ngx_int_tn;ngx_core_conf_t*ccf;ngx_listening_tols;2. 检查if(!ls-reuseport||ls-worker!0){returnNGX_OK;}检查当前监听对象 ls-reuseport 是否启用了 reuseport 标志 ls-worker 该监听套接字所属的 worker 进程编号。 初始创建时worker 为 0表示尚未分配给特定 worker。 如果未启用 reuseport 或已经分配给某个 workerworker ! 0 则直接返回 NGX_OK无需克隆。3. 保存原始监听对象ols*ls;保存原始监听对象的完整副本 后续克隆时将基于此副本创建新对象4. 获取核心配置ccf(ngx_core_conf_t*)ngx_get_conf(cycle-conf_ctx,ngx_core_module);从配置上下文中获取核心模块的配置结构 ngx_core_conf_t 其中包含了 worker_processesworker 进程数量等信息。5. 循环为每个 worker 创建克隆for(n1;nccf-worker_processes;n){/* create a socket for each worker process */lsngx_array_push(cycle-listening);if(lsNULL){returnNGX_ERROR;}*lsols;ls-workern;}#endif循环从 1 开始到 worker_processes - 1 结束。 因为原始监听对象worker 0已经存在 所以只需要为剩余的 worker_processes - 1 个进程创建克隆。 每次循环 调用 ngx_array_push 向 cycle-listening 动态数组尾部追加一个新的监听对象。 如果内存不足返回 NGX_ERROR。 将新元素的内容设置为之前保存的副本 ols即原始监听对象的全部属性。 将新监听对象的 worker 字段设置为当前循环计数器 n 标识该套接字将归属于第 n 个 worker 进程。 循环结束后cycle-listening 数组中的监听对象数量增加了 worker_processes - 1 个。 每个克隆对象拥有相同的地址、端口、选项但由于设置了不同的 worker 后续在 socket 创建阶段会为每个 worker 独立创建真正的套接字文件描述符 并绑定到同一个地址端口借助 SO_REUSEPORT 实现内核级负载均衡。6. 返回值returnNGX_OK;}操作成功返回表示成功的代码