现在的位置: 首页 > 综合 > 正文

Nginx详细讲解

2013年08月03日 ⁄ 综合 ⁄ 共 40817字 ⁄ 字号 评论关闭

 

nginx文档
吴东
April 28, 2009

Contents
1前言 5
2基本配置 7
2.1安装………………… 7
2.2配置说明………………. 10
2.3启动和控制……………… 25
3深入源码 27
3.1源码结构………………. 27
3.2configure配置 ……………. 27
3.3nginx源码习惯 ……………. 27
3.4常用基础库……………… 28

3.5core模块………………. 40

3.6event模块 ……………… 44

3.7http模块………………. 46

4模块编写 55
4.1http模块编写…………….. 55

4.2基于nginx的高性能服务器开发 . . . . . . . . . 55
5附录 57
5.1编译器参数……………… 57

5.2系统函数………………. 59

CONTENTS CONTENTS
Chapter 1

前言
在互联网编程中,http服务器编程作为一个非常重要方向一直为各种语言所重视,从c语言的apache,Lighttpd到当前非常流行的nginx。 Java有tom-cat,jetty,websphere等众多服务器,pyhoen的zope等服务器。既有重量级的服务器,又有轻量级的,嵌入式的服务器。从互联网的应用来说,c语言的http服务器一直占有主导地位,当前最流行的三个开源服务器有apache,Lighttpd和nginx。 Apache作为经典的Web服务器,除了慢没有别的缺点了,Apache2对fcgi支持并不好,非常好用的proxy和proxy_ajp(很多人用它作为tomcat的前端),不支持epoll(这年头,epoll几乎是性能的必备)。Lighttpd作为杀手级的静态文件能力,杀手级的fcgi能力但是proxy模块不够稳定。Nginx速度快,占用资源少,杀手级的proxy和rewrite,非常不错的静态文件能力,最适合作为整个网站的前端服务(将php、svn等不同请求发送往后端apache)。现在国内Nginx的用户越来越多了,多数拥抱Nginx的网站都钟意其优异的性能表现,如果是相对比较大的网站,节约下来的服务器成本无疑是客观的。当前
Ngnix美中不足之处是相关的文档和用户经验都还是很欠缺,用户之间还很难做到可借鉴性的交流。最近因为朋友遇到一些技术问题,我也翻阅了不少 Nginx的邮件列表内容,发现大量的技术细节仍然在频繁变化中,可是中文社区内相关的记录和讨论太少了。相信国内这些Nginx用户积攒的经验肯定是不少的,但可能是因为某些其它因素考虑而看不到相关的技术分享。本书的写作就是为了向大家展示nginx的内部结构,以便于大家更好的使用该服务器。对于一个八万行代码的http服务器,从性能来看它是那么的出色,从功能来看它并不逊色于几十万行的apache服务器。Nginx是实现有几个非常出色的地方:模块化设计,流水线请求处理,多进程控制,epoll的使用,平滑的升级程序或是配置文件。Nginx采用的是单线程的方式,网络服务器的几种模型可以参考C10K的介绍。当然,如果在linux下,最好的模型自然是EPool(effectiveepoll?)。目前一台服务器支持10K个客户访问,基本上还比较麻烦,64位的CPU,可能是一个比较好的解决方案。2块1000M网卡,10K客户端,每个客户端的带宽是
2000/10000=200K,这是理论值,勉强可行。考虑一下纯粹的线程模型。10K个客户端,需要10K个线程。考虑到每个进程3G的用户空间,那么每个线程的空间是3000M/10K=300K,只能说非常勉强可以运行(每个线程的cruntime大约需要2-3K空间)。但是大量的线程调度会极大的减缓系统效率。再考虑一下多个进程的模型,每个进程创建多个线程。其实与纯粹的线程模型差异不大,不过是每个线程的用户空间不受太大限制。大量的线程调度带来的巨大性能损耗会使得整个系统效率及其低下。当然,这种模型也不是一无是处,对于客户端数目不多的情况,比如ftp服务器,这种模型是非常合适的。然后就剩下epoll模
Chapter1.前言
型。要使用epoll模型,首先必须有Linux2.6的内核。了解select模型的人都知道,select每个句柄只能支持64个socket,这可以通过阅读linuxselect.h知道。而Poll模型则是一种事件触发的模型,没有64个socket的限制。epoll是对Poll模型的一个改造,让一个Poll句柄可以同时支持多个Socket句柄,好处是将大量Poll句柄的事件探测机制放到内核中处理,大大减少了将数据从内核态拷贝到用户态的次数,从而提高效率。阅读Linux的源码可以看到,epoll的内部使用的是一个Hashmap,Hashmap中存放Poll对象,所以从根本上来说,epoll模型是一种更好的Poll模型(我一直理解为EffectivePoll)。
当然nginx也有不足的地方,例如各个模块之间的耦合性太强,各个模块不适合直接拿出来使用。Nginx的作者过于强调按照他自己所理解的模块化,而把一些基础模块也用作者所谓的模块化来实现,导致代码相互引用太多,艰涩难懂。
本书的编写的面向的用户除了初级linux工程师外,还可以为中高级linux工程师作为开发高性能服务器的工具书,目的除了向用户展示nginx精巧的设计和完整的实现外,还希望通过本书的讲解能够让用户以nginx作为基本框架或是自己实现更多的高性能服务器。
Chapter 2

基本配置
2.1安装
安装依赖模块
1.
gzip模块需要zlib库,该模块在http://www.zlib.net/网站下载。

2.
rewrite模块需要pcre库,该模块在http://www.pcre.org/网站下载。

3.
ssl功能需要openssl库该模块在http://www.openssl.org/网站下载。

