nginx upstream模块源码学习(0)

初始化阶段

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中。

下一篇介绍请求处理流程。

 

转载于:https://my.oschina.net/u/1777349/blog/873761

你可能感兴趣的:(nginx upstream模块源码学习(0))