Nginx源码分析之开篇

Nginx源码构思精巧,每每阅读颇有收获,写此文与各码农分享。阅读从main开始,流程非常清晰。
首页 新闻资讯 行业资讯 Nginx源码分析之开篇

Nginx源码构思精巧,每每阅读颇有收获,写此文与各码农分享。

阅读从main开始,流程非常清晰。

复制

/* 系统错误初始化,将构建ngx_sys_errlist */  ngx_strerror_init();  /* 选项处理 */ ngx_get_options(argc, argv);   /* 时间初始化, 当前时间:ngx_current_msec */ ngx_time_init();   /* 日志初始化 */ log = ngx_log_init(ngx_prefix);   /* 选项处理 */ ngx_save_argv(..., argc, argv);  ngx_process_options(...);   /* 操作系统初始化处理 */ ngx_os_init(log);   /* 模块点名, ngx_modules代表所有模块,是个数组 */ ngx_max_module = 0;  for (i = 0; ngx_modules[i]; i++) {      ngx_modules[i]->index = ngx_max_module++;  }   /*   * 系统初始化,这里将发生配置文件解析,模块上下文注册钩子调用,模块初始化   * module     : 模块   * commands  : 模块指令集,负责解析配置文件的选项,一个指令对应一个配置选项   * conf            : 模块配置结构体,指令解析后的值就是存储在这个里面,每个模块都有自已的一个conf   * ctx              : 模块上下文,有四种,core, event, http, mail,有注册钩子功能。比如 create conf, init conf   */ cycle = ngx_init_cycle(&init_cycle);   /* 创建进程id文件 */ ngx_create_pidfile(&ccf->pid, cycle->log);   /*   * 进程处理   * 主进程(master)产生多个工作进程(worker)   * 这里将做各模块进程初始化,监听,接受,请求处理,还有信号等   */ ngx_master_process_cycle(cycle) {      ngx_start_worker_processes(cycle, ccf->worker_processes,                                 NGX_PROCESS_RESPAWN) {          for ( ... ) {              ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,                            "worker process", type);          }      }  }    goto: 继续  /* 生产进程都在这个函数里处理 */ ngx_worker_process_cycle {      /* 各模块进程注册钩子调用 */     ngx_worker_process_init();           for ( ;; ) {          ngx_process_events_and_timers(cycle);      }  }        goto: 继续  ngx_process_events_and_timers(cycle) {      /*       * 定时器,用红黑树实现,这里找出某个event(事件)的超时时间       * 每个事件在红黑树里的key的值为:ngx_currnet_msec + 超时时间(默认60s)       * timer的值为 -1 (如果没有事件),或 ngx_current_msec - key       */     timer = ngx_event_find_timer();       /* epoll 机制,这里将做 epoll_wait(..., timer); */     ngx_process_events(cycle, timer, flags);           /* 先处理所有可能超时的事件,如果超时,将event的timedout设为1,并且马上event->handler(ev); */     ngx_event_expire_timers();       /* 事件存队列方式,开始遍历,调用 */     ngx_event_process_posted(cycle, &ngx_posted_events);  }    /*   * 几个重要的结构体   * ngx_listening_t       : 监听套接字的结构体,比如地址,端口等   * ngx_connection_t   : 每个socket将对应一个connection,意为连接,里面存着 fd,read(读事件),   *                               write(写事件) 等。   * ngx_event_t    : 事件结构体,有个重要的函数指针handler,fd事件被驱动时,将调用这个函数。   *                               它有几个重要成员   *                                     timer_set  : 每个event在epoll_wait前,要先进入定时器红黑树,这个标记就是   *                                                       标记是否在定时器里, 超时处理用的.   *                                     active       : 当ngx_add_event里(添加或更新事件) 进入epoll时,会置为1.   *                                     ready       : 进入事件队列里,将置为1,只有为1,它对应的socket fd才可以读   *                                     timedout   : 此事件对应的socket fd将视为超时   */   /*   * http处理   * 当 listen fd 有连接过来时,它将调用函数 ngx_http_init_connection   * 当 accept fd 有传送东东时,它将调用函数 ngx_http_init_request,所以的处理都将从这函数开始   */ ngx_http_init_request {      ngx_http_process_request_line {          /* 读请求头 */         ngx_http_read_request_header(...);           /* 解析请求行 */         ngx_http_parse_request_line(...);           /* 处理请求头部信息 */         ngx_http_process_request_headers(...) {              for ( ;; ) {                  /* 解析每一行 */                 ngx_http_parse_header_line(...);              }               /* 解析之后对所有行的处理 */             ngx_http_process_request_header(...);               /* 真正开始处理请求 */             ngx_http_process_request(r) {                  ngx_http_handler(r) {                      /* 非常巧妙的设计处理即将开始 */                     ngx_http_core_run_phases(r);                  }              }          }       }  }    /*   * 精巧的设计函数:责任链模式   * http的每个请求可以分为好几个阶段   *        规则重写(rewrite)   *        处理配置(不同url有不同的配置)   *        权限访问处理   *        核心内容处理(是走fastcgi,还是直接输出或从缓存获取等)   *        日志处理   *   * 每个阶段都可以由好几个模块处理,这些模块组成一个链,   * 这是设计模式里的一种,责任链模式   */  ngx_http_core_run_phases(r) {      while (ph[r->phase_handler].checker) {           rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);           if (rc == NGX_OK) {              return;          }      }   }
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

  • 33.

  • 34.

  • 35.

  • 36.

  • 37.

  • 38.

  • 39.

  • 40.

  • 41.

  • 42.

  • 43.

  • 44.

  • 45.

  • 46.

  • 47.

  • 48.

  • 49.

  • 50.

  • 51.

  • 52.

  • 53.

  • 54.

  • 55.

  • 56.

  • 57.

  • 58.

  • 59.

  • 60.

  • 61.

  • 62.

  • 63.

  • 64.

  • 65.

  • 66.

  • 67.

  • 68.

  • 69.

  • 70.

  • 71.

  • 72.

  • 73.

  • 74.

  • 75.

  • 76.

  • 77.

  • 78.

  • 79.

  • 80.

  • 81.

  • 82.

  • 83.

  • 84.

  • 85.

  • 86.

  • 87.

  • 88.

  • 89.

  • 90.

  • 91.

  • 92.

  • 93.

  • 94.

  • 95.

  • 96.

  • 97.

  • 98.

  • 99.

  • 100.

  • 101.

  • 102.

  • 103.

  • 104.

  • 105.

  • 106.

  • 107.

  • 108.

  • 109.

  • 110.

  • 111.

  • 112.

  • 113.

  • 114.

  • 115.

  • 116.

  • 117.

  • 118.

  • 119.

  • 120.

  • 121.

  • 122.

  • 123.

  • 124.

  • 125.

  • 126.

  • 127.

  • 128.

  • 129.

  • 130.

  • 131.

  • 132.

  • 133.

  • 134.

  • 135.

  • 136.

  • 137.

  • 138.

  • 139.

  • 140.

  • 141.

  • 142.

  • 143.

  • 144.

  • 145.

  • 146.

  • 147.

  • 148.

  • 149.

  • 150.

  • 151.

  • 152.

  • 153.

  • 154.

  • 155.

  • 156.

  • 157.

  • 158.

 原文链接:http://my.oschina.net/fqing/blog/79145