官方源代码下载
在http://sysoev.ru/nginx/download.html网站上可以下载nginx源代码。
使用源代码安装
Nginx使用 Unix下常用的 ‘./configure && make && make install’过程来编译安装。configure脚本确定系统所具有一些特性,特别是nginx用来处理连接的方法。然后,它创建Makefile文件。configure支持下面的选项:
–prefix=
-Nginx安装路径。如果没有指定,默认为/usr/local/nginx。
–sbin-path=
-Nginx可执行文件安装路径。只能安装时指定,如果没有指定,默认为
/sbin/nginx。
–conf-path=
-在没有给定-c选项下默认的nginx.conf的路径。如果没有指定,默认为
/conf/nginx.conf。
–pid-path=
-在nginx.conf中没有指定pid指令的情况下,默认的nginx.pid的路径。如果没有指定,默认为
/logs/nginx.pid。
–lock-path=
-nginx.lock文件的路径。
–error-log-path=
-在nginx.conf中没有指定error_log指令的情
2.1.安装 Chapter2.基本配置
况下,默认的错误日志的路径。如果没有指定,默认为
/logs/er-ror.log。
–http-log-path=
-在nginx.conf中没有指定access_log指令的情况下,默认的访问日志的路径。如果没有指定,默认为
/logs/ac-cess.log。
–user=-在nginx.conf中没有指定user指令的情况下,默认的nginx使用的用户。如果没有指定,默认为nobody。 –group=-在nginx.conf中没有指定user指令的情况下,默认的nginx使用的组。如果没有指定,默认为nobody。 –builddir=DIR-指定编译的目录–with-rtsig_module-启用 rtsig模块
–with-select_module–without-select_module-允许或不允许开启SE-LECT模式,如果configure没有找到更合适的模式,比如:kqueue(sun os),epoll (linux kenel2.6+), rtsig(实时信号)或者/dev/poll(一种类似select的模式,底层实现与SELECT基本相同,都是采用轮训方法) SELECT模式将是默认安装模式
–with-poll_module –without-poll_module -允许或不允许开启pool模式.–with-http_ssl_module-开启HTTPSSL模块,使NGINX可以支持HTTPS请求。这个模块需要已经安装了OPENSSL,在DEBIAN上是libssl–with-http_realip_module-启用 ngx_http_realip_module。–with-http_addition_module-启用 ngx_http_addition_module–with-http_sub_module-启用ngx_http_sub_module–
with-http_dav_module-启用 ngx_http_dav_module–with-http_flv_module-启用 ngx_http_flv_module –with-http_stub_status_module -启用 “server status”页 –without-http_charset_module -禁用 ngx_http_charset_module –without-http_gzip_module -禁用 ngx_http_gzip_module.如果启用,需要zlib。
–without-http_ssi_module -禁用 ngx_http_ssi_module–without-http_userid_module-禁用ngx_http_userid_module– without-http_access_module-禁用ngx_http_access_module–without- http_auth_basic_module-禁用ngx_http_auth_basic_module–without- http_autoindex_module-禁用ngx_http_autoindex_module–without-
http_geo_module-禁用ngx_http_geo_module–without-http_map_module-禁用 ngx_http_map_module–without-http_referer_module-禁用 ngx_http_referer_module–without-http_rewrite_module-禁用 ngx_http_rewrite_module.如果启用需要 PCRE。–without-http_proxy_module-禁用ngx_http_proxy_module
Chapter2.基本配置 2.1.安装
–without-http_fastcgi_module-禁用ngx_http_fastcgi_module–without- http_memcached_module-禁用ngx_http_memcached_module–without- http_limit_zone_module-禁用ngx_http_limit_zone_module–without- http_empty_gif_module-禁用ngx_http_empty_gif_module–without- http_browser_module-禁用
ngx_http_browser_module–without-http_upstream_ip_hash_module-禁用 ngx_http_upstream_ip_hash_module–with-http_perl_module-启用 ngx_http_perl_module –with-perl_modules_path=PATH-指定 perl模块的路径 –with-perl=PATH
-指定 perl执行文件的路径 –http-log-path=PATH -Set path to the http access log –http-client-body-temp-path=PATH -Set path to the http client
request body temporary files –http-proxy-temp-path=PATH -Set path to the http proxy temporary files –http-fastcgi-temp-path=PATH -Set path to the http fastcgi tem-
porary files –without-http -禁用 HTTP server –with-mail -启用 IMAP4/POP3/SMTP代理模块 –with-mail_ssl_module -启用 ngx_mail_ssl_module –with-cc=PATH -指定 C编译器的路径 –with-cpp=PATH -指定 C预
处理器的路径 –with-cc-opt=OPTIONS -Additional parameters which will be added to the variable CFLAGS. With the use of the system library PCRE in FreeBSD, it is necessary to indicate –with-cc-opt=”-I /usr/local/include”. If we are using select() and it is necessary
to increase the number of file descriptors, then
this also can be assigned here: –with-cc-opt=”-D FD_SETSIZE=2048″. –with-ld-opt=OPTIONS -Additional parameters passed to the linker.
With the use of the system library PCRE in FreeBSD, it is necessary to indicate –with-ld-opt=”-L /usr/local/lib”.
–with-cpu-opt=CPU -为特定的 CPU编译,有效的值包括:pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64
–without-pcre -禁止 PCRE库的使用。同时也会禁止 HTTP rewrite模块。在 “location”配置指令中的正则表达式也需要 PCRE。 –with-pcre=DIR -指定 PCRE库的源代码的路径。 –with-pcre-opt=OPTIONS -Set additional options for PCRE building. –with-md5=DIR -Set path to md5 library sources.
2.2.配置说明 Chapter2.基本配置
–with-md5-opt=OPTIONS -Set additional options for md5 building.
–with-md5-asm -Use md5 assembler sources.
–with-sha1=DIR -Set path to sha1 library sources.
–with-sha1-opt=OPTIONS -Set additional options for sha1 building.
–with-sha1-asm -Use sha1 assembler sources.
–with-zlib=DIR -Set path to zlib library sources.
–with-zlib-opt=OPTIONS -Set additional options for zlib building.
–with-zlib-asm=CPU -Use zlib assembler sources optimized for

specified CPU, valid values are: pentium, pentiumpro –with-openssl=DIR -Set path to OpenSSL library sources –with-openssl-opt=OPTIONS -Set additional options for OpenSSL
building –with-debug -启用调试日志 –add-module=PATH -Add in a third-party module found in directory
PATH在不同版本间,选项可能会有些许变化,请总是使用 ./configure–help命令来检查一下当前的选项列表。示例(最好能在同一行):
1 ./ configure \
2 ..sbin.path =/ usr / local / nginx / nginx \
3 ..conf.path =/ usr / local / nginx / nginx . conf \
4 ..pid.path =/ usr / local / nginx / nginx . pid \
5 ..with.http_ssl_module \
6 ..with.pcre =../ pcre .4.4 \
7 ..with.zlib =../ zlib .1.1.3

Example on Ubuntu/debian with libgcrypt11-dev, libpcre3-dev and libssl-dev installed (choose EITHER –with-md5 OR –with-sha1, but not both; on debian and ubuntu, they should both point to /usr/lib)
1 ./ configure \
2 ..with.openssl =/ usr / lib / ssl / \
3 ..with.md5 =/ usr / lib

An Ubuntu Edgy .deb for version 0.5.2 can be found here: nginx_0.5.2-1_i386.deb. (NOTE: According to an October 2006 message md5 was used in a now broken http cache module and sha1 is used in an incomplete mysql library module and so are currently not needed.)

2.2配置说明
主模块
daemon
Chapter2.基本配置 2.2.配置说明
语法: daemon on | off
缺省值: on生产环境中不要使用”daemon”和”master_process”指令,这

