deep think


Forword proxy via Nginx

0x00 Nginx 启动流程

  1. 解析命令行,处理各种参数
    • ngx_get_options(argc, argv)
    • ngx_process_options(&init_cycle)
  2. 读取升级信息并继承监听socket
    • ngx_add_inherited_sockets(&init_cycle)
  3. 创建存储配置项的结构体
    • module->create_conf(cycle)
  4. 解析 nginx.conf 中的配置项
    • ngx_conf_parse(&conf, &cycle->conf_file)
  5. 初始化核心模块配置
    • module->init_conf(cycle, cycle->conf_ctx[cycle->modules[i]->index]
  6. 打开文件并创建共享内存
    • ngx_open_file shm_zone[i].init(&shm_zone[i], NULL)
  7. 创建监听socket
    • ngx_open_listening_sockets(cycle)
  8. 调用所有模块的init_module
    • ngx_init_modules(cycle)
  9. 如果单进程模式
    1. 调用所有模块的init_process
      • cycle->modules[i]->init_process(cycle)
  10. 如果master进程工作模式
    1. 启动worker子进程
      • ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN);
    2. 调用所有模块的init_process方法
      • cycle->modules[i]->init_process(cycle)
    3. 视情况启动cache子进程
      • ngx_start_cache_manager_processes(cycle, 0)

0x01 Nginx 进程工作模式

当nginx配置为master-worker进程模式时,会调用ngx_master_process_cycle进入master进程工作循环中,从而在ngx_spawn_process中通过fork()系统调用新建一个子进程,在子进程中调用ngx_worker_process_cycle 进入到worker进程工作循环中

master进程不处理网络事件,仅仅用于管理worker进程,nginx通过一个数组ngx_processes保存所有子进程的相关信息:

ngx_process_t    ngx_processes[NGX_MAX_PROCESSES];

其中ngx_process_t的定义为:

typedef struct {
    ngx_pid_t           pid;
    int                 status;
    ngx_socket_t        channel[2];  // 用于master进程与worker进程通信

    ngx_spawn_proc_pt   proc;  // worker进程的循环函数
    void               *data;
    char               *name;

    unsigned            respawn:1;
    unsigned            just_spawn:1;
    unsigned            detached:1;
    unsigned            exiting:1;
    unsigned            exited:1;
} ngx_process_t;

ngx_worker_process_cycle工作循环

  1. 初始化 worker 进程
    • 设置进程优先级,文件描述符等
    • 调用所有模块的 init_process 方法
  2. 根据以下四个信号标志位(由 ngx_signal_handler 设置)执行不同的逻辑:
    • ngx_exiting: 检查定时器事件并调用所有模块的exit_process
    • ngx_quit(QUIT): 直接调用所有模块的exit_process
    • ngx_terminate(TERM): 进行资源回收(如关闭监听句柄)并设置ngx_exiting
    • ngx_reopen(USR1): 重新打开所有文件

ngx_master_process_cycle工作循环

  1. 添加信号到信号集中,并启动worker工作循环
  2. master进程根据以下信号标志位使用ngx_signal_worker_processes函数来通知worker进程执行对应的逻辑:
    • ngx_reap(CHID): 检查每个子进程的状态,拉起非正常退出的子进程
    • ngx_terminate(TERM or INT): 强制关闭整个服务
    • ngx_quit(QUIT): 优雅地关闭整个服务
    • ngx_reopen(USR1): 重新打开服务中的所有文件
    • ngx_change_binary(USR2): 平滑升级到新版本的 Nginx 程序
    • ngx_reconfigure(HUP): 重读配置文件并使服务对新配置项生效

Published by


Leave a Reply

Your email address will not be published. Required fields are marked *