Nginx系列(八):server快速查询

一、基于名字的虚拟主机

Nginx首先选定由哪一个虚拟主机来处理请求。让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始:

server {
    listen      80;
    server_name example.org www.example.org;
    ...
}
 
server {
    listen      80;
    server_name example.net www.example.net;
    ...
}
 
server {
    listen      80;
    server_name example.com www.example.com;
    ...
}

在这个配置中,nginx仅仅检查请求的“Host”头以决定该请求应由哪个虚拟主机来处理。如果Host头没有匹配任意一个虚拟主机,或者请求中根本没有包含Host头,那nginx会将请求分发到定义在此端口上的默认虚拟主机。在以上配置中,第一个被列出的虚拟主机即nginx的默认虚拟主机——这是nginx的默认行为。而且,可以显式地设置某个主机为默认虚拟主机,即在"listen"指令中设置"default_server"参数:

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

"default_server"参数从0.8.21版开始可用。在之前的版本中,应该使用"default"参数代替。
请注意"default_server"是监听端口的属性,而不是主机名的属性。后面会对此有更多介绍。

二、server的解析

在这里插入图片描述

  1. ngx_http_add_listen
    listen字段解析的主回调函数。
  2. ngx_http_add_addresses
    端口(ngx_http_conf_port_t)已存在,地址和虚拟主机不确定是否存在时,调用该接口为ngx_http_conf_port_t加入一个新的地址。
  3. ngx_http_add_address
    端口(ngx_http_conf_port_t)已存在,地址不存在时,调用该接口为ngx_http_conf_port_t加入一个新的地址。
  4. ngx_http_add_server
    端口和地址均已存在,调用该接口为ngx_http_conf_addr_t加入新的虚拟主机。
    ngx_http_conf_addr_t->opt
    即ngx_http_listen_opt_t,根据配置文件中listen参数,对套接字选项进行保存。

三、形成散列表

对每一个ngx_http_conf_addr_t(即每地址),都会形成一个散列表,用于查找该ip:port上建立连接所对应的server块。
HASH表
以ngx_http_server_name_t中的name为key,*server为value,建立hash表,hash表保存在ngx_http_conf_addr_t中的hash、*wc_head、*wc_tail字段。

四、形成监听(ngx_listening_t)

对于每一个ngx_http_conf_port_t,都需要形成一个或多个监听(存在通配符时是一个,不存在通配符是多个),
在这里插入图片描述
server查询
当某个监听套接字触发后,唯一的ngx_http_port_t确定。如果监听非通配符,则为一个的ngx_http_in_addr_t也唯一确定;如果监听通配符,则需要通过套接字选项获取客户真正访问的地址,之后查询ngx_http_port_t->addrs,确定对应的地址节点(ngx_http_in_addr_t)。

for (i = 0; i < port->naddrs - 1; i++) {
	if (addr[i].addr == sin->sin_addr.s_addr) {
		break;
	}
}
hc->addr_conf = &addr[i].conf;

之后根据报文中携带的host信息,查询该ngx_http_in_addr_t的hash表,从而获取server块(ngx_http_core_srv_conf_t)。

ls->servers:这个监听地址包含的所有虚拟主机。

typedef struct {
    /* ngx_http_in_addr_t or ngx_http_in6_addr_t */
    void                      *addrs; //所有地址信息,通配符情况时包含多个,无通配符包含一个
    ngx_uint_t                 naddrs; //通配符情况下表示包含的地址数,无通配符时为1
} ngx_http_port_t;
 
typedef struct {
    in_addr_t                  addr; //具体地址
    ngx_http_addr_conf_t       conf;
} ngx_http_in_addr_t;
 
struct ngx_http_addr_conf_s {
    /* the default server configuration for this address:port */
    ngx_http_core_srv_conf_t  *default_server; //默认的server块
 
    ngx_http_virtual_names_t  *virtual_names; //包含该地址下所有虚拟主机name和server块结构体的hash表。
 
    unsigned                   ssl:1;
    unsigned                   http2:1;
    unsigned                   proxy_protocol:1;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值