[nginx] upstream结束和keepalive实现
来源:互联网 发布:ni usb数据采集卡介绍 编辑:程序博客网 时间:2024/06/08 13:17
- upstream请求结束:数据交互出错、后端关闭socket时nginx接收到FIN、content-length数据已接收到
- upstream结束的主函数:
ngx_http_upstream_finalize_request()
- keepalive机制:nginx长连接
一、upstream finalize
upstream请求结束分三种情况:
- read()、write()过程中出现NGX_ERROR/NGX_ABORT,表示请求过程中发生异常,设置
p->upstream_error = 1
; - read()函数时后端关闭socket,后端系统发送FIN分节到nginx,接收到该信号则设置
rev->ready = 0
和p->upstream_eof = 1
; - 正常情况下,upstream接收Header时会记录content-length,然后接收body时减小p->length的值,当所有body接收完时p->length=0,并设置
p->upstream_done = 1
;
分析ngx_http_upstream_finalize_request()
:
- 清除cleanup指针,因为在upstream的前面阶段:create、init、发送请求、接收Headers时出现异常则会调用
ngx_http_finalize_request()
,并执行cleanup()的调用。所以这里首先要清除cleanup指针; u->finalize_request()
,实际调用ngx_http_proxy_finalize_request
,没有任何操作;u->peer.free()
,实际调用’ngx_http_upstream_keepalive_close_handler()’进行peer的“关闭”操作;- 如果peer->connection不为空,则关闭connection,原因是上一步有可能是keepalive里把connection放到cache里后置为空,所以不用关闭connection;
ngx_http_send_special()
,设置一个带有last标志的特殊buffer,告知数据发送环节需要将之前缓存而没有发送的buffer chain,发送出去;ngx_http_finalize_request()
,结束请求- 如果还没数据没发送完
c->buffered
不为0,则设置write句柄为ngx_http_write
,表示要继续发送数据,在函数ngx_http_write
中ngx_htt_finalize_request()
是最后执行,形成递归; - 若数据发送完了,则直接干到这一行
r->done = 1
,标记结束,并把client的write句柄关闭 ngx_http_post_action()
,若无后续操作,则无实际执行- 如果socket关闭了,会发送FIN分节,标记
c->read->eof
,执行ngx_http_close_request()
关闭socket,???? ngx_http_finalize_connection()
,关闭链接- 检查请求的引用计数器,不等于1说明还有多个动作在操作着请求???(请求创建时
ngx_http_create_request()
该值赋为1); - 引用计数器为1时,检查keepalive是否超时,接着结束keepalive请求返回;
- 调用
ngx_http_set_lingering_close()
,默认lingering超时是5s- 设置
ngx_http_lingering_close_handler()
读事件,意思客户端在lingering_timeout时间内没有进行任何操作,那么就会关闭与客户端的连接,如果有操作,也有总时间lingering_time超时,然后调用ngx_http_close_request()
ngx_shutdown_socket(fd, NGX_WRITE_SHUTDOWN)
关闭socket写端;- 调用
ngx_http_lingering_close_handler()
,进一步会ngx_http_free_request()
打印请求日志、释放request,ngx_http_close_connection()
中释放connection,并ngx_close_socket(fd)
回收描述符。lingering机制详见nginx lingering_close,进一步也可以了解与之相关的case:nginx的延迟关闭。
- 设置
- 检查请求的引用计数器,不等于1说明还有多个动作在操作着请求???(请求创建时
- 如果还没数据没发送完
二、upstream keepalive
启用nginx到upstream的keepalive,需要设置proxy http\1.1和覆盖connection为空(nginx默认会置为close)。
2.1 数据发送
ngx_http_proxy_create_request()
,nginx首先准备好发向upstream的数据;- 调用
uscf->peer.init()
,实际调用ngx_http_upstream_init_keepalive_peer()
==>ngx_http_upstream_init_round_robin_peer()
,通过负载均衡引擎获取一个后端服务节点; - 是否连接该服务节点取决于keepalive queue中是否能从cache队列线性查找到该节点,若查找到则从队列中移出该节点,并将节点放到空闲队列free;
ngx_http_upstream_send_request()
,向该节点发送数据。
2.2 数据接收
- 先接收upstream发来的Header,一边接收一边解析,直到完整接收到Header
- nginx立即将Headers发送给client,再接收Body,一边从upstream接收一边发往client,但这里底层实际上是先buffer住,等所有数据接收完才发往client发送数据;
- 其中p->length记录了待接收数据的长度(解析header时用content-length赋值给u->length然后调用ngx_http_proxy_input_filter_init()赋值给p->length),每次收到数据会减小,直到p->length为0时,会判断connection_close(在http\1.0下默认为1否则为0),当upstream返回connection:close时设置为1,以决定是否keepalive;
- 若遇到readv()返回0表示upstream发送了FIN信号而关闭的远端socket,则nginx也后续相应关闭链接;
- 最后若对方socket未关闭、socket未出错、keepalive,则会把后端节点的连接对象存放到cache队列头部,如果队列满了,则释放列队尾部的一个元素,LRU淘汰策略。
0 0
- [nginx] upstream结束和keepalive实现
- Nginx Upstream Keepalive 分析
- Nginx Upstream Keepalive 分析
- Nginx Upstream Keepalive 分析
- Nginx Upstream Keepalive配置
- Nginx Upstream Keepalive 分析
- Nginx Upstream Keepalive 分析
- Nginx Upstream Keepalive配置
- Nginx Upstream Keepalive配置
- nginx + keepalive 实现HA
- [nginx] proxy和upstream模块
- Nginx upstream原理分析【1】upstream和FastCGI前篇
- Nginx upstream原理分析【1】upstream和FastCGI前篇
- NGINX UPSTREAM
- nginx upstream
- Nginx 中 upstream 机制的实现
- Nginx配置upstream实现负载均衡
- Nginx配置upstream实现负载均衡
- [OpenGL]矩阵乘法引发的血案
- Codeforces Beta Round #17 C. Balance DP
- Matplotlib进阶:Seaborn教程
- JSON之stringify()、parse()
- Java提高篇(二六)------hashCode
- [nginx] upstream结束和keepalive实现
- spring的学习(二)
- 跟踪分析Linux内核的启动过程
- 传输层协议
- 关键词break, python
- 数据库范式
- hdu2083简易版最短路径。。简单数学题
- S2 xml 经典解析 居委会
- Linux下diff和patch命令以及简单补丁