3.stream_proxy深度解析
2023-03-15 18:20:44 0 举报
AI智能生成
nginx stream proxy模块的配置解析
作者其他创作
大纲/内容
基础配置
<b>三大模块函数列表</b><br>(proxy模块必须包含三个模块)
<b>ngx_sream_upstream_module</b>
ngx_stream_upstream.c
upstream提供的变量
upstream提供的变量, 可以打印日志
1.<b>upstream_addr</b>: 上游服务器的IP地址,格式为可读的字符串,例如127.0.0.1:8080<br> <br>2.<b>upstream_connect_time</b>: 与上游服务器建立连接消耗的时间,单位为秒,精确到毫秒<br><br>
子主题
子主题
子主题
ngx_stream_upstream_round_robin.c
<b>ngx_stream_write_filter_module</b>
ngx_stream_write_filter_module.c
<b>ngx_stream_proxy_module</b>
ngx_stream_proxy_module.c
数据结构
stream_module
upstream_module
1. 上游服务器的基本信息: (us)<b><br><font color="#4669ea">ngx_stream_upstream_server_t</font></b><br>
<b>指令配置项中解析: <br><font color="#a23c73">ngx_stream_upstream_commands</font>[]{<br></b><span style="font-size: inherit; font-weight: bold;"> </span><span style="font-size: inherit;">ngx_string</span><span style="font-size: inherit; font-weight: bold;">(</span><font style="font-size: inherit; font-weight: bold;" color="#358e90"><b style="">"server"</b></font><span style="font-size: inherit; font-weight: bold;">), ----server{}中解析配置</span><b><br></b> <b><font color="#569230">ngx_stream_upstream_server</font></b>, ----解析处理函数<br>}<br><br>typedef struct {<br> ngx_str_t <b>name</b>; //域名<br> ngx_addr_t <b>*addrs; </b>//解析地址<br> ngx_uint_t <b> naddrs; </b>//解析出的地址个数<br> ngx_uint_t <b> weight; </b>//服务器所在权重<br> ngx_uint_t <b>max_conns; </b>//服务器最大连接数<br> ngx_uint_t <b> max_fails;</b><br> time_t <b>fail_timeout;</b><br> <font color="#9e9e9e">ngx_msec_t </font><b><font color="#9e9e9e"> slow_start</font>; <font color="#9e9e9e">//开源版本未使用</font></b><br> ngx_uint_t <b> down;</b><br><br> unsigned <b> backup:1;</b><br>} <b><font color="#314aa4">ngx_stream_upstream_server_t</font></b>;<br>
(权重值)<br>weight = 1;<br>
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strncmp</font></b>(value[i].data,<b><font color="#a23735"> "weight="</font></b>, 7) == 0) {<br> <b>weight </b>= <b><font color="#569230">ngx_atoi</font></b>(&value[i].data[7], value[i].len - 7);<br>}<br>
允许server的最大连接数<br>max_conns = 0;<br>
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strncmp</font></b>(value[i].data,<font color="#a23735"> <b>"max_conns=",</b></font> 10) == 0)<br> <b>max_conns </b>= <b><font color="#569230">ngx_atoi</font></b>(&value[i].data[10], value[i].len - 10);<br>}<br>
允许的最大失败次数<br>max_fails = 1;
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strncmp</font></b>(value[i].data,<font color="#a23735"><b>"max_fails="</b></font>, 10) == 0)<br> <b>max_conns </b>= <b><font color="#569230">ngx_atoi</font></b>(&value[i].data[10], value[i].len - 10);<br>}<br>
失败的时间区间<br>fail_timeout = 10;<br>
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strncmp</font></b>(value[i].data, <font color="#a23735"><b>"fail_timeout="</b></font>, 13)<br> s.len = value[i].len - 13;<br> s.data = &value[i].data[13];<br><br> <b><font color="#000000">fail_timeout </font></b>= <b><font color="#569230">ngx_parse_time</font></b>(&s, 1);<br>}<br>
是否为备用服务器<br>backup=0;<br>
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strcmp</font></b>(value[i].data,<font color="#a23735"><b> "backup"</b></font>) == 0)<br> us-><b>backup </b>= 1;<br>}<br>
是否下线该服务器<br>down=0;<br>
<font color="#ed77b6"><b>关键代码段: </b></font><br>if (<b><font color="#569230">ngx_strcmp</font></b>(value[i].data,<font color="#a23735"><b> "down"</b></font>) == 0)<br> us-><b>down</b>= 1;<br>}<br>
<span style="font-weight: normal;">服务器地址URL</span><br>name<br>
<font color="#ed77b6"><b>关键代码段: <br></b></font>url = value[1]; --- 第一个参数就是URL<br>if (<b><font color="#569230">ngx_parse_url</font></b>(cf->pool, &<b>u</b>) != NGX_OK) --- 解析URL<br>if (u.no_port) --- 要求server必须有端口号<br><br>us->addrs = <b>u</b>.addrs;<br>us->naddrs = <b>u</b>.naddrs;<br>
服务器对应的地址数组,可能有多个ip地址<br><b>ngx_addr_t *addr</b><br>
// 服务器地址数组的长度,即个数<br><b>naddrs</b><br>
<b><font color="#9e9e9e"><strike>服务器的恢复时间<br></strike>(在开源版本中暂未有使用)<br>slow_start</font></b><br>
<b>2. srv块配置信息</b><br><b><font color="#314aa4">ngx_stream_upstream_srv_conf_s</font></b><br>
<b>typedef struct {</b><br> ngx_stream_upstream_init_pt init_upstream;<br> ngx_stream_upstream_init_peer_pt init;<br> void *data;<br>} <b><font color="#314aa4">ngx_stream_upstream_peer_t</font></b>;<br><br>struct <b><font color="#314aa4">ngx_stream_upstream_srv_conf_s</font></b> {<br> <b><font color="#314aa4">ngx_stream_upstream_peer_t</font></b> peer;<br> void **srv_conf;<br> //服务器数组<br> <b><font color="#4669ea">ngx_array_t *servers;</font> </b> ---上游服务器结构(<b><font color="#4669ea">ngx_stream_upstream_server_t</font></b>)<br> ngx_uint_t flags;<br> ngx_str_t host;<br> u_char *file_name;<br> ngx_uint_t line;<br> in_port_t port;<br> ngx_uint_t no_port; /* unsigned no_port:1 */<br>} <br>
3. upstream数据转发结构<br><b><font color="#314aa4">ngx_stream_upstream_t</font></b><br>
<br><br>typedef struct {<br> <b><font color="#a66a30">ngx_peer_connection_t </font></b>peer; ---从upstream获取的上游的server连接<br><br> ngx_buf_t downstream_buf; ---下行缓冲区<br> ngx_buf_t upstream_buf; ---上行缓冲区<br><br> ngx_chain_t *free; ---缓冲区的free空闲链表<br> ngx_chain_t *upstream_out; ---上行(下游往上游)发送缓冲链表<br> ngx_chain_t *upstream_busy; ---上行(下游往上游)最终发送缓冲链表<br> ngx_chain_t *downstream_out; ---下行(上游往下游)发送缓冲链表 <br> ngx_chain_t *downstream_busy; ---下行(上游往下游)发送缓冲链表<br><br> off_t received; ---接收到的总字节数<br> time_t start_sec; ---开始连接后端的时间, 限速配置开启时,用于计算速率<br> ngx_uint_t requests; ---上行接收到的包个数<br> ngx_uint_t responses; <br> ngx_msec_t start_time; ---开始启动连接时间, 毫秒<br><br> size_t upload_rate; ---上行速率<br> size_t download_rate; ---下行速率<br><br> <strike>ngx_str_t ssl_name; </strike><br><br> <font color="#314aa4"><b>ngx_stream_upstream_srv_conf_t</b></font> *upstream; ---上游服务块相关配置<br> ngx_stream_upstream_resolved_t *resolved; ---上游服务地址解析<br> ngx_stream_upstream_state_t *state; ---上游服务器连接状态查询信息<br> unsigned connected:1; ---是否已经成功连接上游服务器<br> unsigned proxy_protocol:1; ---是否启用了代理协议<br> unsigned half_closed:1; ---是否已经处于半关闭状态<br>} <b><font color="#314aa4">ngx_stream_upstream_t</font></b>;
4. upstream负载均衡
a. 轮询算法
struct <b><font color="#314aa4">ngx_stream_upstream_rr_peers_s </font></b>{<br> ngx_uint_t number; ---可用的上游服务器数量<br> ngx_uint_t total_weight; ---上游服务器总权重,用于各权重相加算法计算<br> ngx_uint_t tries; ---重试次数<br><br> unsigned single:1; ---是否为只有一个上游服务器<br> unsigned weighted:1; ---是否开启权重算法<br><br> ngx_str_t *name; ---服务器名称<br><br> <b>ngx_stream_upstream_rr_peers_t </b>*next; ---下一个上游服务器<br> <b>ngx_stream_upstream_rr_peer_t </b>*peer; ---下一个上游服务器 <br>};
typedef struct <b><font color="#314aa4">ngx_stream_upstream_rr_peer_s </font>ngx_stream_upstream_rr_peer_t</b>;<br><br>struct <b><font color="#314aa4">ngx_stream_upstream_rr_peer_s </font></b>{<br> struct sockaddr *sockaddr; // 上游服务器的地址<br> socklen_t socklen; // 地址长度<br> ngx_str_t name; // 上游服务器的名称<br> ngx_int_t current_weight; // 当前权重:<br> ngx_int_t effective_weight; // 有效权重:出错时,会降低权重值<br> ngx_int_t weight; // 权重:初始权重<br> ngx_uint_t conns; // 与该上游服务器建立的连接数<br> ngx_uint_t fails; // 连接失败的次数<br> ngx_uint_t max_fails; // 允许连接失败的最大次数<br> time_t fail_timeout; // 失败超时时间<br> time_t accessed; // 上次访问时间<br> ngx_uint_t down; // 是否下线<br> ngx_uint_t index; // 在轮询中的索引<br> <b>ngx_stream_upstream_rr_peer_t </b>*next; // 指向下一个上游服务器<br>};<br>
proxy_module
<b><font color="#314aa4">proxy_pass配置块</font></b>
<b>typedef struct {</b><br> ngx_addr_t *addr;<br> ngx_stream_complex_value_t *value; ---连接上游服务器的各种参数(超时、缓冲大小等)<br> ngx_uint_t transparent; ---开启透明代理,需要配合iptables路由表使用<br>} <b><font color="#5b79e8">ngx_stream_upstream_local_t</font><font color="#314aa4">;</font></b><br><br><b>typedef struct {</b><br> ngx_msec_t connect_timeout; ---连接上游事件超时时间<br> ngx_msec_t timeout; ---读写事件超时<br> ngx_msec_t next_upstream_timeout; ---连接上游服务器超时时间<br> size_t buffer_size; ---上游读取数据缓冲区大小<br> ngx_stream_complex_value_t *upload_rate; ---上行速率<br> ngx_stream_complex_value_t *download_rate; ---下行速率<br> ngx_uint_t requests; ---上行的包统计数<br> ngx_uint_t responses; ---下行的包统计数<br> ngx_uint_t next_upstream_tries; ---上行断开重试次数<br> ngx_flag_t next_upstream; ---默认值为1(是否有upstream? )<br> ngx_flag_t proxy_protocol; ---是否开启了代理协议<br> ngx_flag_t half_close; ---半关闭: 只有双方都读取到EOF才关闭连接<br> <b><font color="#5b79e8"> ngx_stream_upstream_local_t</font></b> *local; ---如上: 本端的一些配置<br> ngx_flag_t socket_keepalive; ---是否开启TCP keepAlive保活<br> ......................<br> ngx_stream_upstream_srv_conf_t *upstream; ---转发上游服务器集群upstream{}块<br> ngx_stream_complex_value_t *upstream_value; ---upstream支持的复杂变量<br>} <b><font color="#314aa4">ngx_stream_proxy_srv_conf_t</font></b>;<br>
<font color="#a66a30">上游服务连接信息</font>
struct <font color="#a66a30"><b>ngx_peer_connection_s </b>{</font><br> ngx_connection_t *connection; ---事件连接器<br> struct sockaddr *sockaddr; ---上游服务地址<br> socklen_t socklen; <br> ngx_str_t *name; ---上游服务名称<br> ngx_uint_t tries; ---最大重试次数<br> ngx_msec_t start_time; ---连接开始的时间,即发起主动连接的时刻<br><br> ngx_event_get_peer_pt get; ---从upstream{}里获取一个上游server地址, 如: ngx_stream_upstream_get_round_robin_peer()<br> ngx_event_free_peer_pt free; ---释放一个上游地址,如:ngx_stream_upstream_free_round_robin_peer()<br> ngx_event_notify_peer_pt notify; ---服务可用或者不可用状态变化,如: ngx_stream_upstream_notify_round_robin_peer()<br> void *data; ---get/free函数所需的参数<br> <br> ngx_addr_t *local; ---本地地址<br> int type; ---标记tcp/udp<br> int rcvbuf; ---接收缓冲区大小<br> ngx_log_t *log; ---日志对象<br><br> unsigned cached:1; ---连接是否已经缓存, 可以重复使用TCP连接, 避免重建TCP(HTTP中较为场景)<br> unsigned transparent:1; ---透明代理标记<br> unsigned so_keepalive:1; ---TCP连接保活标记<br> unsigned down:1; ---上游是否处于不可用状态<br>};<br>
write_filter_module
发送缓存
typedef struct {<br> ngx_chain_t *from_upstream; ---上行发送缓存<br> ngx_chain_t *from_downstream; ---下行发送缓存<br>} <b>ngx_stream_write_filter_ctx_t</b>;
事件与数据处理
客户端connect
客户端send
客户端recv
服务端recv
服务端send
定时器timer
自定义事件
调试
0 条评论
下一页