天天看點

《深入了解nginx》筆記之 ngx_upstream相關結構

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:;
    // 是否啟用檔案緩存
    unsigned                         cacheable:;
    unsigned                         accel:;
    // 是否基于SSL協定通路上遊伺服器
    unsigned                         ssl:;
#if (NGX_HTTP_CACHE)
    unsigned                         cache_status:;
#endif

     // 向下遊轉發上遊包體時,是否開啟更大的記憶體及臨時磁盤檔案用于緩存
    unsigned                         buffering:;
    unsigned                         keepalive:;
    unsigned                         upgrade:;

     // 表示是否已經向上遊伺服器發送了請求
    unsigned                         request_sent:;

    // 表示是否把標頭轉發給用戶端
    unsigned                         header_sent:;
};
           

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:;
#endif

     // 與ngx_http_upstream_t中的store一樣
    signed                           store:;

    // 1:捕獲到404直接轉發
    unsigned                         intercept_404:;

    /* 1:用于動态決定buffering标志位。根據ngx_http_upstream_t的headers_in中的
    X-Accel-Buffering(yes/no)的值來确定buffering */
    unsigned                         change_buffering:;

#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;
           

繼續閱讀