nginx自定义模块编写-实时统计模块
不是第一次写nginx的自定义模块了,之前有写过根据POST数据转发请求的模块(参见nginx自定义模块编写-根据post参数路由到不同服务器),不过上次写的是处理模块,而这次写的是过滤模块,还是有一些区别的。
在正式开始前,先说一下写nginx自定义模块要注意的几个点:
OK,废话不多说,开始正式说我这次写的统计模块吧
需求背景呢,就是现在已经在nginx后面挂了很多服务器,需要用nginx来统计成功率,响应时间等等参数,在网上翻了半天,大部分居然是用access_log,然后用程序扫描$request_time来实现的,这对一个每秒几千次访问的服务器是不可忍受的,所以最终没办法,那就自己写一个呗~
重新看了nginx自定义模块的开发文档,整个调用过程如下:
但是实在是没找到请求整个结束时的回调函数,最接近的也就是用filter模块了(即过滤模块),当然这样统计出来的请求时间,可能会比实际时间短一些。
OK,定了要写那种模块后,我们来考虑一下具体的实现
UDP上报client这里,因为是用的公司的库,而且又很简单,这里就不细说了,大家看代码也会看到,我在里面用的是static变量来保证不析构:
1 |
static COpenApiMonitorClient client; |
参数配置这里,因为上报库的要求,需要ip,port,来源,所以配置代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
typedef struct { ngx_str_t host; ngx_int_t port; ngx_str_t collect_point; } ngx_http_stat_report_conf_t; static ngx_command_t ngx_http_stat_report_filter_commands[] = { { ngx_string("stat_report_host"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_stat_report_conf_t, host), NULL }, { ngx_string("stat_report_port"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_stat_report_conf_t, port), NULL }, { ngx_string("stat_report_collect_point"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_stat_report_conf_t, collect_point), NULL }, ngx_null_command }; |
对于是选择ngx_http_output_header_filter_pt还是ngx_http_output_body_filter_pt这里,我最终选择了ngx_http_output_header_filter_pt,虽然说计算请求时间上会有差别,但是因为ngx_http_output_body_filter_pt会进入多次,写起来更复杂些,所以就走简单的了~
代码如下:
1 2 3 4 5 6 7 8 9 10 11 |
static ngx_int_t ngx_http_stat_report_header_filter(ngx_http_request_t *r) { ngx_http_stat_report_conf_t *conf; conf = (ngx_http_stat_report_conf_t *)ngx_http_get_module_loc_conf(r, ngx_http_stat_report_filter_module); SendStatReport(r, conf); return ngx_http_next_header_filter(r); } |
对于上报字段这里,主要是ngx_http_request_t每个字段的意义搞了我很久时间,这里也不多解释了,直接贴代码,大家应该能直接看懂了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
ngx_http_request_body_t* rb = r->request_body; char* body = NULL; int body_size = 0; if (rb && rb->buf) { body = (char*)rb->buf->pos; body_size = rb->buf->last - rb->buf->pos; } string str_uri = r->uri.data ? string((char*)r->uri.data,r->uri.len) : ""; string protocol = r->http_protocol.data ? string((char*)r->http_protocol.data, r->http_protocol.len) : ""; string str_data; map |
OK,整个代码基本就是这样了
惯例,下面又发现的新问题,纠结了我好久,现在还是没解决
最后,代码已经上传的googlecode
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Dante 来源: Vimer
- 标签: 实时统计 自定义模块
- 发布时间:2012-05-10 23:55:58
- [2289] 代理的加密部分
- [1072] 创业笔记 | 从0到1开公司是什么体验
- [397] vimgtd-在vim(gvim)中实现GT
- [326] 查找第K小的元素
- [62] Oracle MTS模式下 进程地址与会话信
- [61] 【社会化设计】自我(self)部分――欢迎区
- [60] Go Reflect 性能
- [58] 图书馆的世界纪录
- [56] android 开发入门
- [56] 如何拿下简短的域名