关键数据结构
1 ngx_http_upstream_s
其结构定义为
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;//连接到后端服务器的连接对象
ngx_event_pipe_t *pipe;//开启缓存时用于将上游数据发到下游
ngx_chain_t *request_bufs; //用于存放发到上游的消息的缓存
//用于将数据发送到上游
ngx_output_chain_ctx_t output;
ngx_chain_writer_ctx_t writer;
ngx_http_upstream_conf_t *conf;//表示依赖upstream的其它http模块的上游配置
ngx_http_upstream_srv_conf_t *upstream;//上游的upstream的srv配置
#if (NGX_HTTP_CACHE)
ngx_array_t *caches;//开启NGX_HTTP_CACHE时的缓存
#endif
//处理上游响应时处理头部
ngx_http_upstream_headers_in_t headers_in;
ngx_http_upstream_resolved_t *resolved;//解析到的上游信息
ngx_buf_t from_client;//用于存储下游数据的缓存
ngx_buf_t buffer;//用于接收响应的缓冲区
off_t length;//响应长度
//用于向下游发送响应的缓冲区
ngx_chain_t *out_bufs;
ngx_chain_t *busy_bufs;
ngx_chain_t *free_bufs;
ngx_int_t (*input_filter_init)(void *data);//处理上游响应包体的初始化操作
ngx_int_t (*input_filter)(void *data, ssize_t bytes);//处理上游响应包体
void *input_filter_ctx;
#if (NGX_HTTP_CACHE)
ngx_int_t (*create_key)(ngx_http_request_t *r);//开启缓存时用于创建缓存key
#endif
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);//结束请求
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);//重写cookie
ngx_msec_t start_time;//向上游发起连接的时间
ngx_http_upstream_state_t *state;//上游的状态信息
ngx_str_t method;//发往上游的方法
ngx_str_t schema;//发往上游的协议
ngx_str_t uri;//发往上游的uri
#if (NGX_HTTP_SSL || NGX_COMPAT)
ngx_str_t ssl_name;//开启ssl时为上游解析到的主机信息
#endif
ngx_http_cleanup_pt *cleanup;
unsigned store:1;//是否指定文件缓存路径的标识
unsigned cacheable:1;//是否开启文件缓存
unsigned accel:1;//暂时没有使用
unsigned ssl:1;//是否基于ssl协议访问上游
#if (NGX_HTTP_CACHE)
unsigned cache_status:3;//缓存状态
#endif
unsigned buffering:1;//当向下游转发上游的响应包体时,是否开启更大的内存及临时于缓存来不及发到下游的响应包体
unsigned keepalive:1;//是否与上游保活
unsigned upgrade:1;//上游是否在升级
unsigned error:1;
unsigned request_sent:1;//是否向上游发送过请求
unsigned request_body_sent:1;//是否向上游发送包体
unsigned request_body_blocked:1;//向上游发送包体是否发生阻塞
unsigned header_sent:1;//是否把包头转发给下游
};
2 ngx_http_upstream_conf_t
其结构定义为
typedef struct {
ngx_http_upstream_srv_conf_t *upstream;
ngx_msec_t connect_timeout;//控制连接上游的超时时间
ngx_msec_t send_timeout;//发送消息到上游的超时时间
ngx_msec_t read_timeout;//从上游读取消息的超时时间
ngx_msec_t next_upstream_timeout;//获取下一个可用上游的超时时间
size_t send_lowat;//控制在向上游写数据时的阀值,当大于这个阀值时才表示可写
size_t buffer_size;//用于接收上游响应头缓存区的大小
size_t limit_rate;//用于控制上下游转发响应里的速率
size_t busy_buffers_size;//当buffering=1,并且向下游转发响应时生效
size_t max_temp_file_size;//buffering=1,若上游速度快于下游,则可能把上游的响应存在临时文件中的临时文件大小
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_uint_t ignore_headers;//在处理上游响应头部时,根据位来忽略某些头
ngx_uint_t next_upstream;//根据错误码来选择下一个上游服务器
ngx_uint_t store_access;//创建目录和文件的权限
ngx_uint_t next_upstream_tries;//设置请求下一个上游的重试次数
ngx_flag_t buffering;//决定转发响应方式的标志位
ngx_flag_t request_buffering;//在将消息体发到上游时,是否缓存
ngx_flag_t pass_request_headers;//向上游发送请求时,是否透传下游的请求头
ngx_flag_t pass_request_body;//是否透传消息体,与buffering配合使用
ngx_flag_t ignore_client_abort;//当下游断开时,是否检查客户端状态
ngx_flag_t intercept_errors;//是否拦截上游返回的错误码,来决定返回下游错误信息
ngx_flag_t cyclic_temp_file;//复用临时文件中已经使用过的空间
ngx_flag_t force_ranges;//是否忽略上游的响应的"Accept-Ranges"
ngx_path_t *temp_path;//在开启缓存时,用于存放上游响应体的临时文件目录
ngx_hash_t hide_headers_hash;//用于处理上游响应头时,需要忽略的
ngx_array_t *hide_headers;//处理上游响应头时,需要忽略的,在初始化时会添加到hide_headers_hash这个表中
ngx_array_t *pass_headers;//在初始化时,在将hide_headers添加到hide_headers_hasha散列表前,如果在pass_headers中,则不加入到散列表中
ngx_http_upstream_local_t *local;//连接上游服务器时的本机地址
ngx_flag_t socket_keepalive;//用于配置连接上游时设置套装字的SO_KEEPALIVE
#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;
off_t cache_max_range_offset;
ngx_flag_t cache_lock;
ngx_msec_t cache_lock_timeout;
ngx_msec_t cache_lock_age;
ngx_flag_t cache_revalidate;
ngx_flag_t cache_convert_head;
ngx_flag_t cache_background_update;
ngx_array_t *cache_valid;
ngx_array_t *cache_bypass;
ngx_array_t *cache_purge;
ngx_array_t *no_cache;
#endif
ngx_array_t *store_lengths;//表示存放路径的长度
ngx_array_t *store_values;//表示存放路径
#if (NGX_HTTP_CACHE)
signed cache:2;
#endif
signed store:2;
unsigned intercept_404:1;//捕获到404直接转发
unsigned change_buffering:1;//动态修改upstream中的buffering
unsigned pass_trailers:1;//结束upstream时是否向下游发送trainer
unsigned preserve_output:1;//在向上游发送完请求后,是否继续输出,主要是设置upstream的write_event_handler,如果不继续,则设置为ngx_http_upstream_dummy_handler
#if (NGX_HTTP_SSL || NGX_COMPAT)
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;
ngx_http_complex_value_t *ssl_certificate;
ngx_http_complex_value_t *ssl_certificate_key;
ngx_array_t *ssl_passwords;
#endif
ngx_str_t module;
NGX_COMPAT_BEGIN(2)
NGX_COMPAT_END
} ngx_http_upstream_conf_t;
ngx_http_upstream_conf_t的设置
主要是在各自模块的handler来设置
模块 | Handler |
ngx_http_fastcgi_module | ngx_http_fastcgi_handler |
ngx_http_grpc_module | ngx_http_grpc_handler |
ngx_http_proxy_module | ngx_http_proxy_handler |
ngx_http_memcached_module | ngx_http_memcached_handler |
3 ngx_http_upstream_srv_conf_s
struct ngx_http_upstream_srv_conf_s {
ngx_http_upstream_peer_t peer;//上游服务对端
void **srv_conf;//服务配置,对应ngx_http_conf_ctx_t中的srv_conf
//ngx_http_upstream_module在处理server指令添加
ngx_array_t *servers; /* ngx_http_upstream_server_t */
ngx_uint_t flags;//值可以为以下位值 NGX_HTTP_UPSTREAM_CREATE,NGX_HTTP_UPSTREAM_WEIGHT,NGX_HTTP_UPSTREAM_MAX_CONNS,NGX_HTTP_UPSTREAM_MAX_FAILS,NGX_HTTP_UPSTREAM_FAIL_TIMEOUT,NGX_HTTP_UPSTREAM_DOWN
ngx_str_t host;//对应upstream指令的name
u_char *file_name;//配置所在文件
ngx_uint_t line;//配置所在行
in_port_t port;//端口号,默认是0
ngx_uint_t no_port; /* unsigned no_port:1 *///没有端口标识,默认是1
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_shm_zone_t *shm_zone;//ngx_http_upstream_zone_module和ngx_stream_upstream_zone_module会使用到
#endif
};
4 ngx_http_upstream_peer_t
typedef struct {
ngx_http_upstream_init_pt init_upstream;//初始化upstream的处理器
ngx_http_upstream_init_peer_pt init;//初始化peer的处理器
void *data;//peer的数据,不同的负载均衡有不同的数据结构
} ngx_http_upstream_peer_t;
5 ngx_http_upstream_rr_peers_s和ngx_http_upstream_rr_peer_s
负载均衡的轮询方式会使用
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;//总的权重值 是经过加权计算得出
ngx_uint_t tries;//不包含处于down下线状态的服务器的个数,用于重试计数
unsigned single:1;//仅有一个peer server
unsigned weighted:1;
ngx_str_t *name;
ngx_http_upstream_rr_peers_t *next;//下一个peer server
ngx_http_upstream_rr_peer_t *peer;//当前轮询的peer server
};
//在ngx_http_upstream_init_round_robin中设置
struct ngx_http_upstream_rr_peer_s {
struct sockaddr *sockaddr;//服务端地址
socklen_t socklen;//服务端sock长度
ngx_str_t name;//服务地址名
ngx_str_t server;//服务名
ngx_int_t current_weight;//当前权重,初始为0
ngx_int_t effective_weight;//有效权重,不会大于weight
ngx_int_t weight;//配置的权重
ngx_uint_t conns;//连接数
ngx_uint_t max_conns;//最大连接数
ngx_uint_t fails;//失败数
time_t accessed;//记录失败时的时间
time_t checked;//用于失败检查恢复的时间
ngx_uint_t max_fails;//最大失败数
time_t fail_timeout;//失败超时时间
ngx_msec_t slow_start;
ngx_msec_t start_time;
ngx_uint_t down;
#if (NGX_HTTP_SSL || NGX_COMPAT)
void *ssl_session;
int ssl_session_len;
#endif
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_atomic_t lock;
#endif
ngx_http_upstream_rr_peer_t *next;
NGX_COMPAT_BEGIN(32)
NGX_COMPAT_END
};
6 ngx_peer_connection_s
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;
ngx_event_get_peer_pt get;//获取远端服务器函数指针,其定义为typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,void *data);
ngx_event_free_peer_pt free;//释放远端服务器函数指针,其定义为typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,ngx_uint_t state);
ngx_event_notify_peer_pt notify;//通知远端服务器函数指针,其定义为typedef void (*ngx_event_notify_peer_pt)(ngx_peer_connection_t *pc,void*data, ngx_uint_t type);
void *data;
#if (NGX_SSL || NGX_COMPAT)
ngx_event_set_peer_session_pt set_session;
ngx_event_save_peer_session_pt save_session;
#endif
ngx_addr_t *local;
int type;
int rcvbuf;
ngx_log_t *log;
unsigned cached:1;
unsigned transparent:1;
unsigned so_keepalive:1;
unsigned down:1;
/* ngx_connection_log_error_e */
unsigned log_error:2;
NGX_COMPAT_BEGIN(2)
NGX_COMPAT_END
};
依赖关系
upstream的抽象设计
input_filter_init:处理上游响应包体前的初始化操作
input_filter:处理上游响应包体
create_key:在开启缓存时,创建缓存的key
create_request:创建发送到上游的请求
reinit_request:在出错时,重新初始化发送到上游的请求
process_header:处理上游返回的包头
abort_request:丢弃上游的请求
finalize_request:结束上游请求
rewrite_redirect:在上游返回的响应包头中包含Location或者Refresh,ngx_http_upstream_process_headers会调用重写重定向
rewrite_cookie:在上游返回的响应包头中包含Set-Cookie时,ngx_http_upstream_process_headers会调用重写cookie