首先從以下結構體開始,他也被包含在ngx_http_upstream_srv_conf_s結構中
typedefstruct {/*typedef ngx_int_t (*ngx_http_upstream_init_pt)(ngx_conf_t*cf,ngx_http_upstream_srv_conf_t *us);*/ ngx_http_upstream_init_pt init_upstream; ngx_http_upstream_init_peer_pt init; void *data; } ngx_http_upstream_peer_t
以下重點分析下兩個成員變數init_upstream和init
init_upstream
每個upsteam配置塊塊執行一次;
可通過配置keepalive或者ip_hash功能配置,即碰到keepalive或者ip_hash配置被調用,如果沒有配置預設實現為ngx_http_upstream_init_round_robin函數,在配置初始化函數ngx_http_upstream_init_main_conf被調用,預設設定為主要功能是有2個
- us->servers數組中取得資料初始化ngx_http_upstream_rr_peers_t結構存房子us->peer.data中供init函數使用;
- 設定init函數的值,實現init可配置;
init
init函數對於每一個到oringin的請求執行一次;
在ngx_http_upstream_init_request中被調用,用來配置r->upstream->peer結構體,對於keepalive和ip_hash功能將配置不同的get和free函數,預設實現是ngx_http_upstream_create_round_robin_peer
struct ngx_peer_connection_s { ngx_connection_t *connection; struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t *name; ngx_uint_t tries; ngx_msec_t start_time; /*類型typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc, void *data);*//* 上面init的函數中被配置,如果配置了keepalive且從cache中找到了connection將返回NGX_DONE,*//* 且設定複 用已經存在的串連,如果沒有配置keepalive或者,沒有找到存在的connection,*//*但找到了下一跳地址,將返回NGX_OK,*/ ngx_event_get_peer_pt get; /*,同樣在init中被設定,串連釋放時被調用*/ ngx_event_free_peer_pt free; /* 在init中被設定,用以儲存init_upstream中產生的us->peer.data資料,在get和free方法中被使用*/void*data; ......... };
init函數初始化的資料將在為rr建立串連是被使用,調用過程如下:
ngx_http_upstream_init_request->ngx_http_upstream_connect->ngx_event_connect_peer->
rc = pc->get(pc, pc->data);
round_robin ,ip_hash,keepalive模組之間關係
round_robin和ip_hash模組都用於尋找嚇一跳ip,keepalive功能用於找到嚇一跳ip地址之後,通過ip地址尋找是否已經存在可用的connection,所以兩個模組的get實現方式不同,ip_hash是現使用ip_hash尋找下一下,尋找失敗後採用預設的round_robin功能,
而keepalive功能是在ip尋找到之後才能使用,ip尋找可以使用ip_hash的方法,也可以使用round_robin提供的方法,
如下
static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_upstream_keepalive_peer_data_t *kp; ngx_http_upstream_keepalive_srv_conf_t *kcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "init keepalive peer"); kcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_keepalive_module); kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t)); if (kp ==NULL) { return NGX_ERROR; } if (kcf->original_init_peer(r, us) != NGX_OK) { return NGX_ERROR; } kp->conf = kcf; kp->upstream = r->upstream; /*儲存預設的original_get_peer方法,仍將在新的get方法中被調用,r->upstream->peer.get;可以是round_robin,也可以是iphash模組提供的 */ kp->original_get_peer = r->upstream->peer.get; kp->original_free_peer = r->upstream->peer.free; ....../*儲存預設的在original_init_peer中初始化好的資料,get和free方法中需要使用*/ kp->data= r->upstream->peer.data; /*可以通過r->upstream->peer.data找到keepalive模組*/ r->upstream->peer.data= kp; /*設定新的get和free鉤子*/ r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer; r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer; return NGX_OK; } static ngx_int_tngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void*data){ ngx_http_upstream_keepalive_peer_data_t *kp =data; ngx_http_upstream_keepalive_cache_t *item; ngx_int_t rc; ngx_queue_t *q, *cache; ngx_connection_t *c; /* ask balancer 此源碼注釋應不準確*//*適用round_robin或者ip_hash等功能找到下一跳地址*/ rc = kp->original_get_peer(pc, kp->data); if (rc != NGX_OK) { return rc; } /* search cache for suitable connection */cache=&kp->conf->cache;
可以看出keepalive類似於裝飾器模型,即在下一跳ip上增加一個keepalive的功能,keepalive包含origin實現的函數指標
而ip_hash和round_robin 能類似於策略模型,即在init_upstream中設定對於request尋找ip的不同策略。
而這三個模組整體關係,類似於建造者之間關係,即都必須實現且按順序調用init_upstream,init,get,free等函數。
後記:
round_robin多提供了一個create函數,用於upstream中resolved成員被設定的情況,例如通過
proxy_pass http://$vhost;的方式設定到origin的地址。 此時init被create代替,且不能在具有keepalive和ip_hash功能。keepalive和iphash都只能用於upstream模組中。
').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('
').text(i)); }; $numbering.fadeIn(1700); }); });
以上就介紹了 nginx roundrobin 、keepalive、ip_hash模組分析,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。