nginx upstream模块详解(处理流程篇二 upstream与event_pipe交互)

本文详细介绍了nginx中upstream模块与ngx_event_pipe的交互,ngx_event_pipe用于处理上游服务器返回的包体数据,并将其发送到请求端。主要涉及的函数包括ngx_event_pipe_read_upstream(读取上游数据)、ngx_event_pipe_write_to_downstream(发送到下游)。同时,ngx_event_pipe还涉及包体数据的临时文件存储和缓存。整个处理流程在ngx_http_upstream_process_upstream和ngx_http_upstream_process_downstream的触发下进行。
摘要由CSDN通过智能技术生成

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) {
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值