Nginx http端口监听

server {} block里面的"listen"指令调用了ngx_http_core_listen()函数

C代码   收藏代码
  1. ngx_http_core_listen(...)  
  2. {  
  3.     ngx_http_core_srv_conf_t *cscf = conf;  
  4.     ngx_http_listen_opt_t   lsopt;  
  5.   
  6.     /*根据配置的参数设置lsopt*/  
  7.     //...  
  8.   
  9.     ngx_http_add_listen(cf, cscf, &lsopt);  
  10. }  
C代码   收藏代码
  1. ngx_http_add_listen(...)  
  2. {  
  3.     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);  
  4.     //...  
  5.   
  6.     port = ngx_array_push(cmcf->ports);  
  7.     ngx_http_add_address(cf, cscf, port, lsopt);  
  8. }  
C代码   收藏代码
  1. ngx_http_add_address(...)  
  2. {  
  3.     ngx_http_conf_addr_t  *addr;  
  4.     addr = ngx_array_push(&port->addrs);  
  5.     //...  
  6.     ngx_http_add_server(cf, cscf, addr);  
  7. }  
C代码   收藏代码
  1. ngx_http_add_server(...)  
  2. {  
  3.     ngx_http_core_srv_conf_t  **server;  
  4.     server = ngx_array_push(&addr->servers);  
  5.     *server = cscf;  
  6. }  

可以看到,上面的几个函数基本上就是把当前server的ngx_http_core_srv_conf_t关联到port->addrs->servers和port->addrs->default_server,而每个port又是cmcf->ports的一员。

在http_block()函数的最后会调用到ngx_http_optimize_servers(cf, cmcf, cmcf->ports)。

C代码   收藏代码
  1. ngx_http_optimize_servers(...)  
  2. {  
  3.     //对于每个cmcf->ports的成员port[p]  
  4.     for(;;){  
  5.         //...  
  6.         ngx_http_init_listening(cf, &port[p]);  
  7.     }  
  8. }   
C代码   收藏代码
  1. ngx_http_init_listening(...)  
  2. {  
  3.     addr = port->addrs.elts;  
  4.     //对于port的每个addr[i]  
  5.     while(...){  
  6.         //...  
  7.         //从cf->cycle->listening数组分配内存给ls并初始化(如ls->handler,ls->sockaddr等)  
  8.         ls = ngx_http_add_listening(cf, &addr[i]);  
  9.         hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));  
  10.         ls->servers = hport;  
  11.         //把addr[i]的default_server关联到hport(即ls->servers)的成员addrs  
  12.         ngx_http_add_addrs(cf, hport, addr);  
  13.         //...  
  14.     }  
  15. }  

  

注:上面的函数都是在http_block()里面调用的,比如当在http{...} block里面解析到server{...},又会继续在server{...} block解析,当解析到"listen"的时候, 调用了ngx_http_core_listen()。

而整个的配置读取和解析, 是在main()函数的ngx_init_cycle()里面调用了ngx_conf_parse()。

在上面的配置解析完之后, 在ngx_init_cycle()里面又调用了ngx_open_listening_sockets()创建、bind()和listen() socket。

在之后每个子进程中, ls->fd会被关联到一个connection并添加到事件监听 (如果获得mutex); ngx_http_init_request()中,ls->servers就被用来找到处理请求的那个server{...} block的cscf。

 

猜你喜欢

转载自zzc1684.iteye.com/blog/2164181