些选项仅用于开发调试。
debug_points
语法: debug_points [stop | abort]
缺省值: nonedebug_points stop;应该适用于调试,在调试器内设置断
点之类的。
error_log
语法: error_log file [ debug | info | notice | warn | error | crit
]
缺省值: ${prefix}/logs/error.log Nginx添加 –with-debug编译参数,你还能够使用以下配置: error_log LOGFILE [ debug_core | debug_alloc
| debug_mutex | debug_event | debug_http | debug_imap];
include
语法:include file | *
缺省值: none你可以在任意地方使用include指令实现配置文件的包含,类似于apache中的include方法,可减少主配置文件d。 include指令还支持像下面配置一样的全局包含的方法,例如包含一个目录下所有以”.conf”结尾的文件:include vhosts/*.conf;注意路径受到configure编译参数–prefix=<路径>指令的影响,如果没有指定,Nginx默认是被编译在/usr/local/nginx。
lock_file
语法: lock_file file
缺省值: compile-time option lock_file /var/log/lock_file; nginx uses accept mutex to serialize accept() syscalls. If nginx is built by gcc, Intel C++, or SunPro C++ compilers on i386, amd64, sparc64, and ppc64, then nginx uses the atomic instructions to implement
the mutex. In other cases the lock file would be used.
master_process
语法: master_process on | off
缺省值:on master_process off;生产环境中不要使用”daemon”和”master_process”指
令,这些选项仅用于开发调试。
pid
语法: pid file
缺省值:compile-time option Example:pid /var/log/nginx.pid;进程
id存储文件。可以使用 kill -HUP cat/var/log/nginx.pid\对Nginx进行配置文件重新加载。
SSL_ENGINE
语法: ssl_engine engine
缺省值: system dependent该指令用于指定openssl使用的引擎。你可以通过下面的命令行获知系统目前支持的openssl引擎 openssl engine -t例如: $ openssl engine -t (cryptodev) BSD cryptodev engine [ available
2.2.配置说明 Chapter2.基本配置
] (dynamic) Dynamic engine loading support [ unavailable ]
timer_resolution
语法: timer_resolution t
缺省值: none Example: timer_resolution 100ms; The directive al-lows to decrease number gettimeofday() syscalls.By缺省值 gettime-ofday() is called after each return from kevent(), epoll, /dev/poll, select(), poll(). But if you need an exact time in logs when log-ging
$upstream_response_time, or $msec variables, then you should use timer_resolution.
USER
语法: user user [group]
缺省值:nobody nobody指定Nginx Worker进程运行用户,默认是nobody帐号。例如: user www users;
worker_cpu_affinity
语法: worker_cpu_affinity cpumask [cpumask...]
缺省值: none Linux only. With this option you can bind the worker process to a CPU, it calls sched_setaffinity().仅适用于linux,使用该选项可以绑定worker进程和CPU. For example, worker_proceses 4; worker_cpu_affinity 555-5555 555-5555; Bind each worker process to one CPU only.分别给每个worker进程绑定一个CPU.
worker_proceses 2; worker_cpu_affinity 555-5555; Bind the first worker to CPU0/CPU2, bind the second worker to CPU1/CPU3.This is suitable for HTT.将CPU0/CPU2绑定给第一个worker进程,将CPU1/CPU3绑定给第二个worker进程。
worker_priority
语法: worker_priority [-]number
缺省值: on With this option you can give to all worker processes the priority (nice) you need/wish, it calls setpriority().使用该选项可以给所有的worker进程分配优先值。
worker_processes
语法: worker_processes number
缺省值: 1 e.g.: worker_processes 5; nginx has the ability to use more than one worker process for several reasons:nginx可以使用多个worker进程,原因如下: to use SMP to decrease latency when workers blockend on disk I/O to limit number of connections per process when select()/poll()
is used The worker_processes and worker_connections from the event sections allows you to calculate maxclients value: k max_clients = worker_processes * worker_connections
worker_rlimit_core
语法: worker_rlimit_core size
缺省值: ‘ Maximum size of core file per worker;
worker_rlimit_nofile
语法: worker_rlimit_nofile limit
Chapter2.基本配置 2.2.配置说明
缺省值: ‘ Specifies the value for maximum file descriptors that can be opened by this process.指定
worker_rlimit_sigpending
语法: worker_rlimit_sigpending limit
缺省值: ‘ (Since Linux 2.6.8) Specifies the limit on the number of signals that may be queued for the real user ID of the calling process.
working_directory
语法: working_directory path
缺省值: –prefix This is the working directory for the workers. It’s used for core files only. nginx uses absolute paths only, all relative paths in configuration files are relative to –prefix==PATH.
event配置
http参数
alias
语法: alias file-path|directory-path;
缺省值: no context: location This directive assigns a path to be used for the indicated location. Note that it may look similar to the root directive, but the document root doesn’t change, just the file system path used for the request. For example:
1 location /i/ {
2 alias / spool / w3 / images /;
3 }

The request “/i/top.gif” will return the file “/spool/w3/images/ top.gif”. It is possible to use variables in the replacement path. The alias directive cannot be used inside a regex-specified location. If you need to do this you must use a combination of
rewrite and root.
client_body_in_file_only
语法: client_body_in_file_only on|off
缺省值: client_body_in_file_only off context: http, server, lo-cation The directive enables to store a client request body in a file. Please note that the file at the request completion will not be removed if the directive is enabled. The directive can be used
for debugging and for the $r->request_body_file method in the ngx_http_perl_module module.
client_body_buffer_size
语法: client_body_buffer_size the_size
缺省值: client_body_buffer_size 8k/16k context: http, server, location The directive specifies the client request body buffer size. If the request body is more than the buffer, then the entire request
2.2.配置说明 Chapter2.基本配置
body or some part is written in a temporary file.The缺省值 size is equal to two pages size, depending on platform it is either 8K or 16K.
client_body_temp_path
语法: client_body_temp_path dir-path [ level1 [ level2 [ level3 ] ]]
缺省值: client_body_temp_path client_body_temp context: http, server, location The directive assigns the directory for storing the temporary files in it with the body of the request. In the dir-path a hierarchy of subdirectories up to three levels are possible.
For example
1 client_body_temp_path /spool/nginx/client_temp 1 2;
The directory structure will be like this: /spool/nginx/client_temp/ 7/45/555-55557
client_body_timeout
语法: client_body_timeout time
缺省值: client_body_timeout 60 context: http, server, location Directive sets the read timeout for the request body from client. The timeout is set only if a body is not get in one readstep. If after this time the client send nothing, nginx returns error “Request
time out” (408).
client_header_buffer_size
语法: client_header_buffer_size size
缺省值: client_header_buffer_size 1k context: http, server Direc-tive sets the headerbuffer size for the request header from client. For the overwhelming majority of requests it is completely sufficient a buffer size of 1K. However if a big cookie is in the request-header
or the request has come from a wap-client the header can not be placed in 1K, therefore, the request-header or a line of request-header is not located completely in this buffer nginx allocate a bigger buffer, the size of the bigger buffer can be set with the
instruction large_client_header_buffers.
client_header_timeout
语法: client_header_timeout time
缺省值: client_header_timeout 60 context: http, server Directive assigns timeout with reading of the title of the request of client. The timeout is set only if a header is not get in one readstep. If after this time the client send nothing, nginx returns error
“Request time out” (408).
client_max_body_size
语法: client_max_body_size size
缺省值: client_max_body_size 1m context: http, server, location Directive assigns the maximum accepted body size of client request,
Chapter2.基本配置 2.2.配置说明
indicated by the line “Content-Length” in the header of request. If size is greater the given one, then the client gets the error “Request Entity Too Large” (413). It is necessary to keep in mind that the browsers do not know how to correctly show this error.
缺省值_type
语法:缺省值_type MIME-type
缺省值:缺省值_type text/plain context: http, server, location default_type assigns the default MIME-type to be used for files where the standard MIME map doesn’t specify anything. See also types Example:
1 location = / proxy . pac {
2 default_type application /x.ns.proxy.autoconfig ;
3 }
4 location = / wpad . dat {
5 rewrite . / proxy . pac ;
6 default_type application /x.ns.proxy.autoconfig ;
7 }

error_page
语法: error_page code [ code... ] [ = |=answer-code ] uri
缺省值: no context: http, server, location, if in location The directive specifies the URI, which will be showed for the errors indicated. Example of the use:
1 error_page 404 /404.html;
2 error_page 502 503 504 /50x.html;
3 error_page 403

http://example.com/forbidden.html;

Furthermore, it is possible to change the code of answer to another, for example: error_page 404 =200 /.empty.gif; If an erroneous answer is processed by the proxied or FastCGI server and this server can return the different answer codes, for example, 200,
302, 401 or 404, then it is possible to issue the code returned: error_page 404 = / 404.php;
index
语法: index file


缺省值: index index.html context: http, server, location Directive determines the file(s) which will be used as the index. It’s possible to use variables in the name of file. The presence of the files is checked in the order of their enumeration. A file with an
absolute path can be put at the end. Example using a variable: index index. $geo.html index.0.html /index.html;
internal
语法: internal
缺省值: no context: location internal indicates that the match-ing location can be used only for so called “internal” requests. For
2.2.配置说明 Chapter2.基本配置
external requests it will return the error “Not found” (404). Inter-nal requests are the following: requests redirected by the instruc-tion error_page subrequests created by the command include virtual of the “ngx_http_ssi_module” module requests changed by
the instruction rewrite of the “ngx_http_rewrite_module” module An example to prevent clients fetching error pages directly:
1 error_page 404 /404.html; 2 location /404.html {
3
internal; 4}
keepalive_timeout
语法: keepalive_timeout time [ time ]
缺省值: keepalive_timeout 75 context: http, server, location Directive assigns the timeout, for keep-alive connections with the client. The second parameter assigns value in the line “Keep-Alive: timeout=time” in the header of answer. The parameters can differ
from each other. Line “Keep-Alive: timeout=time” understands Mozilla and Konqueror. MSIE itself shuts keep-alive connection approximately after 60 seconds.
large_client_header_buffers
语法: large_client_header_buffers number size
缺省值: large_client_header_buffers 4 4k/8k context: http, server Directive assigns the maximum number and size of buffers for large headers to read from client request. The request line can not be bigger then the size of one buffer, if the client send a bigger
header nginx returns error “Request URI too large” (414). The longest header line of request also must be not more than the size of one buffer, otherwise the client get the error “Bad request” (400). Buffers are separated only as needed. By default the size
of one buffer is equal to the size of page, depending on platform this either 4K or 8K, if at the end of working request connection converts to state keep-alive, then these buffers are freed.
limit_except
语法: limit_except methods {…}
缺省值: no context: location Directive limits HTTP-methods, acces-sible inside location. For the limitation can be used the directives of modules ngx_http_access_module and ngx_http_auth_basic_module: limit_except GET { allow 192.168.1.0/32; deny all; }
limit_rate
语法: limit_rate speed
缺省值: no context: http, server, location, if in location Direc-tive assigns the speed of transmission of the answer to client. Speed is assigned in the bytes per second. Limitation works only for one connection, i.e., if client opens 2 connections, then total
velocity
Chapter2.基本配置 2.2.配置说明
will be 2 times than higher limited. If it is necessary to limit speed for the part of the clients at the level of server, then directive limit_rate for this does not be suitable. Instead of this should be assigned the necessary speed of variable $limit_rate:
1 2 3 4 server if } { ( $slow ) { set $limit_rate 4k;
5
6 …
7 8 }

listen
语法:listen address:port [缺省值 [ backlog=num | rcvbuf=size | sndbuf=size | accept_filter=filter | deferred | bind ] ]
缺省值: listen 80 context: server The directive specifies the address and port, on which the server accepts requests. It is possible to specify address or port only, besides, an address can be the server name, for example:
1 listen 127.0.0.1:8000;
2 listen 127.0.0.1;
3 listen 8000;
4 listen *:8000;
5 listen localhost :8000;

If only address is given, then缺省值 port 80 is used. If the directive has the”缺省值” parameter, then the server, in whom is described this directive, he will be the缺省值 server for the ad-dress:port pair, but if there are no directives with the”缺省值”parameter,
then the缺省值 server will be the first server, in whom is described the address:port pair. In directive listen with parameter缺省值 it is possible to indicate several parameters, specific for the system calls listen(2) and bind(2). backlog=num –is assigned parameter
backlog in call listen(2). By缺省值 backlog it is equal to -1. rcvbuf=size –is assigned parameter SO_RCVBUF for listening socket. sndbuf=size –is assigned parameter SO_SNDBUF for listening socket. accept_filter=filter –is assigned name accept-filter. It works
only to FreeBSD, it is possible to use two filters –dataready and httpready. On the signal -HUP accept-filter it is possible to change only in the quite last versions FreeBSD: 6.0, 5.4-STABLE and 4.11-STABLE. deferred –indicates to use that postponed accept(2)
on Linux with the aid of option TCP_DEFER_ACCEPT. bind –indicates that it is necessary to make bind(2) separately for this pair of address:port. The fact is that if are described several directives listen with the identical port, but by different addresses
and one of the directives listen listens to on all addresses for this port (*:port), then nginx will make bind(2) only to *:port. It is necessary to consider that in
2.2.配置说明 Chapter2.基本配置
this case for determining the address, on which the connections ar-rive, is done the system call getsockname(). But if are used parameters backlog, rcvbuf, sndbuf, accept_filter or deferred, then it is always done separately for this pair of address:port bind(2).
Example of the use of the parameters:listen 127.0.0.1缺省值 accept_filter=dataready backlog=1024;
location
语法: location [=|~|~*|^~] /uri/ { … }
缺省值: no context: server This directive allows different con-figurations depending on the URI. It can be configured using both conventional strings and regular expressions. To use regular expres-sions, you must use the prefix ~* for case insensitive match and
~ for case sensitive match. To determine which location directive matches a particular query, the conventional strings are checked first. Con-ventional strings match the beginning portion of the query and are case-sensitive -the most specific match will be
used (see below on how nginx determines this). Afterwards, regular expressions are checked in the order defined in the configuration file. The first regular expres-sion to match the query will stop the search. If no regular expression matches are found, the
result from the convention string search is used. There are two ways to modify this behavior. The first is to use the prefix “=”, which matches an exact query only. If the query matches, then searching stops and the request is handled immediately. For example,
if the request “/” occurs frequently, then using “location = /” will expedite the processing of this request. The second is to use the prefix ^~. This prefix is used with a conventional string and tells nginx to not check regular expressions if the path provided
is a match. For instance, “location ^~ /images/” would halt searching if the query begins with /images/ -all regular expression directives would not be checked. Furthermore it is important to know that NGINX does the comparison not URL encoded, so if you have
a URL like “/ images/%20/test” then use “/images/ /test” to determine the location. To summarize, the order in which directives are checked is as follows: Directives with the = prefix that match the query exactly. If found, searching stops. All remaining directives
with conventional strings, longest match first. If this match used the ^~ prefix, searching stops. Regular expressions, in order of definition in the configuration file. If #3 yielded a match, that result is used. Else the match from #2 is used. Example:
1 location = / {
2 # matches the query / only.
3 [ configuration A ]
4}
5 location / {

6 # matches any query , since all queries begin with /, but regular 7 # expressions and any longer conventional blocks will be
Chapter2. 基本配置 2.2. 配置说明
8 # matched first .
9 [ configuration B ]
10 }
11 location ^~ / images / {
12 # matches any query beginning with / images / and halts
searching ,
13 # so regular expressions will not be checked .
14 [ configuration C ]
15 }
16 location ~* \.( gif | jpg | jpeg )$ {
17 # matches any request ending in gif , jpg , or jpeg .
However , all
18 # requests to the / images / directory will be handled
by
19 # Configuration C.
20 [ configuration D ]
21 }

Example requests: / -> configuration A /documents/document.html -> configuration B /images/1.gif -> configuration C /documents/1.jpg -> configuration D Note that you could define these 4 configurations in any order and the results would remain the same.
How nginx Determines Which Path Matches Most users will not need to know how nginx internally determines which path to use -know that it will choose the “most specific” match for your URL in a speedy and efficient manner. For those that are curious, however,
read on. All path strings are sorted alphabetically. nginx then proceeds to search down the list looking for matches until the request URI has a “higher” value then the current string in the sorted list. This is determined using the family of strcmp() functions
-once strcmp() returns 1, then searching stops. Once searching stops, the last string which matched is used. For example, lets say we have the following paths: / /a /apple /banana Now, lets say the server gets the path “/az”. nginx would begin search down
this list. First, “/” would match, but “/ is less than “/az” so searching continues. “/a” also matches, but “/a” is still less than “/ az” so we continue again. “/apple” does not match. The next string, “/ banana”, is greater than “/az” so searching stops
and the last match, “/a”, would be used.
msie_padding
语法: msie_padding [on|off]
缺省值: msie_padding on context: http, server, location This directive enables or disables the the msie_padding feature for MSIE browsers. When this is enabled Nginx will pad the size of the response headers up to 512 bytes for responses with status codes of more
than 400. This prevents activating the “friendly” http error pages feature of the relevant browsers, so as to not hide the possibly more informative error pages.
msie_refresh
2.2.配置说明 Chapter2.基本配置
语法: msie_refresh [on|off]
缺省值: msie_refresh off context: http, server, location This directive allows or forbids issuing a refresh instead of doing a redirect for MSIE.
optimize_server_names
语法: optimize_server_names [ on|off ]
缺省值: optimize_server_names on context: http, server Directive activates or deactivates optimization of host name checks for name-based virtual servers. In particular, the check influences the name of the host used in redirects. If optimization is on, and all
name-based servers listening on one address:port pair have identical configura-tion, then names are not checked during request execution and redirects use first server name. If redirect must use host name passed by the client, then the optimization must be
turned off.
port_in_redirect
语法: port_in_redirect [ on|off ]
缺省值: port_in_redirect on context: http, server, location Di-rective allows or prevents port indication in redirects handled by nginx.
recursive_error_pages
语法: recursive_error_pages [on|off]
缺省值: recursive_error_pages off context: http, server, loca-tion recursive_error_pages enables or disables following a chain of error_page directives.
root
语法: root path
缺省值: root html context: http, server, location, if in location root specifies the document root for the requests. For example, with this configuration
1 location /i/ { 2 root /spool/w3; 3}
A request for “/i/top.gif” will return the file “/spool/w3/i/ top.gif”. You can use variables in the argument.
satisfy_any
语法: satisfy_any [ on|off ]
缺省值: satisfy_any off context: location Directive solves access with at least one successful checking, executed by modules ngx_http_access_module or ngx_http_auth_basic_module:
1 location / { 2 satisfy_any on;
3 allow 192.168.1.0/32;
Chapter2.基本配置 2.2.配置说明
4 deny all ;
5 auth_basic ” closed site “;
6 auth_basic_user_file conf / htpasswd ;
7 }

send_timeout
语法: send_timeout the time
缺省值: send_timeout 60 context: http, server, location Directive assigns response timeout to client. Timeout is established not on entire transfer of answer, but only between two operations of reading, if after this time client will take nothing, then nginx is
shutting down the connection.
sendfile
语法: sendfile [ on|off ]
缺省值: sendfile off context: http, server, location Directive activate or deactivate the usage of sendfile().
server
语法: server {…}
缺省值: no context: http Directive assigns configuration for the virtual server. There is no clear separation of the virtual servers ip-based (on the basis ip-address) and name-based (on the basis of the name, transferred in the line “Host” of the title of request).
Instead of this by directives listen are described all addresses and ports, on which it is necessary to assume connections for this server, and in directive server_name are indicated all names of servers. The example to configurations is described in tuning
of virtual servers.
server_name
语法: server_name name [... ]
缺省值: server_name hostname context: server Directive assigns the names of virtual server, for example: server { server_name example.com
www.example.com; } The first name becomes the basic name of server. By缺省值 the name of the machine (hostname) is used. It is possible to use “*” for replacing the first part of the name: server
{ server_name example.com *.example.com; } Two of the given name of the above example can be combined into one: server { server_name .example.com; } The basic name of server is used in an HTTP redirects, if no a “Host” header was in client request or that
header does not match any assigned server_name. You can also use just “*” to force Nginx to use the “Host” header in the HTTP redirect (note that “*” cannot be used as the first name, but you can use a dummy name such as “_” instead): server { server_name
example.com *; } server { server_name _ *; }
server_names_hash_max_size
语法: server_names_hash_max_size number
缺省值: server_names_hash_max_size 512 context: http Directive
2.2.配置说明 Chapter2.基本配置
assigns the maximum size of the hash-tables of the names of servers. In greater detail see in the description of tuning hash.
server_names_hash_bucket_size
语法: server_names_hash_bucket_size number
缺省值: server_names_hash_bucket_size 32/64/128 context: http Directive assigns the size of basket in the hash-tables of the names of servers.This value by缺省值 depends on the size of the line of processor cache. In greater detail see in the description of tuning
hash.
tcp_nodelay
语法: tcp_nodelay [on|off]
缺省值: tcp_nodelay on context: http, server, location This di-rective allows or forbids the use of the socket option TCP_NODELAY. Only included in keep-alive connections. Want to know more about the TCP_NODELAY socket option? ReadMoreAboutTcpNodelay
tcp_nopush
语法: tcp_nopush [on|off]
缺省值: tcp_nopush off context: http, server, location This di-rective permits or forbids the use of the socket options TCP_NOPUSH on FreeBSD or TCP_CORK on Linux. This option is only available when using sendfile. Setting this option causes nginx to attempt to
send it’s HTTP response headers in one packet on Linux and FreeBSD 4.x ReadMoreAboutTcpNopush
types
语法: types {…} context: http, server, location Directive as-signs the correspondence of expansion and MIME-types of answers. Toone MIME-type can correspond several expansions. By缺省值 it is used these correspondences:
1 types {
2 text / html html ;
3 image / gif gif ;
4 image / jpeg jpg ;
5 }

The sufficiently complete table of mappings is included and is located in file conf/mime.types. So that for that determined location’a for all answers would reveal MIME-type “application/octet-stream”, it is possible to use the following:
1 location /download/ {
2 types { }
3 default_type application/octet.stream;
4}

Chapter2.基本配置 2.2.配置说明
http配置
The module ngx_http_core_module supports the built-in variables, whose names correspond with the names of variables in Apache. First of all, these are the variables, which represent the lines of the title of the client request, for example,
$http_user_agent, $http_cookie and so forth. Furthermore, there are other variables:
$args, this variable is equal to arguments in the line of request;
$content_length, this variable is equal to line “Content-Length” in the header of request; $content_type, this variable is equal to line “Content-Type” in the header of request; $document_root, this variable is equal to the value of directive root for the current
request;
$document_uri, the same as $uri;
$host, this variable is equal to line “Host” in the header of request or name of the server, to whom the request arrived, if there is no this line;
$limit_rate, the variable allows to limit connection rate;
$request_method, this variable is equal to the method of request, usually this “GET” or “POST”; $remote_addr, this variable is equal to the address of client; $remote_port, this variable is equal to the port of client;
$remote_user, this variable is equal to the name of user, authen-ticated by ngx_http_auth_basic_module;
$request_filename, this variable is equal to path to the file for the current request, formed from directives root or alias and URI request; $request_body_file, ??? $request_uri, this variable is equal to the complete initial URI together with the arguments;
$query_string, the same as $args;
$scheme, the HTTP scheme (http, https). Evaluated only on demand, for example: rewrite ^(.+)$ $scheme://example.com$1 redirect;
$server_protocol, this variable is equal to the protocol of re-quest, usually this “HTTP/1.0″ or “HTTP/1.1″;
$server_addr, the variable is equal to the server address, to whom arrived the request. As a rule, for obtaining the value of this variable is done one system call. In order to avoid system call, it is necessary to indicate addresses in directives listen and
to use parameter bind;
$server_name, this variable is equal to the name of the server, to whom arrived the request;
$server_port, this variable is equal to the port of the server, to which the request arrived;
$uri, this variable is equal to current URI in the request, it can differ from initial, for example by internal redirects, or with the
2.2.配置说明 Chapter2.基本配置
use of index it is file with internal redirects.
常用配置举例nginx目录自动加斜线
1 if (.d $request_filename ){
2 rewrite ^/(.*) ([^/]) $ http :// $host / $1$2 / permanent ;
3 }

nginx防盗链
1.
针对不同的文件类型

2.
针对不同的目录

1 # Preventing hot linking of images and other file types
2 location ~* ^.+\.( gif | jpg | png | swf | flv | rar | zip )$ {
3 valid_referers none blocked server_names *. linuxtone .
org http :// localhost baidu . com ;
4 if ( $invalid_referer ) {
5 rewrite ^/ http :// www . linuxtone . org / images /
default / logo . gif ;
6 # return 403;
7 }
8 }

1 location / img / {
2 root / data / www / wwwroot / bbs / img /;
3 valid_referers none blocked server_names *. linuxtone .
org http :// localhost baidu . com ;
4 if ( $invalid_referer ) {
5 rewrite ^/ http :// www . linuxtone . org / images /
default / logo . gif ;
6 # return 403;
7 }
8 }

nginx expires
1.根据文件类型expires
1 # Add expires header for static content
2 location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ { 3 if (.f $request_filename) { 4 root /data/www/wwwroot/bbs;
5
expires 1d;
Chapter2. 基本配置 2.3. 启动和控制
6 7 8 } } break ;

2.根据判断某个目录
1 # serve static files
2 location ~ ^/( images | javascript | js| css | flash | media | static
)/ {
3 root / data / www / wwwroot / down ;
4 expires 30 d;
5 }

nginx下载限制并发和速率
1
2 limit_zone one $binary_remote_addr 10 m;
3 server {
4 listen 80;
5 server_name down . linuxotne . org ; index index . html
index . htm index . php ;
6 root / data / www / wwwroot / down ;
7 # Zone limit
8 location / {
9 limit_conn one 1;
10 limit_rate 20 k;
11 }

2.3启动和控制
nginx是超级稳定的服务器,一般不会因为超载问题而需要重启,重启的目的一般都是修改配置文件后需要加载一下。最开始的时候,我是用最直接的重启方式 killall -9 nginx;/data/nginx/sbin/nginx如果机器比较慢,kill进程时一瞬间杀不完,再执行一次即可。这种重启方式不是特别安全,如果配置有误,则会重启失败,需要重新修改配置文件然后再启动,期间会消耗一点时间。不过对于目前普遍还是不怎么严格的http界而言,这点时间还不至于产生太大损失,只要不是在关键时刻搞出来就好。如果希望沿用这种重启办法,我提议还是先好好测试吧。后来我在nginx.net上看到了一种更奇妙的重启
kill-HUP$pid($pid就是nginxmaster进程的进程号)我一般这样用
kill .HUP `cat / data / nginx / logs / nginx .pid `
这种方式的好处是实现“平滑重启”,在ps-aux中可以看到,nginx首先启动新进程,旧的进程仍然提供服务,在一段时间后,旧的进程服务结束就自动关闭,剩下新进程继续服务。但是这种方式也是有缺点的,如果配置文件有误,或者资源冲突,则重启失效,但nginx并没有任何的提示!这就会时常发现改动的配置文件没有生效,又比较难找到问题。所以,最后杂和了一下问题,
2.3.启动和控制 Chapter2.基本配置
弄了一个nginx.sh,这个版本的nginx.sh还是没有解决kill-HUP的资源冲突的问题,但解决了配置文件的问题。资源冲突的比如80端口被占用、日志文件目录没有创建这种的,我再想想办法。
1
#!/ bin/sh
2 BASE_DIR =’/data/’
3 ${BASE_DIR}nginx/sbin/nginx .t .c ${BASE_DIR}nginx/conf/

nginx.conf > & ${BASE_DIR}nginx/logs/nginx.start 4 info =` cat ${BASE_DIR}nginx/logs/nginx.start ` 5 if [`echo $info | grep .c "syntax is ok " ` .eq 1 ]; then 6 if [`ps aux|grep "nginx "|grep .c "master" ` == 1 ];
then 7 kill .HUP `cat ${ BASE_DIR } nginx / logs / nginx .pid ` 8 echo “ok ”
9
else
10
killall .9 nginx
11
sleep 1 12 ${BASE_DIR}nginx/sbin/nginx
13
fi
14
else 15 echo “######## error: ########” 16 cat ${BASE_DIR}nginx/logs/nginx.start
17
fi

Chapter 3
深入源码

3.
1源码结构

3.
2configure配置

3.
3nginx源码习惯

为了能更好的看懂代码,需要对nginx的源码习惯有所了解,这样读源码会更加容易一些,在所有的nginx的中实现的模块都有一个ngx_前缀,包括源文件的文件名,结构体和函数。http模块中的结构体和函数以ngx_http作为前缀。
nginx的数组的使用习惯,如下面/src/http/ngx_http_upstream.c文件中的代码所示:
1 if (uscf.>servers == NULL ) {
2 uscf.>servers = ngx_array_create (cf.>pool , 4, sizeof (
ngx_http_upstream_server_t ));
3 if (uscf .>servers == NULL ) {
4 return NGX_CONF_ERROR ;
5 }
6 }
7
8 us = ngx_array_push (uscf.>servers );
9 if (us == NULL ) {
10 return NGX_CONF_ERROR ;
11 }
12
13 ngx_memzero (us , sizeof ( ngx_http_upstream_server_t ));

如上面的代码所示,数组首先调用ngx_array_create创建一个数组对象,然后调用ngx_array_push函数得到一个指针,这个指针指向一个对象,该对象的内存已经分配好了,可以直接使用。首先使用一个指针指向数组结构的elts字段,这样就得到了一个数组,该数组的大小为数组结构体的nelts字段,使用的方式如下所示:
3.4.常用基础库 Chapter3.深入源码
1 uscfp = umcf.>upstreams.elts;
2 for (i = 0; i < umcf.>upstreams.nelts; i++) {
3 if ( uscfp [i].>host.len != u.>host.len ||

ngx_strncasecmp ( uscfp [i].>host.data, u.>host .data , u.>host.len)!= 0){
4
continue ; 5} 6}
对于其他数据结构的使用大致如此,在后面的讲解基础结构的时候详细解释。
在内存使用方面,尽量使用nginx提供的内存使用方式,在初始化或是需要长时间保存的内存尽量采用在cf->pool(即由全局配置分配的内存池)中分配内存的方式来分配内存,在每个请求
3.4常用基础库
由于c语言没有C++或是java那样丰富的库函数,所以一般会自己实现一些相对简单却非常实用的库函数,在nginx中有很多值得学习的基础库函数。在本书中只介绍一些使用频繁或是设计精巧的库函数。如果您是一个经验丰富的linux开发人员,本章可以略过。
字符串
任何一门编程语言中,字符串的操作都是最基本的知识,所以把这个基本操作单列出来。该模块在ngx_string.h和ngx_string.c中。字符串的操作一般包括:初始化,复制,格式化输出,大小写转换,查找子字符,查找子字符串,字符串转换成数字,字符串编码类型相关函数,字符串比较,trim,split等函数。在这个类中间没有调用其他模块的函数,作为一个http服务器,还需要实现URL转换,简单的html转换等函数。字符串的结构体非常简单实用,是非常值得刚入门的linux开发工程师学习的。字符串的结构体为ngx_str_t,其两个字段如下:
Table 3.1:字符串结构体字段
字段 说明
len 字符串长度
data 字符串指针

字符串结构体由两个字段构成,一个是字符串的长度,一个字符串的首指针。这种结构体可以使得在使用字符串的时候异常简单,但是nginx的实现不够彻底还是有些使用c的字符串规则的函数,即以0作为字符串的最后一个字符。字符串函数如下表所列:
Chapter3.深入源码 3.4.常用基础库
Table 3.2:字符串结构体字段
函数 说明
ngx_string 初始化函数
ngx_null_string 初始化空字符串函数
ngx_tolower 字符转小写函数
ngx_toupper 字符转大写函数
ngx_strncmp 比较指定长度的字符串是否相同
ngx_strcmp 比较字符串是否相同
ngx_strstr 从字符串中找到需要的字符串
ngx_strlen 字符串的长度
ngx_strchr 在字符串中找到匹配的字符,返回 0为匹

ngx_strlchr 在字符串中找到匹配的字符,返回匹配的
指针
ngx_memzero 把一片内存区设置为0
ngx_memset 把一片内存区设置为指定的数
ngx_memcpy 复制内存,没有返回
ngx_cpymem 复制内存,返回复制完了 dst的最后一个
字符的下一个字符的指针
ngx_copy 同ngx_cpymem
ngx_memcmp 比较内存中的数据是否相同
ngx_strlow 把字符串都转换成小写
ngx_cpystrn 复制字符串,并且返回字符串的最后一个
字符的下一个字符的指针
ngx_pstrdup 复制字符串到pool,返回字符串的指针
ngx_sprintf 把各种类型的数据格式化输出到buf,最
大的长度为65536
ngx_snprintf 把各种类型的数据格式化输出到指定长度
的buf
ngx_strcasecmp 不分大小写比较两个字符串是否相同
ngx_strncasecmp 指定长短不分大小写比较两个字符串是否
相同
ngx_strnstr 在指定大小一个字符串中是否有子字符串
ngx_strstrn 在一个字符串中是否有子指定大小的字符

ngx_strcasestrn 在一个字符串中是否有子指定大小的字符
串,不区分大小写
ngx_rstrncmp 从后往前比较两个字符串是否相同,返回
相同的位置
ngx_rstrncasecmp 从后往前比较两个字符串是否相同,返回
相同的位置,不区分大小写
ngx_memn2cmp 比较两个指定长度的内存是否相同,也比
较长的内存是否包含短的内存
ngx_atoi 指定长度的字符串转换成数字
ngx_atosz 指定长度的字符串转换成 ssize_t类型数

ngx_atoof 指定长度的字符串转换成off_t类型数字
ngx_atotm 指定长度的字符串转换成time_t类型数字

3.4.常用基础库 Chapter3.深入源码
续表 3.8
函数 说明
ngx_hextoi 指定长度的字符串转换成十六进制数字
ngx_hex_dump 把数字转换成16进制的字符串
ngx_encode_base64 base64编码
ngx_decode_base64 base64解码
ngx_utf8_decode 把 utf8字符解码成双字节的 unicode或是
单字节字符,但是该函数会移动*p的值,
请注意
ngx_utf8_length 得到utf8编码的字符占几个字节
ngx_utf8_cpystrn 赋值utf8字符串,保证完整的复制
ngx_escape_uri 对uri进行编码
ngx_unescape_uri 对uri的进行解码
ngx_escape_html 对html进行编码
ngx_sort 排序,主要是用于数组排序
ngx_qsort 快速排序
ngx_value 把宏数字转换成字符串

为了测试,我们可以用以下两种方式打印出来
1 ngx_str_t str ;
2 printf (” %* s” , str . len , str . data );
3 peinrf (”%V”, & str );

内存分配
Nginx的内存分配的技巧很值得我们学习,设计的是非常精巧的,它会根据不同的生存周期建立起一系列的内存pool,在需要使用内存的时候,直接在 pool中获取内存即可。这种方法既加快了速度,又能够非常方便的管理内存,避免内存泄露。涉及到内存分配的文件主要有 ngx_alloc.h,ngx_alloc.c,ngx_buf.c,ngx_output_chain.c,ngx_buf.h,ngx_palloc.h 和ngx_palloc.c。
我们在讲解对内存池的创建和使用之前,我们先讲解一下封装的基本的分配内存的函数:
ngx_alloc
这个函数实际上是调用malloc()函数,但是记录了日志。C语言跟内存申请相关的函数主要有 alloc,calloc,malloc,free,realloc,sbrk等,其中alloc是向栈申请内存,因此无需释放,malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间,calloc则将初始化这部分的内存,设置为0,而realloc则对malloc申请的内存进行大小的。
ngx_calloc
这个函数调用了ngx_alloc分配了内存之后,调用ngx_memzero把分配的内存都置为0。
ngx_memalign
Chapter3.深入源码 3.4.常用基础库
这个函数在linux下实际封装调用了memalign函数。能够分配连续的内存块。这个函数主要在分配大块的内存的时候使用。
ngx_free
这个函数就是free函数的宏定义。
内存池的结构体如下代码所示
1 struct ngx_pool_s {
2 ngx_pool_data_t d;
3 size_t max ;
4 ngx_pool_t * current ;
5 ngx_chain_t * chain ;
6 ngx_pool_large_t * large ;
7 ngx_pool_cleanup_t * cleanup ;
8 ngx_log_t * log ;
9 };

d字段为池数据;max字段为分配的内存大小减去ngx_pool_s的结构体所占内存大小,也就是能够使用的内存的大小;current字段为指向ngx_pool_s结构体的指针;chain在ngx_alloc_chain_link函数中使用,主要是用来标示chain的,large是指向大块内存的指针,这里的大块的意思是需要分配大于max大小的内存的时候,新分配的内存块,log为记录日志的结构体。
数据结构讲完了,我们来看一下相关函数。
ngx_create_pool
创建内存池,该函数的功能为分配内存,并初始化内存池的一些字段。
ngx_palloc
使用内存池,在分配好的内存池中分配一片内存使用,在当前需要分配的内存不够的时候,则再通过ngx_palloc_block分配一块与初始化的内存一样大小的内存供使用,如果需要分配的内存的大小size大于max时候,该函数通过调用ngx_palloc_large分配一个需要 size+sizeof(ngx_pool_t)大小的内存。我们在为nginx编写module的时候,一般只需用调用这个函数分配内存就可以了。
ngx_destroy_pool
释放由ngx_create_pool创建的内存,以及在使用过程中所分配的资源。
ngx_reset_pool
释放掉large的资源,保留已分配的基本内存资源,并把ngx_pool_s结构体初始化。
除了内存的使用,nginx还提供了buf以及chain的使用。我们首先讲解buf的相关的结构体和函数,然后再讲解chain的结构体和函数。下面为buf的结构体:
1 typedef struct ngx_buf_s ngx_buf_t;
2 struct ngx_buf_s {
3 u_char * pos ;
4 u_char * last ;
5 off_t file_pos ;
6 off_t file_last ;
7 u_char * start ; /* start of buffer */

