阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx http filter异常排查

103次阅读
没有评论

共计 5384 个字符,预计需要花费 14 分钟才能阅读完成。

问题:

  • 访问异常

    root@cloud:/usr/local/nginx# curl -i http://localhost/test.html
    curl: (52) Empty reply from server
  • 错误日志

    2016/09/11 13:17:03 [alert] 63560#0: worker process 63663 exited on signal 11 (core dumped)
  • dmesg 信息

    [265950.220943] nginx[63663]: segfault at 128 ip 000000000048259d sp 00007ffde898eab0 error 4 in nginx[400000+a5000]
  • core dump 设置
    默认 Worker 进程用户 nobody:nogroup,无法写 coredump. 需在 nginx.conf 配置:

    worker_rlimit_core 1024m; #1G
    working_directory /tmp/core # 保证 nobody:nogroup 有 W 权限

    执行 ”sbin/nginx -s reload” 重新加载配置。

  • core dump 分析
  • 使用 readelf 工具
    core dump 是 ELF 格式文件,你可以用 readelf -a 查看 core dump 文件,但哪只是一堆数据。
  • 使用 gdb 工具

    gdb <command> <core>

    一般会直接显示出错的代码位置

  • 位置 1

    conf = ngx_http_conf_get_module_loc_conf(r,ngx_http_myfilter_module); #应该是 ngx_http_get_module_loc_conf(...)
  • 位置 2

    myfilter_ctx_t *ctx;
    ctx = ngx_http_get_module_ctx(r, ngx_http_myfilter_module);
    if (ctx->add_prefix != 1) {应该先判断 ctx == NULL
        return next_body_filter(r, in);
    }

Nginx http filter 示例源码

ngx_addon_name=ngx_http_myfilter_module
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_myfilter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_myfilter_module.c"
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

static ngx_str_t filter_prefix = ngx_string("[my filter prefix]");
static ngx_http_output_header_filter_pt next_header_filter;
static ngx_http_output_body_filter_pt next_body_filter;

typedef struct {ngx_flag_t enable;
} myfilter_conf_t;

typedef struct {ngx_int_t add_prefix;
} myfilter_ctx_t;

static ngx_int_t myfilter_header_filter(ngx_http_request_t *r);
static ngx_int_t myfilter_body_filter(ngx_http_request_t *r, ngx_chain_t *in);
static ngx_int_t myfilter_init(ngx_conf_t *cf);

static void *myfilter_create_loc_conf(ngx_conf_t *cf);
static char *myfilter_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);

static ngx_http_module_t myfilter_conf = {NULL,
    myfilter_init,
    NULL,
    NULL,
    NULL,
    NULL,
    myfilter_create_loc_conf,
    myfilter_merge_loc_conf
};

static ngx_command_t myfilter_commands[] = {
    {ngx_string("add_prefix"),
        NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
        ngx_conf_set_flag_slot,
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(myfilter_conf_t, enable),
        NULL
    },
    ngx_null_command
};

ngx_module_t ngx_http_myfilter_module = {
    NGX_MODULE_V1,
    &myfilter_conf,
    myfilter_commands,
    NGX_HTTP_MODULE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NGX_MODULE_V1_PADDING
};

static ngx_int_t myfilter_init(ngx_conf_t *cf){
    next_header_filter = ngx_http_top_header_filter;
    next_body_filter = ngx_http_top_body_filter;

    ngx_http_top_header_filter = myfilter_header_filter;
    ngx_http_top_body_filter = myfilter_body_filter;

    return NGX_OK;
}

static ngx_int_t myfilter_header_filter(ngx_http_request_t *r){myfilter_conf_t *conf;
    myfilter_ctx_t *ctx;

    if(r->headers_out.status != NGX_HTTP_OK){return next_header_filter(r);
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_myfilter_module);
    if(ctx){return next_header_filter(r);
    }

    conf = ngx_http_get_module_loc_conf(r,ngx_http_myfilter_module);
    if(conf == NULL || conf->enable == 0){return next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(myfilter_ctx_t));
    if(ctx == NULL){return NGX_ERROR;
    }
    ctx->add_prefix = 0;
    ngx_http_set_ctx(r, ctx, ngx_http_myfilter_module);

    r->headers_out.status = NGX_HTTP_MOVED_TEMPORARILY;
    ngx_str_t keys = ngx_string("Location");
    ngx_str_t vals = ngx_string("http://www.163.com");
    ngx_table_elt_t *headers = ngx_list_push(&r->headers_out.headers);
    if(headers){
        headers->key.data = keys.data;
        headers->key.len = keys.len;
        headers->value.data = vals.data;
        headers->value.len = vals.len;
        headers->hash = 1;
    }

//  if (r->headers_out.content_type.len >= sizeof("text/plain") - 1
//          && ngx_strncasecmp(r->headers_out.content_type.data,
//                  (u_char *) "text/plain", sizeof("text/plain") - 1) == 0) {
        ctx->add_prefix = 1;
        if(r->headers_out.content_length_n > 0){r->headers_out.content_length_n += filter_prefix.len;}
//  }

    return next_header_filter(r);
}

static ngx_int_t myfilter_body_filter(ngx_http_request_t *r, ngx_chain_t *in) {myfilter_ctx_t *ctx;
    ctx = ngx_http_get_module_ctx(r, ngx_http_myfilter_module);
    if (ctx == NULL || ctx->add_prefix != 1) {return next_body_filter(r, in);
    }

    ctx->add_prefix = 2;
    ngx_buf_t *b = ngx_create_temp_buf(r->pool, filter_prefix.len);
    b->start = b->pos = filter_prefix.data;
    b->last = b->pos + filter_prefix.len;

    ngx_chain_t *cl = ngx_alloc_chain_link(r->pool);
    cl->buf = b;
    cl->next = in;
    return next_body_filter(r, cl);
}

static void *myfilter_create_loc_conf(ngx_conf_t *cf) {myfilter_conf_t *mycf;
    mycf = (myfilter_conf_t *)ngx_pcalloc(cf->pool, sizeof(myfilter_conf_t));
    if(mycf == NULL) return NULL;
    mycf->enable = NGX_CONF_UNSET;
    return mycf;
}

static char *myfilter_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child){myfilter_conf_t *prev = (myfilter_conf_t *)parent;
    myfilter_conf_t *conf = (myfilter_conf_t *)child;

    ngx_conf_merge_value(conf->enable, prev->enable, 0);
    return NGX_CONF_OK;
}

————————————– 分割线 ————————————–

Nginx 负载均衡配置实战  http://www.linuxidc.com/Linux/2014-12/110036.htm

CentOS 6.2 实战部署 Nginx+MySQL+PHP http://www.linuxidc.com/Linux/2013-09/90020.htm

使用 Nginx 搭建 WEB 服务器 http://www.linuxidc.com/Linux/2013-09/89768.htm

搭建基于 Linux6.3+Nginx1.2+PHP5+MySQL5.5 的 Web 服务器全过程 http://www.linuxidc.com/Linux/2013-09/89692.htm

CentOS 6.3 下 Nginx 性能调优 http://www.linuxidc.com/Linux/2013-09/89656.htm

CentOS 6.3 下配置 Nginx 加载 ngx_pagespeed 模块 http://www.linuxidc.com/Linux/2013-09/89657.htm

CentOS 6.4 安装配置 Nginx+Pcre+php-fpm http://www.linuxidc.com/Linux/2013-08/88984.htm

Nginx 安装配置使用详细笔记 http://www.linuxidc.com/Linux/2014-07/104499.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

————————————– 分割线 ————————————–

Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-09/135262.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计5384字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中