上一篇(http://blog.csdn.net/xlgen157387/article/details/49781487)已经介绍了Nginx的基本功能,也介绍了在Windows下的安装和简单的实现负载均衡,下边主要学习一下Nginx的源码结构。
环境:nginx-1.8.0+CentOS7.0
(可以使用yum install tree
来安装tree命令,就可以显示出文件的树结构)
[root@iZ94sni08orZ nginx-1.8.0]# tree src/
src/
├── core
│ ├── nginx.c
│ ├── nginx.h
│ ├── ngx_array.c
│ ├── ngx_array.h
│ ├── ngx_buf.c
│ ├── ngx_buf.h
│ ├── ngx_conf_file.c
│ ├── ngx_conf_file.h
│ ├── ngx_config.h
│ ├── ngx_connection.c
│ ├── ngx_connection.h
│ ├── ngx_core.h
│ ├── (省略部分)
│ ├── ngx_times.c
│ └── ngx_times.h
├── event
│ ├── modules
│ │ ├── ngx_aio_module.c
│ │ ├── ngx_devpoll_module.c
│ │ ├── ngx_epoll_module.c
│ │ ├── ngx_eventport_module.c
│ │ ├── ngx_kqueue_module.c
│ │ ├── ngx_poll_module.c
│ │ ├── ngx_rtsig_module.c
│ │ ├── ngx_select_module.c
│ │ └── ngx_win32_select_module.c
│ ├── ngx_event_accept.c
│ ├── ngx_event.c
│ ├── ngx_event_connect.c
│ ├── ngx_event_connect.h
│ ├── (省略部分)
│ └── ngx_event_timer.h
├── http
│ ├── modules
│ │ ├── ngx_http_access_module.c
│ │ ├── ngx_http_addition_filter_module.c
│ │ ├── ngx_http_auth_basic_module.c
│ │ ├── ngx_http_auth_request_module.c
│ │ ├── ngx_http_autoindex_module.c
│ │ ├── ngx_http_browser_module.c
│ │ ├── ngx_http_charset_filter_module.c
│ │ ├── ngx_http_chunked_filter_module.c
│ ├── (省略部分)
│ │ ├── ngx_http_uwsgi_module.c
│ │ ├── ngx_http_xslt_filter_module.c
│ │ └── perl
│ │ ├── Makefile.PL
│ │ ├── nginx.pm
│ │ ├── nginx.xs
│ │ ├── ngx_http_perl_module.c
│ │ ├── ngx_http_perl_module.h
│ │ └── typemap
│ ├── ngx_http.c
│ ├── ngx_http_cache.h
│ ├── ngx_http_config.h
│ ├── ngx_http_header_filter_module.c
│ ├── (省略部分)
│ ├── ngx_http_variables.h
│ └── ngx_http_write_filter_module.c
├── mail
│ ├── ngx_mail_auth_http_module.c
│ ├── ngx_mail.c
│ ├── (省略部分)
│ ├── ngx_mail_ssl_module.c
│ └── ngx_mail_ssl_module.h
├── misc
│ ├── ngx_cpp_test_module.cpp
│ └── ngx_google_perftools_module.c
└── os
└── unix
├── ngx_aio_read.c
├── ngx_aio_read_chain.c
├── ngx_aio_write.c
├── (省略部分)
├── ngx_udp_recv.c
├── ngx_user.c
├── ngx_user.h
└── ngx_writev_chain.c
10 directories, 265 files
[root@iZ94sni08orZ nginx-1.8.0]#
从上边的源码中可以看出共有10 directories, 265 files,Nginx的主要模块是Core、event、http、mail、misc(杂项,包含多种功能)、os这几个部分,并且根据源代码的命名也可以大致的猜测出其所代表的功能。
建议大家下载其源码,大致看一下,这样的话,也能够更好的理清楚Nginx的功能组成。
举个简单的例子,Core模块下的第一个文件nginx.c的一部分代码如下:
static ngx_command_t ngx_core_commands[] = {
{ ngx_string("daemon"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, daemon),
NULL },
{ ngx_string("master_process"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, master),
NULL },
。。。
从上述可以看出,ngx_core_commands[]这一个数组定义了Core模块下所使用的全部设置命令(这也是后边学习Core模块的时候需要介绍的)。
并且还有event–modules下边明确的列出了几种事件的模型,也是后边在学习该模块的时候需要学习的地方。
由于对shell脚本语言和C掌握的程度有限,不对源码做过多的解释。
如果使用的CentOS的话需要先下载一些基础软件,可以使用命令进行下载:
1、为了支持rewrite功能,我们需要安装pcre
# yum install pcre* //如过你已经装了,请跳过这一步
2.安装openssl
需要ssl的支持,如果不需要ssl支持,请跳过这一步
# yum install openssl*
3.gzip 类库安装
yum install zlib zlib-devel
(注:如果是Ubuntu的话,直接使用命令sudo apt-get install nginx
进行下载即可)
4、准备好源码,进行解压tar -zxvf nginx-1.8.0.tar.gz
5、编译和安装,执行如下命令:
# cd nginx-1.8.0
# ./configure --prefix=/usr/local/nginx-1.7.0 \
--with-http_ssl_module --with-http_spdy_module \
--with-http_stub_status_module --with-pcre
–with-http_stub_status_module:支持nginx状态查询
–with-http_ssl_module:支持https
–with-http_spdy_module:支持google的spdy,想了解请百度spdy,这个必须有ssl的支持
–with-pcre:为了支持rewrite重写功能,必须制定pcre
(如果这里有提示还需要安装其他的包,安装即可)
设置之后,执行make
结束之后执行 make install
启动命令在/usr/local/nginx-1.8.0/sbin文件下
启动:./nginx
关闭:./nginx -s stop
重启:./nginx -s reload
(如果在Ubuntu的话,可能是在/usr/sbin目录下)
/usr/local/nginx-1.8.0目录下:这是编译之后生成的配置等文件
[root@iZ94sni08orZ nginx-1.8.0]# tree
.
├── client_body_temp
├── conf
│ ├── fastcgi.conf
│ ├── fastcgi.conf.default
│ ├── fastcgi_params
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf
│ ├── nginx.conf.default
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp
├── html
│ ├── 50x.html
│ └── index.html
├── logs
│ ├── access.log
│ └── error.log
├── proxy_temp
├── sbin
│ └── nginx
├── scgi_temp
└── uwsgi_temp
9 directories, 20 files
[root@iZ94sni08orZ nginx-1.8.0]#
在conf目录下有几个配置文件,该配置文件用于控制Nginx服务器的基本功能,其中nginx.conf为:
#user nobody; #运行的用户
worker_processes 1; #允许work线程的数目
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024; #每个work子进程允许最大的连接数为1024
}
http {
include mime.types; #用于载入配置文件
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
从上边的内容中可以看出,每一个配置属性的意思大致可以看出来,这一点会在后边的分模块学习时详细说明。
同样的在编译之后,会在原来的Nginx代码包中生成一个objs的目录,其中,生成的ngx_modules.c文件中,重新集中申明(使用extern关键字)了nginx配置的所有模块,这些模块可通过编译前的configure命令进行配置,即设置哪些模块需要编译,哪些不被编译。
如下。包含了执行编译过程中的内容:
#include <ngx_config.h>
#include <ngx_core.h>
extern ngx_module_t ngx_core_module;
extern ngx_module_t ngx_errlog_module;
extern ngx_module_t ngx_conf_module;
extern ngx_module_t ngx_events_module;
...(省略部分)
extern ngx_module_t ngx_http_upstream_hash_module;
extern ngx_module_t ngx_http_upstream_ip_hash_module;
ngx_module_t *ngx_modules[] = {
&ngx_core_module,
&ngx_errlog_module,
&ngx_conf_module,
&ngx_events_module,
&ngx_event_core_module,
&ngx_epoll_module,
&ngx_openssl_module,
&ngx_regex_module,
&ngx_http_module,
&ngx_http_core_module,
...(省略部分)
&ngx_http_range_body_filter_module,
&ngx_http_not_modified_filter_module,
NULL
};
这些模块均是在此处用extern进行申明,以表明其他模块可以访问,而对其本身的定义和初始化ngx_module_t结构在其对应的.c文件中进行。例如,ngx_core_module模块便是在./src/core/nginx.c文件中定义并进行静态初始化。实际上,ngx_core_module是一个全局的结构体对象,其他模块类同。如下。
ngx_module_t ngx_core_module = {
NGX_MODULE_V1,
&ngx_core_module_ctx, /* module context */
ngx_core_commands, /* module directives */
NGX_CORE_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
};