首页 > 代码库 > nginx(一)

nginx(一)

crul新浪微博的时候发现对面用的是nginx服务器,在虎扑足球(挺好的足球论坛)讨论世界杯也发现他们也用这nginx,联想到阿里的tengine也是基于nginx的,觉得有了解一下nginx的必要了。

1.  nginx安装

  nginx安装跟普通开源软件安装相似(都使用makefile),具体流程:下载源文件,./configure,make,make install。

  在./configure过程中,会出现一些找不到一些依赖组件的提示,自行安装即可。可以通过源码编译方式安装对应组件。也可以通过系统自带的安装方式进行,比如在使用fedora安装相关openssl组件时,

  sudo yum install openssl-devel  这里会添加相应的编程关联文件,如果仅仅是sudo yum install openssl  就可能出现错误。

  ./configure过程中存在一些比较实用的参数,如

  ./configure --prefix=/../.. --with-http_ssl_module --with-openssl=/../.. --add-module=/home/..

  这些参数不加的话也会设置相应的默认值。

2.  程序

  nginx_http_mytest_module.c

#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r);static char * ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static ngx_command_t ngx_http_mytest_commands[] = {    {        ngx_string("mytest"),        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,        ngx_http_mytest,        NGX_HTTP_LOC_CONF_OFFSET,        0,        NULL    },    ngx_null_command};static ngx_http_module_t ngx_http_mytest_module_ctx = {    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL};ngx_module_t ngx_http_mytest_module = {    NGX_MODULE_V1,    &ngx_http_mytest_module_ctx,    ngx_http_mytest_commands,    NGX_HTTP_MODULE,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NGX_MODULE_V1_PADDING};static char * ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_http_core_loc_conf_t *clcf;    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);    clcf->handler = ngx_http_mytest_handler;    return NGX_CONF_OK;}static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r){    if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) {        return NGX_HTTP_NOT_ALLOWED;    }    ngx_int_t rc = ngx_http_discard_request_body(r);    if (rc != NGX_OK) {        return rc;    }    ngx_str_t type = ngx_string("text/plain");    ngx_str_t response = ngx_string("miao miao");    r->headers_out.status = NGX_HTTP_OK;    r->headers_out.content_length_n = response.len;    r->headers_out.content_type = type;    rc = ngx_http_send_header(r);    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {        return rc;    }    ngx_buf_t *b;    b = ngx_create_temp_buf(r->pool, response.len);    if (b == NULL) {        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    ngx_memcpy(b->pos, response.data, response.len);    b->last = b->pos + response.len;    b->last_buf = 1;    ngx_chain_t out;    out.buf = b;    out.next = NULL;    return ngx_http_output_filter(r, &out);}

  a.  ngx_command_t

  定义服务器配置文件(安装目录/conf/nginx.conf)对应的配置项,并定义了配置项对应的回调函数,在此为ngx_http_mytest。

  b.  ngx_http_module_t 

  模块上下文,每个null分别对应着一个函数指针

 ngx_http_module_t ngx_http_mytest_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 */};

  c.  ngx_module_t 

  对于开发一个模块来说,需要定义一个ngx_module_t类型的变量来说明这个模块本身的信息,从某种意义上来说,这是这个模块最重要的一个信息,它告诉了nginx这个模块的一些信息,上面定义的配置信息,还  有模块上下文信息,都是通过这个结构来告诉nginx系统的,也就是加载模块的上层代码,都需要通过定义的这个结构,来获取这些信息。

ngx_module_t ngx_http_mytest_module = {  NGX_MODULE_V1,    /*  #define NGX_MODULE_V1    0, 0, 0, 0,NGX_DSO_ABI_COMPATIBILITY, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR    */  &ngx_http_mytest_module_ctx,  /* module context */  ngx_http_mytest_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 /*    #define NGX_MODULE_V1_PADDING  0, 0, 0, 0, 0, 0, 0, 0    */};

3.  编译安装新模块

  Nginx提供了一种简单的方式将第三方的模块编译到Nginx中。首先把源代码文件全部放到一个目录下,同时在该目录中编写一个文件用于通知Nginx如何编译本模块,这个文件名必须为config。然后,在configure脚本执行时加入参数--add-module=PATH(新模块源代码以及config文件存放目录),就可以在执行政策编译安装流程时完成Nginx编译工作。Nginx添加新模块要求整个服务器重新编译应该是为了性能的需求。

  config文件格式
  config文件其实是一个可执行的Shell脚本,如果只想开发一个HTTP模块,需要定义三个变量:
  (1)ngx_adon_name。
  仅在configure执行时使用,一般设置为模块名称。
  (2)HTTP_MODULES。
  保存所有的HTTP模块名称。每个模块间由空格相连。在重新设置这个变量时,不要直接覆盖,因此要如下设置:
  "$HTTP_MODULES ngx_http_mytest_module"
  (3)NGX_ADDON_SRCS。
  用于指定新模块的源代码,多个待编译的源代码之间可以用空格相连。
  注意,在设置这个变量时可以使用$ngx_addon_dir变量,它等价于configure执行时--add-module=PATH的PATH参数。

ngx_addon_name=ngx_http_mytest_module
HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"

  编译安装新模块的命令如下:

./configure --prefix=/usr/local/nginx(指定安装部署后的根目录) --add-module=/home/nginx(新模块存放目录)makesudo make install

4.  推荐内容

Nginx开发从入门到精通  http://tengine.taobao.org/book/index.html