ngx_http_upstream_t數據結構的意義
typedef struct ngx_http_upstream_s ngx_http_upstream_t;
struct ngx_http_upstream_s {
// 處理讀事件的回調函數
ngx_http_upstream_handler_pt read_event_handler;
// 處理寫事件的回調函數
ngx_http_upstream_handler_pt write_event_handler;
// 主動向上游服務器發起的連接
ngx_peer_connection_t peer;
/* 當向下遊服務器轉發響應時,如果打開了緩存且認爲上游網速更快,
則會使用pipe成員來轉發響應。這時,pipe必須由HTTP模塊事先構造。 */
ngx_event_pipe_t *pipe;
ngx_chain_t *request_bufs;
// 定義了向下遊發送響應的方式
ngx_output_chain_ctx_t output;
ngx_chain_writer_ctx_t writer;
// 使用upstream機制時的各種配置
ngx_http_upstream_conf_t *conf;
#if (NGX_HTTP_CACHE)
ngx_array_t *caches;
#endif
/* 希望upstream直接轉發響應,就需要在process_header函數中將解析出來的
響應頭部適配爲HTTP的響應頭部,同時需要把包頭中的信息設置到header_in結構體中 */
ngx_http_upstream_headers_in_t headers_in;
// 用於解析主機域名
ngx_http_upstream_resolved_t *resolved;
ngx_buf_t from_client;
/* 接收上游服務器響應包頭的緩衝區,在不需要把響應直接轉發給客戶端,或者buffering標誌位
爲0的情況下轉發包體,接收包體的緩衝區仍然使用buffer */
ngx_buf_t buffer;
// 表示來自上游服務器的響應包體的長度
off_t length;
/* 視兩種情況而定:
1. 當不需要轉發包體,且使用默認的input_filter方法處理包體時,out_bufs指向響應包體;
2. 當需要轉發包體到下游時,這個鏈表指向上一次下游轉發響應到現在這段時間內接收自上游的緩存響應;
*/
ngx_chain_t *out_bufs;
/* 當需要轉發響應包體到下游時,它表示上一次向下遊轉發響應時沒有發送完的內容 */
ngx_chain_t *busy_bufs;
// 用於回收out_bufs中已經發送給下游的ngx_buf_t結構體
ngx_chain_t *free_bufs;
// 處理包體前的初始化方法
ngx_int_t (*input_filter_init)(void *data);
// 處理包體的方法
ngx_int_t (*input_filter)(void *data, ssize_t bytes);
// 用於傳遞HTTP模塊自定義的數據結構,在上述的兩個函數中作爲參數傳遞
void *input_filter_ctx;
#if (NGX_HTTP_CACHE)
ngx_int_t (*create_key)(ngx_http_request_t *r);
#endif
// HTTP模塊實現,用於構造發往上游服務器的請求的函數
ngx_int_t (*create_request)(ngx_http_request_t *r);
// 與上游服務器通信失敗後,重新發起連接
ngx_int_t (*reinit_request)(ngx_http_request_t *r);
// 解析上游服務器返回響應的包頭
ngx_int_t (*process_header)(ngx_http_request_t *r);
void (*abort_request)(ngx_http_request_t *r);
// 請求結束時調用
void (*finalize_request)(ngx_http_request_t *r,
ngx_int_t rc);
// 可由HTTP模塊實現的重定向函數
ngx_int_t (*rewrite_redirect)(ngx_http_request_t *r,
ngx_table_elt_t *h, size_t prefix);
ngx_int_t (*rewrite_cookie)(ngx_http_request_t *r,
ngx_table_elt_t *h);
ngx_msec_t timeout;
// 上游響應的錯誤碼、包體長度等信息
ngx_http_upstream_state_t *state;
// 使用文件緩存時有用
ngx_str_t method;
// 日誌記錄時有用
ngx_str_t schema;
ngx_str_t uri;
#if (NGX_HTTP_SSL)
ngx_str_t ssl_name;
#endif
// 暫時相當於一個表示是否清理資源的標誌位
ngx_http_cleanup_pt *cleanup;
// 是否指定緩存路徑
unsigned store:1;
// 是否啓用文件緩存
unsigned cacheable:1;
unsigned accel:1;
// 是否基於SSL協議訪問上游服務器
unsigned ssl:1;
#if (NGX_HTTP_CACHE)
unsigned cache_status:3;
#endif
// 向下遊轉發上游包體時,是否開啓更大的內存及臨時磁盤文件用於緩存
unsigned buffering:1;
unsigned keepalive:1;
unsigned upgrade:1;
// 表示是否已經向上遊服務器發送了請求
unsigned request_sent:1;
// 表示是否把包頭轉發給客戶端
unsigned header_sent:1;
};
ngx_http_upstream_conf_t
這個結構體指定了upstream的運行方式。它必須在啓動upstream機制前設置。
typedef struct {
/* 當ngx_http_upstream_t中沒有實現resolved成員時,這個變量纔會生效,
用來定義上游服務器的配置 */
ngx_http_upstream_srv_conf_t *upstream;
// 建立TCP連接的超時時間,實際上就是寫事件添加到定時器中時設置的超時時間
ngx_msec_t connect_timeout;
// 發送請求超時時間,通常是寫事件添加的定時器中設置的超時時間
ngx_msec_t send_timeout;
// 接收響應的超時時間,通常是讀事件添加的定時器中設置的超時時間
ngx_msec_t read_timeout;
ngx_msec_t timeout;
ngx_msec_t next_upstream_timeout;
// TCP的SO_SNOLOWAT選項,表示發送緩衝區的下限
size_t send_lowat;
// 定義了接收頭部的緩衝區大小(ngx_http_upstream_t中的buffer緩衝區)
size_t buffer_size;
size_t limit_rate;
// 當buffering=1,並且向下遊轉發響應時生效
size_t busy_buffers_size;
// buffering=1,若上游速度快於下游,則可能把上游的響應存在臨時文件中的臨時文件大小
size_t max_temp_file_size;
// 一次寫入臨時文件的字符流最大長度
size_t temp_file_write_size;
size_t busy_buffers_size_conf;
size_t max_temp_file_size_conf;
size_t temp_file_write_size_conf;
// 以緩存響應的方式轉發上游服務器的包體時所用的內存大小
ngx_bufs_t bufs;
// 針對ngx_http_upstream_t中的header_in成員,ignore_headers可根據位操作跳過一些頭部
ngx_uint_t ignore_headers;
// 以二進制來表示一些錯誤碼,會根據這些錯誤碼重新選擇新的上游服務器
ngx_uint_t next_upstream;
// 表示創建的目錄、文件的權限
ngx_uint_t store_access;
ngx_uint_t next_upstream_tries;
/* 決定轉發響應方式的標誌位
1:認爲上游快於下游,會盡量地在內存或者磁盤中緩存來自上游的響應;
0:僅開闢一塊固定大小的內存塊作爲緩存來轉發響應 */
ngx_flag_t buffering;
ngx_flag_t request_buffering;
ngx_flag_t pass_request_headers;
ngx_flag_t pass_request_body;
// 1:上游服務器交互時不檢查是否與下游客戶端斷開連接,繼續執行交互內容
ngx_flag_t ignore_client_abort;
// 截取錯誤碼,查看是否有對應可以返回的語義
ngx_flag_t intercept_errors;
// 1:試圖複用臨時文件中已經使用過的空間
ngx_flag_t cyclic_temp_file;
ngx_flag_t force_ranges;
// 存放臨時文件的路徑
ngx_path_t *temp_path;
// 根據ngx_http_upstream_hide_headers_hash函數構造出的需要隱藏的HTTP頭部散列表
ngx_hash_t hide_headers_hash;
// 不希望轉發的頭部
ngx_array_t *hide_headers;
// 明確希望轉發的頭部
ngx_array_t *pass_headers;
// 連接上游服務器時的本機地址
ngx_http_upstream_local_t *local;
#if (NGX_HTTP_CACHE)
ngx_shm_zone_t *cache_zone;
ngx_http_complex_value_t *cache_value;
ngx_uint_t cache_min_uses;
ngx_uint_t cache_use_stale;
ngx_uint_t cache_methods;
ngx_flag_t cache_lock;
ngx_msec_t cache_lock_timeout;
ngx_msec_t cache_lock_age;
ngx_flag_t cache_revalidate;
ngx_array_t *cache_valid;
ngx_array_t *cache_bypass;
ngx_array_t *no_cache;
#endif
// 表示存放路徑的長度
ngx_array_t *store_lengths;
// 表示存放路徑
ngx_array_t *store_values;
#if (NGX_HTTP_CACHE)
signed cache:2;
#endif
// 與ngx_http_upstream_t中的store一樣
signed store:2;
// 1:捕獲到404直接轉發
unsigned intercept_404:1;
/* 1:用於動態決定buffering標誌位。根據ngx_http_upstream_t的headers_in中的
X-Accel-Buffering(yes/no)的值來確定buffering */
unsigned change_buffering:1;
#if (NGX_HTTP_SSL)
ngx_ssl_t *ssl;
ngx_flag_t ssl_session_reuse;
ngx_http_complex_value_t *ssl_name;
ngx_flag_t ssl_server_name;
ngx_flag_t ssl_verify;
#endif
// 使用upstream的模塊名稱,僅用於記錄日誌
ngx_str_t module;
} ngx_http_upstream_conf_t;