Nginx教程:实现一个简单的http模块

Nginx是由俄罗斯软件工程师Igor Sysoev开发的一个高性能的HTTP和反向代理服务器,具备IMAP/POP3和SMTP服务器功能。Nginx最大的特点是对高并发的支持和高效的负载均衡,在高并发的需求场景下,是Apache服务器不错的替代品。目前,包括新浪、腾讯等知名网站已经开始使用Nginx作为Web应用服务器,淘宝开发的tengine也是基于Nginx开发的。
 
Nginx的安装很简单,下载源码包解压,进入Nginx目录,执行以下命令

./configure

make

make install

在Linux中,需要使用命令行来控制Nginx的启动与停止、重新加载配置文件、回滚日志文件、平滑升级等操作。默认情况下Nginx被安装到/usr/local/nginx/中,可执行文件是/usr/local/nginx/sbin/nginx,配置文件是/urs/local/nginx/conf/nginx.conf,我安装的时候把ngnix安装在自己的nginx目录/home/yujian/nginx下。目录结构如下:

常见的命令有以下几个:

1、启动Nginx

./nginx

2、停止Nginx

./nginx -s stop(快速方式:发送SIGINT或是SIGTERM信号直接杀死进程)

./nginx -s quit(优雅方式:发送SIGQUIT信号,此时服务器会关闭监听端口,停止接受新的连接,然后把当前处理的连接全部处理完成,最后才退出进程)

3、重新读取配置文件

./ngnix -s reload

当重新加载配置文件时,Nginx会首先检查配置文件是否有语法错误,如果没有错误,就以“优雅的”方式关闭再重启Nginx。

Nginx的配置更为灵活,由配置块来组织配置项,并将配置块分为main,srv,loc等级别,便于配置文件的解析和管理,Nginx的配置文件时一个普通的文本,他的基本配置语法是

配置项名 值1 值2 ......(注意当当值中包含语法符号时,需要用当引号或双引号括起来)

以上就是Nginx安装和配置的一些基本知识,为了编写一个简单的http模块,需要了解Nginx是如何如何处理http的,以及他如何介入处理用户自己模块。

Nginx一般是通过master/worker方式工作的,master负责管理所有的worker,而所有的业务处理是有每一个worker完成的。worker会在自己的主循环里面反复调用时间检测模块来检测网络事件,当有连接请求时,worker负责建立连接,并根据配置交由http框架处理,http框架会试图接受完整的http头部,在接受完头部后,http框架将请求分发到具体的http模块中处理,自己编写的http模块就在此时交介入整个处理流程。

要编写Nginx的http模块,需要了解ngx_module_t、ngx_http_module_t、ngx_command_t等几个基本的数据结构,这里就不详述了,我会在代码中做出详细的解释,下面就开始我们的http模块之旅吧!

我们考虑最简单的情况,在loc块中配置自己的配置项mytest,当遇到mytest时,掉用自己的处理函数,响应用户请求。在Nginx的配置块中,模块处理请求的顺序是固定的,因为http框架定义了11中阶段,可以在每一个阶段中介入http框架,通常的http模块都是在HGX_HTTP_CONTENT_PHASE阶段介入的。我们接选择这种方式。

一、定义配置项的处理

假设我们在loc块中有如下的定义

location /test{ 
    mytest; 

我们需要定义一个ngx_command_t类型的数组,说明配置项的名称以及解析配置项的回调函数,定义如下:

//定义模块配置文件的处理 
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   
    },   
    //command数组要以ngx_null_command结束 
    //#define ngx_null_command {ngx_null_string,0,NULL,0,0,NULL} 
    ngx_null_command   
 };   

推荐阅读:

 

相关推荐