初始化阶段
1. ngx_http_upstream_create_main_conf
创建主配置项结构
typedef struct {
ngx_hash_t headers_in_hash;
ngx_array_t upstreams;
/* ngx_http_upstream_srv_conf_t */
} ngx_http_upstream_main_conf_t;
upstream模块有两个配置“upstream”和“server”。
static ngx_command_t ngx_http_upstream_commands[] = {
{ ngx_string("upstream"),
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_http_upstream,
0,
0,
NULL },
{ ngx_string("server"),
NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,
ngx_http_upstream_server,
NGX_HTTP_SRV_CONF_OFFSET,
0,
NULL },
ngx_null_command
};
2. ngx_http_upstream函数:
将调用ngx_http_upstream_add,向upstream主配置结构的upstreams数组中添加并初始化ngx_http_upstream_srv_conf_t结构;随后,创建upstream配置块的三级配置结构,开始解析配置项。
struct ngx_http_upstream_srv_conf_s {
ngx_http_upstream_peer_t peer;
void **srv_conf;
ngx_array_t *servers; /* ngx_http_upstream_server_t */
ngx_uint_t flags;
ngx_str_t host;
u_char *file_name;
ngx_uint_t line;
in_port_t port;
in_port_t default_port;
ngx_uint_t no_port; /* unsigned no_port:1 */
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_shm_zone_t *shm_zone;
#endif
};
3. 解析到server时,将调用ngx_http_upstream_server
向servers数组中添加新的后端服务器ngx_http_upstream_server_t,属性默认值为 weight=1;max_fails=1;fail_timeout = 10。
typedef struct {
ngx_str_t name;
ngx_addr_t *addrs;
ngx_uint_t naddrs;
ngx_uint_t weight;
ngx_uint_t max_fails;
time_t fail_timeout;
unsigned down:1;
unsigned backup:1;
} ngx_http_upstream_server_t;
nginx原生的upstream模块还有hash,ip_hash,keepalive,least_conn,zone。
4. upstream模块初始化时会添加一些配置文件变量,ngx_http_upstream_vars。
5. ngx_http_upstream_init_main_conf函数
调用每个upstream对应的ngx_http_upstream_srv_conf_t结构中ngx_http_upstream_peer_t成员的回调函数peer.init_upstream,该回调函数默认为ngx_http_upstream_init_round_robin,也可以通过其他upstream模块进行设置。不管什么模块的peer.init_upstream,都负责设置peer.ini回调,并将ngx_http_upstream_srv_conf_t中的server解析到peer.data指向的ngx_http_upstream_rr_peers_t结构中(ngx_http_upstream_init_round_robin函数负责)。
struct ngx_http_upstream_rr_peers_s {
ngx_uint_t number;
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_slab_pool_t *shpool;
ngx_atomic_t rwlock;
ngx_http_upstream_rr_peers_t *zone_next;
#endif
ngx_uint_t total_weight;
unsigned single:1;
unsigned weighted:1;
ngx_str_t *name;
ngx_http_upstream_rr_peers_t *next;
ngx_http_upstream_rr_peer_t *peer;
};
next指针指向的时backup的后端服务器,peer为后端服务器链表。
struct ngx_http_upstream_rr_peer_s {
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t name;
ngx_str_t server;
ngx_int_t current_weight;
ngx_int_t effective_weight;
ngx_int_t weight;
ngx_uint_t conns;
ngx_uint_t fails;
time_t accessed;
time_t checked;
ngx_uint_t max_fails;
time_t fail_timeout;
ngx_uint_t down; /* unsigned down:1; */
#if (NGX_HTTP_SSL)
void *ssl_session;
int ssl_session_len;
#endif
ngx_http_upstream_rr_peer_t *next;
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_atomic_t lock;
#endif
};
随后,ngx_http_upstream_init_main_conf会将ngx_http_upstream_headers_in数组中的头hash到upstream模块主配置项的headers_in_hash中。处理客户端HTTP请求时,会去hash中匹配头,并调用处理函数来设置头信息。
typedef struct {
ngx_str_t name;
ngx_http_header_handler_pt handler;
ngx_uint_t offset;
ngx_http_header_handler_pt copy_handler;
ngx_uint_t conf;
ngx_uint_t redirect; /* unsigned redirect:1; */
} ngx_http_upstream_header_t;
此时,初始化完成,即所有server都被放在了相应upstream块的ngx_http_upstream_rr_peers_t中。
下一篇介绍请求处理流程。