ngx_event_pipe 提供了upstream对上游服务器返回包体数据 同时能做将包体数据发送请求端
ngx_event_pipe具体的结构在点击打开链接
ngx_event_pipe函数负责在upstream包体数据处理过程中读取上游服务器包体数据 并且在处理上游包体数据的过程中 发送到请求端 这种处理流程经过测试验证 的确如此。
提供给upstream模块服务的函数只有ngx_event_pipe 其内置处理的函数有:
ngx_event_pipe_read_upstream 负责读取上游返回的包体 ngx_event_pipe_write_to_downstream负责将包体发送到请求端
ngx_event_pipe_write_chain_to_temp_file 会将包体的数据逐步写入到一个临时文件 这里的临时文件到后面被用作缓存文件
ngx_event_pipe_remove_shadow_links
ngx_event_pipe_drain_chains
ngx_event_pipe函数处理过程
ngx_int_t
ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
{
...
for ( ;; ) {
if (do_write) {
p->log->action = "sending to client";
rc = ngx_event_pipe_write_to_downstream(p); //写标记 包体数据写入到下游请求端
if (rc == NGX_ABORT) {
return NGX_ABORT;
}
if (rc == NGX_BUSY) { //来不及处理
return NGX_OK;
}
}
p->read = 0;
p->upstream_blocked = 0;
p->log->action = "reading upstream";
if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) { //执行上游包体数据读取处理
return NGX_ABORT;
}
if (!p->read && !p->upstream_blocked) { //在上游包体读取未阻塞状态下 没有读取到数据 跳出
break;
}
do_write = 1; //包体读取一般先执行
}
if (p->upstream->fd != (ngx_socket_t) -1) { //对上游连接的socket是有效的
rev = p->upstream->read;
flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0; //上游包体读取出错或者没有数据可读 事件会被清理 否则什么也不做
if (ngx_handle_read_event(rev, flags) != NGX_OK) { //满足flag标记对读事件的处理
return NGX_ABORT;
}
... //添加定时器
}
if (p->downstream->fd != (ngx_socket_t) -1
&& p->downstream->data == p->output_ctx) //同上
{
wev = p->downstream->write;
if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) { //对低潮值进行发送(如果有) 同时会对请求端的写事件进行处理
return NGX_ABORT;
}
... //定时器
}
return NGX_OK;
}
nginx_event_pipe_read_upstream 处理说明
static ngx_int_t
ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
{
...
if (p->upstream_eof || p->upstream_error || p->upstream_done) {
return NGX_OK;
}
#if (NGX_THREADS)
...
#endif
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe read upstream: %d", p->upstream->read->ready);
for ( ;; ) {
if (p->upstream_eof || p->upstream_error || p->upstream_done) {
break;
}
if (p->preread_bufs == NULL && !p->upstream->read->ready) {
break;
}
if (p->preread_bufs) { //pre-read 预读取buffer (包含了缓存header头部和key信息 以及http头) 实际由u->buffer传入
/* use the pre-read bufs if they exist */
chain = p->preread_bufs;
p->preread_bufs = NULL;
n = p->preread_size;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe preread: %z", n);
if (n) { //已经读取了数据read标记
p->read = 1;
}
} else {
#if (NGX_HAVE_KQUEUE)
/*
* kqueue notifies about the end of file or a pending error.
* This test allows not to allocate a buf on these conditions
* and not to call c->recv_chain().
*/
if (p->upstream->read->available == 0
&& p->upstream->read->pending_eof)
{
p->upstream->read->ready = 0;
p->upstream->read->eof = 1;
p->upstream_eof = 1;
p->read = 1;
if (p->upstream->read->kq_errno) {