3.4. 常用基础库 Chapter3. 深入源码
8 u_char * end ; /* end of buffer */
9 ngx_buf_tag_t tag ;
10 ngx_file_t * file ;
11 ngx_buf_t * shadow ;
12
13 /* the buf ’s content could be changed */
14 unsigned temporary :1;
15
16 /*
17 * the buf ’s content is in a memory cache or in a
read only memory
18 * and must not be changed
19 */
20 unsigned memory :1;
21
22 /* the buf ’s content is mmap () ed and must not be
changed */
23 unsigned mmap :1;
24 unsigned recycled :1;
25 unsigned in_file :1;
26 unsigned flush :1;
27 unsigned sync :1;
28 unsigned last_buf :1;
29 unsigned last_in_chain :1;
30 unsigned last_shadow :1;
31 unsigned temp_file :1;
32 /* STUB */ int num ;
33 };

pos字段为当前未使用的buf的指针的开始,last字段标示使用的buf的内存的结束指针,start字段为buf内存的起始指针,temporary字段标示该buf是不是临时的,
ngx_create_temp_buf
在pool中创建一个临时的buf,并初始化一些参数。
ngx_buf_size
得到buf中的数据的大小。
ngx_alloc_buf
在内存池中分配一个buf的结构体。
ngx_calloc_buf
在内存池中分配一个buf的结构体,并把给结构体的所有有字段初始化为
0。
ngx_buf_in_memory
判断当前的buf是不是在内存中。
ngx_buf_in_memory_only
判断当前的buf是不是只在内存中。
Chapter3.深入源码 3.4.常用基础库
chain的相关的结构体如下:
1 struct ngx_chain_s {
2 ngx_buf_t * buf ;
3 ngx_chain_t * next ;
4 };
5
6 typedef ngx_int_t (* ngx_output_chain_filter_pt )( void *ctx
, ngx_chain_t *in);
7
8 typedef struct {
9 ngx_buf_t * buf ;
10 ngx_chain_t * in ;
11 ngx_chain_t * free ;
12 ngx_chain_t * busy ;
13
14 unsigned sendfile ;
15 unsigned directio ;
16 # if ( NGX_HAVE_ALIGNED_DIRECTIO )
17 unsigned unaligned ;
18 # endif
19 unsigned need_in_memory ;
20 unsigned need_in_temp ;
21 ngx_pool_t * pool ;
22 ngx_int_t allocated ;
23 ngx_bufs_t bufs ;
24 ngx_buf_tag_t tag ;
25 ngx_output_chain_filter_pt output_filter ;
26 void * filter_ctx ;
27 } ngx_output_chain_ctx_t ;
28
29 typedef struct {
30 ngx_chain_t * out ;
31 ngx_chain_t ** last ;
32 ngx_connection_t * connection ;
33 ngx_pool_t * pool ;
34 off_t limit ;
35 } ngx_chain_writer_ctx_t ;

