上一篇(/os/201511/449771.html)已經介紹了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
#include
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
};