Nginx http filter异常排查
问题:
- 访问异常
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 filter异常排查的更多相关文章
- redis 异常排查
异常排查 redis-server redis.windows.conf D:\redis-2.8.17>redis-server.exe redis.windows.conf[4692] 27 ...
- Nginx range filter模块数字错误漏洞修复 (Nginx平滑升级) 【转】
对线上生产环境服务器进行漏洞扫描, 发现有两台前置机器存在Nginx range filter模块数字错误漏洞, 当使用nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header ...
- Nginx range filter模块数字错误漏洞修复 (Nginx平滑升级)
对线上生产环境服务器进行漏洞扫描, 发现有两台前置机器存在Nginx range filter模块数字错误漏洞, 当使用nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header ...
- 一次django内存异常排查
起因 Django 作为 Python著名的Web框架,相信很多人都在用,自己工作中也有项目项目在用,而在最近几天的使用中发现,部署Django程序的服务器出现了内存问题,现象就是运行一段时间之后,内 ...
- #研发解决方案#基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案
郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...
- 【转】数据库系统异常排查之DMV
数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排查的方法和步骤,此文为为大家介绍一下通过系统 性能视图(SQLServer05以上版本)来排查系统异常的基本方法 ...
- The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. 异常
异常信息如下: The Struts dispatcher cannot be found. This is usually caused by using Struts tags without t ...
- 基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案 郑昀 基于杨海波的设计文档(转)
郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...
- CPU负载过高异常排查实践与总结
昨天下午突然收到运维邮件报警,显示数据平台服务器cpu利用率达到了98.94%,而且最近一段时间一直持续在70%以上,看起来像是硬件资源到瓶颈需要扩容了,但仔细思考就会发现咱们的业务系统并不是一个高并 ...
随机推荐
- JavaScript的Math对象
原文 简书原文:https://www.jianshu.com/p/8776ec9cfb58 大纲 前言 1.Math对象的值属性 2.Math对象的函数属性 3.Math对象的函数的使用 前言 Ma ...
- (三)RabbitMQ消息队列-Centos7下安装RabbitMQ3.6.1
原文:(三)RabbitMQ消息队列-Centos7下安装RabbitMQ3.6.1 如果你看过前两章对RabbitMQ已经有了一定了解,现在已经摩拳擦掌,来吧动手吧! 用什么系统 本文使用的是Cen ...
- SpringBoot 使用 @Value 从 YAML文件读取属性(转)
在 YAML中有如下配置 paypal: mode:live 在类中,通过 @Value属性读取 @Value("${paypal.mode}") private String m ...
- 远程登录DSM,显示“您没有权限使用本项服务?
远程登录DSM,显示“您没有权限使用本项服务?” https://www.chiphell.com/thread-825297-1-1.html 有可能你单位用的是多wan接入.一般synology不 ...
- Windows Phone 8.1 后台任务
Windows Phone 8.1 应用可以添加多个后台任务,以辅助应用完成某些任务. (1)新建前台应用 后台任务是依托于前台应用的,所以必须拥有一个前台应用. 该前台应用的功能很简单,就是读取文件 ...
- ajax传递list集合
原文链接:https://blog.csdn.net/qq_37936542/article/details/79277495 一:ajax传递List<String>类型的数据 js代码 ...
- [Vue] Dynamic Vue.js Components with the component element
You can dynamically switch between components in a template by using the reserved <component> ...
- [Angular Form] ngModel and ngModelChange
When using Radio button for Tamplate driven form, we want to change to the value change and preform ...
- 如何在一个div中使其子div居中
网上其他地方已讲述过对其的不同实现方式,今天主要做一个详细的汇总,希望对大家有帮助. ps:我面试的时候就被问到过这个问题,当时都回答错了,蓝瘦. 假设父div的类名为father,子div的类名为s ...
- Git远程操作具体解释
Git是眼下最流行的版本号管理系统,学会Git差点儿成了开发人员的必备技能. Git有非常多优势,当中之中的一个就是远程操作非常简便.本文具体介绍5个Git命令,它们的概念和使用方法,理解了这些内容. ...