ngx_chain_s结构体很简单,buf字段就是一个指向缓存的指针,next指向下一个chain。
ngx_output_chain_ctx_t结构体就复杂的多,主要是在ngx_http_copy_filter_module.c和ngx_output_chain.c文件中使用
chain的函数主要在ngx_buf.c和ngx_output_chain.c文件中,其中重要的函数有如下几个:
ngx_alloc_chain_link
就是一个分配ngx_chain_t内存的函数。
ngx_create_chain_of_bufs
3.4.常用基础库 Chapter3.深入源码
在pool中建立一个bufs->num个bufs->size大小的buf,最后返回链表头的指针。 ngx_chain_add_copy把一个链表复制到另外一个链表中,只复制头,不复制内容。 ngx_chain_get_free_buf得到链表中未使用的buf,如果没有,则分配一个。 ngx_chain_update_chains把out的chain变成free的,并挂接到free的chain上。
文件读写和配置文件读取
文件读写是所有的编程语言绕不开的,对于java,python等高级语言来说都有封装好的,跨平台的文件读写文件。对于c语言来说,如果需要支持多个操作系统,就需要封装一下文件的读写。封装文件的读写还有一个益处就是能够把读写异常,读写的内存控制,日志的记录封装起来,以便于其他的模块更好的应用。文件的读写一般会封装成打开文件,关闭打开的文件,读写文件。在nginx的源码中,文件读写主要放在core/ngx_file.c,core /ngx_file.h,src/os/unix/ngx_files.h和src/os/unix/ngx_files.c中。由于nginx的文件读写函数较多,我们只是详细介绍比较重要,经常使用,实现很有技巧的函数。
文件相关的的数据结构有路径,文件,临时文件等数据结构体。
路径的数据结构如下:
1 struct ngx_path_s {
2 ngx_str_t name ;
3 size_t len ;
4 size_t level [3];
5 ngx_gc_handler_pt cleaner ;
6 u_char * conf_file ;
7 ngx_uint_t line ;
8 };

