nginx状态码部分源码梳理

nginx状态码处理函数

nginx记录状态码函数是ngx_http_reqstat_log_handler。

这个函数在ngx_http_reqstat_init处理时放在了log phase。

static ngx_int_t

ngx_http_reqstat_init(ngx_conf_t *cf)

{

...
h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
*h = ngx_http_reqstat_log_handler;
...

}

接下来根据保存好的状态码来进行记录

static ngx_int_t

ngx_http_reqstat_log_handler(ngx_http_request_t *r)

{

...

    // 判断status
    if (r->err_status) {
        status = r->err_status;
    } else if (r->headers_out.status) {
        status = r->headers_out.status;
    } else if (r->http_version == NGX_HTTP_VERSION_9) {
        status = 9;
    } else {
        status = 0;
    }

    // 根据status进行判断对全部的req状态码进行处理
    switch (status) {
        case 500:
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_500, 1);
            break;
        case 502:
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_502, 1);
            break;
        // 处理5xx和4xx upstream_states是个数组 选取的是最后一个元素的状态码

        if (r->upstream_states != NULL && r->upstream_states->nelts > 0) {
            ngx_http_upstream_state_t *state = r->upstream_states->elts;
            status = state[r->upstream_states->nelts - 1].status;

            if (status >= 400 && status < 500) {
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_4XX, 1);
            } else if (status >= 500 && status < 600) {
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_5XX, 1);
            } else if (status >= 200 && status < 300) {
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_2XX, 1);
        }   

    }
...

}

ngx_http_upstream_connect过程中,每次连接都会使用一个新的state(array类型)

void

ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)

{

...
    // 从states选取一个state记录后端的状态
    u->state = ngx_array_push(r->upstream_states);
    ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
    rc = ngx_event_connect_peer(&u->peer);

    // NGX_BUSY意味着后端断开了
    if (rc == NGX_BUSY) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE);
        return;
    }

    // 如果connect阶段都ok则发送request
    ngx_http_upstream_send_request(r, u, 1);
...

}
static void
ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
    ngx_uint_t do_write)

{

...

    // 获取状态码
    rc = ngx_http_upstream_send_request_body(r, u, do_write);

    if (rc == NGX_ERROR) {
        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
        return;
    }

    // 如果状态码异常 则用该状态码结束请求
    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        ngx_http_upstream_finalize_request(r, u, rc);
        return;
    }
...

}

在get round robin peer的时候判断健康检查失败与否

ngx_int_t

ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)

{

...
    #if (NGX_HTTP_UPSTREAM_CHECK)
        if (ngx_http_upstream_check_peer_down(peer->check_index)) {
            goto failed;
        }
    #endif

failed:
return NGX_BUSY;
...

}

ngx_http_upstream_next

static void

ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
    ngx_uint_t ft_type)
{

...
    switch (ft_type) {
        case NGX_HTTP_UPSTREAM_FT_TIMEOUT:
            status = NGX_HTTP_GATEWAY_TIME_OUT;
            break;
        case NGX_HTTP_UPSTREAM_FT_HTTP_500:
            status = NGX_HTTP_INTERNAL_SERVER_ERROR;
            break;
        case NGX_HTTP_UPSTREAM_FT_HTTP_403:
            status = NGX_HTTP_FORBIDDEN;
            break;
        case NGX_HTTP_UPSTREAM_FT_HTTP_404:
            status = NGX_HTTP_NOT_FOUND;
            break;

        /*
         * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
         * never reach here
         */

        default:
            status = NGX_HTTP_BAD_GATEWAY;

    if (status) {
        u->state->status = status;
        timeout = u->conf->next_upstream_timeout;
        // 以这个status终结
        ngx_http_upstream_finalize_request(r, u, status);
    }
...

}

//ngx_http_upstream_finalize_request中会调用finalize request

void
ngx_http_upstream_finalize_request(ngx_http_request_t *r,
    ngx_http_upstream_t *u, ngx_int_t rc)
{

...
    // 以这个状态码结束request
    ngx_http_finalize_request(r, rc);
...

}
void

ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)

