技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> Apache --> nginx模块开发

nginx模块开发

浏览:4612次  出处信息

因为一些需要,我也开始涉及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"
-add-module后面就是我们模块的目录地址 此目录中包含刚才写的config文件, 后面的两个是指定pcre的目录,如果你configure的pcre的时候没有指定安装目录,则可以去掉这两个参数。

编译完成后,我们的模块就和nginx主程序“合体”了。

这时候我们进入nginx.conf 在你的server块中 加入以下信息:

 
1
2
3
location /hello {
	ngx_hello_world;
}

然后启动nginx, 这时候打开你的server/hello 就可以看到输出hello world的信息了。如果你感兴趣,可以用PHP来写个Hello World,然后来压一下比较一下性能:)

下面是本模块打包下载:

ngx_hello_world

建议继续学习:

  1. 配置Nginx+uwsgi更方便地部署python应用    (阅读:105397)
  2. 搜狐闪电邮箱的 Nginx/Postfix 使用模式    (阅读:32523)
  3. 解析nginx负载均衡    (阅读:14505)
  4. 在Apache2.2.XX下安装Mod-myvhost模块    (阅读:11703)
  5. Nginx模块开发入门    (阅读:9870)
  6. 检查nginx配置,重载配置以及重启的方法    (阅读:9093)
  7. Cacti 添加 Nginx 监控    (阅读:8916)
  8. Nginx+FastCgi+Php 的工作机制    (阅读:8848)
  9. nginx的配置文件    (阅读:8821)
  10. 奇怪的 Nginx 的 upstream timed out 引起响应 502    (阅读:8139)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1