nginx模块开发
因为一些需要,我也开始涉及nginx的模块开发,在看了一些资料后,写了自己第一个nginx模块。
其实nginx模块开发还算比较容易,网上开源的模块已经很多,都可以借鉴,令我震惊的是OAuth的模块都有。
nginx模块比较起来一些后端语言的实现,最重要的特点就是速度快了,这个无可厚非,nginx模块与apache的区别就是,apache是加载so模块,而nginx是直接将模块编译到主程序里。在我的简单测试下,一个业务逻辑非常简单的模块,可以达到1-2w/s的请求,如果你的机器够好,这个数据更加可观。对于一个PHP来说,能压到5000/s就非常不错了。
个人觉得nginx现在模块开发资料还比较少(貌似跟上面说的有些矛盾= =),开发起来还是磕磕绊绊的,所以如果大家想尝试一些nginx模块开发,并且运用到生产环境,推荐一些业务逻辑比较简单的时候再考虑。
nginx模块开发还有个优点就是部署起来非常容易,编译也非常简单。
好了 废话就不说了,下面给出一个hello world的demo。网上已经有了很多hello world的例子了 在我看来 还是很复杂。我还是自己来说一遍吧。
在开发模块之前,我们需要新建一个名为“config”的文件,在nginx编译的时候,来告知主程序把我这个模块也编译了。
在这个hello world的例子中,config类似于下面这个样子的:
1 2 3 |
ngx_addon_name=ngx_hello_world_module HTTP_AUX_FILTER_MODULES="$HTTP_MODULES ngx_hello_world_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_hello_world_module.c" |
需要注意的就是模块的名字跟你模块源码的位置
然后在你的这个目录下 新建ngx_hello_world_module.c
然后输入以下代码
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
#include <ngx_core.h> #include <ngx_http.h> #include <nginx.h> static char *ngx_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_hello_world_get_output(ngx_http_request_t *r, char *out_buf); static ngx_int_t ngx_hello_world_handler(ngx_http_request_t *r); /* Commands */ static ngx_command_t ngx_hello_world_commands[] = { { ngx_string("ngx_hello_world"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_hello_world, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command }; static ngx_http_module_t ngx_hello_world_module_ctx = { NULL, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; /* hook */ ngx_module_t ngx_hello_world_module = { NGX_MODULE_V1, &ngx_hello_world_module_ctx, /* module context */ ngx_hello_world_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; static ngx_int_t ngx_hello_world_get_output(ngx_http_request_t *r, char *out_buf){ sprintf(out_buf, "%s", "Hello World!"); return NGX_OK; } static ngx_int_t ngx_hello_world_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; /* Http Output Buffer */ char out_buf[20] = {0}; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK && rc != NGX_AGAIN) { return rc; } //定制头信息 r->headers_out.content_type.len = sizeof("text/html") - 1; r->headers_out.content_type.data = (u_char *) "text/html"; if (r->method == NGX_HTTP_HEAD) { rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } } //获取输出的body ngx_hello_world_get_output(r, out_buf); b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } out.buf = b; out.next = NULL; b->pos = (u_char *)out_buf; b->last = (u_char *)out_buf + strlen(out_buf); b->memory = 1; b->last_buf = 1; r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = strlen(out_buf); rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } return ngx_http_output_filter(r, &out); } static char * ngx_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); /* register hanlder */ clcf->handler = ngx_hello_world_handler; return NGX_CONF_OK; } |
然后编译。
编译需要弄明白的就是,我们不用编译我们的模块,我们只需要在编译nginx的时候 加上-add-module的参数就可以了。
另外,nginx的rewrite是需要用到pcre库的,所以编译nginx前,请先编译安装好pcre。
然后到nginx的目录下,进行configure
以下是代码片段: ./configure --prefix=/home/www/nginx --user=www --group=www --add-module=/home/www/download/ngx_hello_world --with-cc-opt="-I /home/www/pcre/include" --with-ld-opt="-L /home/www/pcre/lib" |
编译完成后,我们的模块就和nginx主程序“合体”了。
这时候我们进入nginx.conf 在你的server块中 加入以下信息:
1 2 3 |
location /hello { ngx_hello_world; } |
然后启动nginx, 这时候打开你的server/hello 就可以看到输出hello world的信息了。如果你感兴趣,可以用PHP来写个Hello World,然后来压一下比较一下性能:)
下面是本模块打包下载:
建议继续学习:
- 配置Nginx+uwsgi更方便地部署python应用 (阅读:105405)
- 搜狐闪电邮箱的 Nginx/Postfix 使用模式 (阅读:32530)
- 解析nginx负载均衡 (阅读:14521)
- 在Apache2.2.XX下安装Mod-myvhost模块 (阅读:11715)
- Nginx模块开发入门 (阅读:9882)
- 检查nginx配置,重载配置以及重启的方法 (阅读:9104)
- Cacti 添加 Nginx 监控 (阅读:8923)
- Nginx+FastCgi+Php 的工作机制 (阅读:8859)
- nginx的配置文件 (阅读:8834)
- 奇怪的 Nginx 的 upstream timed out 引起响应 502 (阅读:8159)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Jessica 来源: Skiyo
- 标签: nginx 模块
- 发布时间:2010-12-21 01:52:06
- [44] 如何拿下简短的域名
- [44] IOS安全–浅谈关于IOS加固的几种方法
- [43] Oracle MTS模式下 进程地址与会话信
- [43] 图书馆的世界纪录
- [41] 界面设计速成
- [41] android 开发入门
- [40] 【社会化设计】自我(self)部分――欢迎区
- [38] 读书笔记-壹百度:百度十年千倍的29条法则
- [37] 视觉调整-设计师 vs. 逻辑
- [34] 程序员技术练级攻略