{

...
    // 状态码异常
    if (rc >= NGX_HTTP_SPECIAL_RESPONSE
        || rc == NGX_HTTP_CREATED
        || rc == NGX_HTTP_NO_CONTENT)
    {
        if (rc == NGX_HTTP_CLOSE) {
            ngx_http_terminate_request(r, rc);
            return;
        }

        if (r == r->main) {
            if (c->read->timer_set) {
                ngx_del_timer(c->read);
            }

            if (c->write->timer_set) {
                ngx_del_timer(c->write);
            }
        }

        c->read->handler = ngx_http_request_handler;
        c->write->handler = ngx_http_request_handler;
        // 特殊状态码回调handler
        ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
        return;
    }
...

}
ngx_int_t

ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)

{

...
    // err_status赋值
    r->err_status = error;
    // 接下来是错误页的返回
...

}

ngx_http_reqstat_show_handler

在配置文件中配置了check_req_status查看nginx节点请求数据状态,真正展示状态码计数的是这个配置。

location /check_req_status {

        req_status_show req_server_status;

}

static ngx_int_t

ngx_http_reqstat_show_handler(ngx_http_request_t *r)

{

...
    for (j = 0; j < rlcf->user_select->nelts; j++) {
        if (user[j] < NGX_HTTP_REQSTAT_RSRV) {
            index = user[j];
            b->last = ngx_slprintf(b->last, b->end, "%uA,",
                                  *NGX_HTTP_REQSTAT_REQ_FIELD(node,
                                  ngx_http_reqstat_fields[index]));
        } else {
            index = user[j] - NGX_HTTP_REQSTAT_RSRV;
            b->last = ngx_slprintf(b->last, b->end, "%uA,",
                                   *NGX_HTTP_REQSTAT_REQ_FIELD(node,
                                   NGX_HTTP_REQSTAT_EXTRA(index)));
        }
    }
...

}

off_t ngx_http_reqstat_fields[30] = {
    NGX_HTTP_REQSTAT_BYTES_IN,
    NGX_HTTP_REQSTAT_BYTES_OUT,
    NGX_HTTP_REQSTAT_CONN_TOTAL,
    NGX_HTTP_REQSTAT_REQ_TOTAL,
    NGX_HTTP_REQSTAT_2XX,
    NGX_HTTP_REQSTAT_3XX,
    NGX_HTTP_REQSTAT_4XX,
    NGX_HTTP_REQSTAT_5XX,
    NGX_HTTP_REQSTAT_OTHER_STATUS,
    NGX_HTTP_REQSTAT_RT,
    NGX_HTTP_REQSTAT_UPS_REQ,
    NGX_HTTP_REQSTAT_UPS_RT,
    NGX_HTTP_REQSTAT_UPS_TRIES,
    NGX_HTTP_REQSTAT_200,
    NGX_HTTP_REQSTAT_206,
    NGX_HTTP_REQSTAT_302,
    NGX_HTTP_REQSTAT_304,
    NGX_HTTP_REQSTAT_403,
    NGX_HTTP_REQSTAT_404,
    NGX_HTTP_REQSTAT_416,
    NGX_HTTP_REQSTAT_499,
    NGX_HTTP_REQSTAT_500,
    NGX_HTTP_REQSTAT_502,
    NGX_HTTP_REQSTAT_503,
    NGX_HTTP_REQSTAT_504,
    NGX_HTTP_REQSTAT_508,
    NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS,
    NGX_HTTP_REQSTAT_UPS_4XX,
    NGX_HTTP_REQSTAT_UPS_5XX,
    NGX_HTTP_REQSTAT_UPS_LATENCY
};

lantency状态码修改

typedef struct {
    ngx_uint_t         status;                                                          
    ngx_msec_t         response_time;                                                  
    ngx_msec_t                       connect_time;                                                     
    ngx_msec_t                       header_time;                                                      
    ngx_msec_t                       queue_time;                                                       
    off_t                            response_length;                                                  
    off_t                            bytes_received;                                                   
    off_t                           bytes_sent;                                                                                                            
    ngx_str_t                       *peer;                                                             
} ngx_http_upstream_state_t;



static void
ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)

{

...
rc = u->process_header(r);
// 获取header time时间
u->state->header_time = ngx_current_msec - u->start_time;
...

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值