ngx_path_s结构体中name字段为路径数据字符串,level为临时目录的三级目录的大小,len为目录的,conf_file为该路径的来源的配置文件,line为该路径在来源的配置文件中的行数,这两个字段主要用来记录日志,来排查错误。
我们首先介绍简单封装的函数,再介绍复杂封装的函数,简单封装的函数有如下函数:
ngx_open_file/ngx_close_file
打开/关闭文件的函数,这个函数其实就是open/close函数,在nginx中为了更好的使用系统资源,没有使用fopen/fread/fclose来处理文件,打开的参数也做了封装,如下面所示
1 # define NGX_FILE_RDONLY O_RDONLY
2 # define NGX_FILE_WRONLY O_WRONLY
3 # define NGX_FILE_RDWR O_RDWR
4 # define NGX_FILE_CREATE_OR_OPEN O_CREAT

Chapter3. 深入源码 3.4. 常用基础库
5 6 7 # define # define # define NGX_FILE_OPEN NGX_FILE_TRUNCATE NGX_FILE_APPEND 0 O_TRUNC O_APPEND

ngx_delete_file删除文件函数,调用系统的unlink函数,unlink()会删除pathname指定的文件。如果该文件名最后连接点,但有其他进程打开了此文件,则在所有关于此文件的文件描述词皆关闭后才会删除。如果参数pathname为一符号连接
(symboliclink),则此连接会被删除。复杂封装的函数 ngx_open_tempfile打开一个临时文件,配置文件一般有三个作用:根据配置文件启用某段程序,用配置文件传入
参数,设定启动程序程序之间的相互关系。Nginx的配置文件也实现了这三部分的功能,nginx的配置文件主要有以下几个主要的结构体和函数配置文件的结构体有:
Table 3.3:配置文件结构体列表
结构体

抱歉!评论已关闭.