nginx-0.8.38源码探秘
nginx面试八股文

nginx面试八股文摘要:1.Nginx简介与特点2.Nginx的基本配置3.Nginx的负载均衡与反向代理4.Nginx的缓存机制5.Nginx的动静分离6.Nginx的配置优化7.Nginx的安全策略8.Nginx的性能调优正文:一、Nginx简介与特点ginx是一款高性能、开源的Web服务器和反向代理服务器,由俄罗斯程序员Igor Sysoev开发。
Nginx具有以下特点:1.高性能:Nginx采用多线程、异步处理的方式,能有效提高服务器资源利用率,承载大量并发请求。
2.稳定性:Nginx在处理高并发请求时,能保持较低的系统资源占用,具有较好的稳定性。
3.丰富的功能:Nginx支持负载均衡、反向代理、缓存、动静分离等功能,满足各种Web应用需求。
4.易于配置:Nginx的配置文件简单易懂,可定制性强。
二、Nginx的基本配置1.安装Nginx:根据操作系统选择合适的版本进行安装。
2.配置Nginx:编辑Nginx的配置文件,设置虚拟主机、服务器名称、文档根目录等基本参数。
3.配置SSL:为Nginx配置SSL证书,提高网站的安全性。
4.启动与停止Nginx:使用命令启动和停止Nginx服务。
三、Nginx的负载均衡与反向代理1.负载均衡:Nginx支持负载均衡功能,可以将请求分发至后端多台服务器,实现负载均衡。
2.反向代理:Nginx可以作为反向代理服务器,代理后端服务,提高应用层的性能。
四、Nginx的缓存机制1.内置缓存:Nginx内置了简单的缓存功能,可以缓存静态文件,提高访问速度。
2.外部缓存:Nginx支持集成第三方缓存服务器,如Redis、Memcached 等,实现更高效的数据缓存。
五、Nginx的动静分离1.动静分离原理:将动态页面和静态页面分离,动态页面由后端服务器处理,静态页面由Nginx直接提供。
2.配置动静分离:在Nginx配置文件中,设置动态域名和静态文件的存放路径。
Nginx源码分析--模块module解析执行nginx.conf配置文件流程分析一

Nginx源码分析--模块module解析执⾏nginx.conf配置⽂件流程分析⼀ 搭建nginx服务器时,主要的配置⽂件 nginx.conf 是部署和维护服务器⼈员经常要使⽤到的⽂件,⾥⾯进⾏了许多服务器参数的设置。
那么nginx 以模块 module为⾻架的设计下是如何运⽤模块 module来解析并执⾏nginx.conf配置⽂件下的指令的呢?在探究源码之前,需要对nginx下的模块 module 有个基本的认知(详情参考前⾯的博⽂ )同时也要对nginx中常⽤到的⼀些结构有个基本的了解如:内存池pool 管理相关的函数、ngx_string 的基本结构等(详情参考前⾯的博⽂),若不然看代码的时候可能不能很明晰其中的意思,本⽂着重探究的是解析执⾏的流程。
1、从main函数说起。
Nginx的main函数在nginx.c⽂件中(本⽂使⽤release-1.3.0版本源码,200⾏),因为是主函数其中涉及到了许许多多的功能模块的初始化等内容,我们只关注我们需要的部分。
看到326⾏:ngx_max_module = 0;for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]->index = ngx_max_module++;} cycle = ngx_init_cycle(&init_cycle); 可以看出来,这⾥对 ngx_modules (中有介绍)进⾏了索引编号,并且计算得到模块的总数 ngx_max_module。
然后,对cycle进⾏初始化,跳转到 ngx_init_cycle中。
对于cycle 这个变量是nginx的核⼼变量,可以说模块机制都是围绕它进⾏的,⾥⾯的参数⽐较复杂涉及到的内容⼗分多,本⽂并不详细对它讨论,可以将其看作是⼀个核⼼资源库。
2、ngx_init_cycle 函数 这个函数在⽂件ngx_cycle.c中(43⾏),这个函数是nginx初始化中最重要的函数之⼀,⾥⾯涉及到与cycle变量相关的初始化⼯作,看到第188⾏cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module *sizeof(void *)); 这⾥获取了 ngx_max_module 个指针空间,⽤来保存每个模块的配置信息,从cycle 变量的字段conf_ctx 命名中就可以知道,ctx 为context 上下⽂的缩写。
Nginx源代码分析

Nginx源代码分析1.Nginx代码的目录和结构nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清楚,是一个大型效劳端软件构建的一个范例。
以下是源码目录结构说明:├─auto 自动编译安装相关目录│ ├─cc 针对各类编译器进行相应的编译配置目录,包括Gcc、Ccc等│ ├─lib 程序依托的各类库,包括md5,openssl,pcre等│ ├─os 针对不同操作系统所做的编译配置目录│ └─types├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等├─contrib├─html└─src 源码目录├─core 核心源码目录,包括概念经常使用数据结构、体系结构实现等├─event 封装的事件系统源码目录├─http http效劳器实现目录├─mail 邮件代码效劳器实现目录├─misc 该目录当前版本只包括google perftools包└─os nginx对各操作系统下的函数进行封装和实现核心挪用的目录。
2.大体数据结构2.1.简单的数据类型在core/ 目录里面概念了大体的数据类型的映射,大部份都映射到c语言自身的数据类型。
typedef intptr_t ngx_int_t;typedef uintptr_t ngx_uint_t;typedef intptr_t ngx_flag_t;其中ngx_int_t,nginx_flag_t,都映射为intptr_t;ngx_uint_t映射为uintptr_t。
这两个类型在/usr/include/的概念为:/* Types for `void *' pointers. */#if __WORDSIZE == 64# ifndef __intptr_t_definedtypedef long int intptr_t;# define __intptr_t_defined# endiftypedef unsigned long int uintptr_t;#else# ifndef __intptr_t_definedtypedef int intptr_t;# define __intptr_t_defined# endiftypedef unsigned int uintptr_t;#endif因此大体的操作和整形/指针类型的操作类似。
Nginx详解

Nginx详解1Nginx是什么Nginx(engine X)是一个开源的轻量级的HTTP服务器,能够提供高性能的HTTP和反向代理服务。
与传统的Apache服务器相比,在性能上Nginx占用系统资源更小、支持高并发,访问效率更高;在功能上,Nginx不仅作为Web 服务软件,还适用于反向代理、负载均衡等场景;在安装配置上,Nginx更为简单、灵活。
Nginx因为并发性能和资源占用上的优势,已经广泛用于大中型互联网企业。
1.1Nginx特点Nginx具有以下特点:➢支持高并发:Nginx是专门为性能优化而开发的,采用内核Poll模型,单机能够支持几万以上的并发连接。
➢低资源消耗:Nginx采取了分阶段资源分配技术,使得CPU与内存的占用率非常低。
一般1万个非活跃的HTTP Keep-Alive连接在Nginx中仅消耗几MB内存。
➢高拓展性:设计极具扩展性,由多个不同功能、不同层次、不同类型且耦合度极低的模块组成。
➢高可用性:Nginx支持热部署,其中的master管理进程与worker工作进程的分离设计;启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7x24小时不间断地运行。
➢丰富的使用场景:可以作为Web服务端、HTTP反向代理、负载均衡和前端缓存服务等场景使用。
➢开源协议:使用BSD许可协议,免费使用,且可修改源码。
1.2Nginx使用场景1.2.1反向代理代理服务器一般指代局域网内部的机器通过代理服务发送请求到互联网上的服务器,代理服务器一般作用于客户端。
代理服务器是介于客户端和Web服务器之间的服务器,客户端首先与代理服务器创建连接,然后根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或则获得目标服务器的指定资源。
正向代理:为了从原始服务器取的内容,客户端向代理发送一个请求并指定目标(Web服务器),然后代理向Web服务器转交请求并将获得的内容返回给客户端,客户端必须要进行一些特别的设置才能使用正向代理。
nginx底层原理

nginx底层原理Nginx,全称为“engine x”(发音为“engine-ex”),是一款高性能的HTTP和反向代理服务器,也是一款由俄罗斯的程序员Igor Sysoev所开发的自由及开放源代码的Web服务器软件。
Nginx能够出色地处理高并发、静态文件服务以及反向代理,可实现负载均衡,还能充当反向代理服务器和正向代理服务器,同时支持多种协议,如IMAP/POP3/SMTP/HTTP/HTTPS等。
Nginx的底层原理是基于事件驱动的架构,它的核心是一个引擎,它将客户端发送过来的请求分发给各个worker process,worker process再根据不同的类型的请求处理相应的逻辑,最终返回给客户端响应信息。
Nginx的底层原理分为三个部分:master 进程、工作进程和事件循环机制。
1. Master进程Master进程是Nginx的核心,它负责监听端口,当有请求进来时,它会将请求分发给相应的工作进程,并定期检查工作进程的运行状况,如果发现某个工作进程出现异常,它会重新启动一个新的工作进程来替换掉原来的工作进程,以保证服务的正常运行。
2. Worker进程Worker进程是Nginx服务的真正实现者,它负责接收Master进程分发的请求,并对请求进行处理,最后将结果返回给客户端,同时它还负责解析配置文件、编译模块、更新日志等。
3. 事件循环机制事件循环机制是一种特殊的机制,用于管理Nginx中的各种事件,它能够有效地帮助Nginx提高处理请求的效率。
Nginx采用了一种叫做“Reactor模式”的事件循环机制,它将Nginx服务程序分解成多个小模块,每个模块负责处理一种事件,当有事件发生时,会以消息的方式将事件分发给各个模块,然后每个模块处理完消息后,将结果返回给Nginx,从而使Nginx能够高效地处理大量的请求。
Nginx具有高性能、高可用性、低资源消耗等优点,它的底层原理是基于事件驱动的架构,它的核心是一个引擎,它将客户端发送过来的请求分发给各个worker process,worker process再根据不同的类型的请求处理相应的逻辑,最终返回给客户端响应信息;同时Nginx还采用了一种叫做“Reactor模式”的事件循环机制,它将Nginx服务程序分解成多个小模块,每个模块负责处理一种事件,从而使Nginx能够高效地处理大量的请求。
Nginx源码研究

Nginx源码研究概貌 (3)内存池 (5)内存分配相关函数 (5)内存池结构 (5)相关函数 (7)小结 (9)ARRAY (10)结构 (10)相关函数 (10)QUEUE (11)结构 (11)相关函数 (12)HASH TABLE (12)结构 (12)相关函数 (14)LIST (15)结构 (15)相关函数 (15)NGINX启动处理 (16)WORK进程逻辑(NGX_WORKER_PROCESS_CYCLE()函数) (30)1.进程部份 (30)2.线程部份 (31)3.回到进程 (32)CYCLE (32)CONNECTION (33)CONNECTION的内存分布 (33)CONNECTION的分配与回收 (33)EVENT (34)结构 (34)相关函数 (38)CONNECTION (38)结构 (38)相关函数 (42)CONNECTION与EVENT (42)BUFS (44)UPSTREAM (46)Nginx的源码是0.8.16版本。
不是最新版本,但是与网上其他人研究nginx的源码有所修改。
阅读时注意参照对比。
概貌Nginx可以开启多个进程,每个进程拥有最大上限128个子线程以及一定的可用连接数。
如果你希望使用线程可以在配置文件中设置worker_threads这个参数,但这个参数在Nginx官方手册上没有。
只有通过阅读源代码才看到。
最大客户端连接数等于进程数与连接数的乘积,连接是在主进程中初始化的,一开始所有连接处于空闲状态。
每一个客户端请求进来以后会通过事件处理机制,在Linux是Epoll,在FreeBSD下是KQueue放到空闲的连接里。
如果设置了线程数,那么被填充的连接会在子线程中处理,否则会在主线程中依次处理。
nginx由以下几个元素组成:1. worker(进程)2. thread(线程)3. connection(连接)4. event(事件)5. module(模块)6. pool(内存池)7. cycle(全局设置)8. log(日志)整个程序从main()开始算ngx_max_module = 0;for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]->index = ngx_max_module++;}这几句比较关键,对加载的模块点一下数,看有多少个。
简单的NGINX负载均衡例子之欧阳术创编

简单的Nginx负载均衡相好娃12021.Nginx做负载需要多台办事器,所以我们这里来模拟一下,需要多个tomcat,所以把先前装置干净的tomcat复制多份,文件夹名字重新取过,如下图。
2.修改tomcat端口号,掀开第二个tomcat,编辑文件vimtomcat82/conf/server.xml,更改端口号,需要改两个处所,端口号随意,最好是累加8015" shutdown="SHUTDOWN"> //把8005改成8015 8081" protocol="HTTP/1.1" //把8080改成8081connectionTimeout="20000"redirectPort="8443" />3.然后为了区别拜访的哪个tomcat,修改tomcat默认的拜访页面vim webapps/ROOT/index.jsp的TITLE,这样我们可以直接从浏览器上观查拜访的是哪个tomcat。
4.测试下,启动2号tomcat,输入IP拜访5.这时候已经有两个tomcat了,可以用来做nginx的负载均衡的测试了。
接下来配置最简单nginx的负载均衡。
编辑vim nginx.conf 文件,添加介入负载的办事器组6.Nginx默认监听的是80端口,按以前的配置,会拜访nginx的欢迎页面,这里配置成拜访nginx时,转向到我们自界说的办事器组上面,采取轮询的负载7.配置完后需要重启nginx输入命令 ../sbin/nginx s reload8.启动后,拜访机器IP,不加端口默认拜访80端口,也就是nginx,会被转到办事器组上。
轮流拜访两台TOMCAT。
刷新页面即可以看到效果。
TOMCAT1TOMCAT2到这里说明负载已经起作用了。
下一篇会结合一个WEB应用对nginx的配置作进一步的了解。
nagix——精选推荐

nagix置文章分类:Java编程安装Nginx1.首先安装pcre-8.02.tar 否则执行完后会提示一个错误,说缺少PCRE library 这个是HTTP Rewrite 模块,也即是url静态化的包可上传pcre-8.02.tar.gz,输入如下命令安装:Java代码1. tar xzvf pcre-8.02.tar2. ./configure3. make4. make installtar xzvf pcre-8.02.tar./configuremakemake install2.执行如下命令解压nginx:Java代码1. tar xzvf nginx-0.8.35.tar.gztar xzvf nginx-0.8.35.tar.gz3.编译安装nginxJava代码1. cd nginx-0.8.352. ./configure --with-http_stub_status_module--with-http_ssl_module --with-http_sub_modulecd nginx-0.8.35./configure --with-http_stub_status_module--with-http_ssl_module --with-http_sub_module#启动server状态页和https模块Java代码1. --with-http_stub_status_module 必须加上,不然报unknown directive "stub_status"2.3. make4.5. make install--with-http_stub_status_module 必须加上,不然报unknown directive "stub_status"makemake install4.nginx安装成功后的安装目录为/usr/local/nginx在conf文件夹中新建proxy.conf,用于配置一些代理参数,内容如下:Java代码1. #!nginx (-)2. # proxy.conf3. proxy_redirect off;4. proxy_set_header Host $host;5. proxy_set_header X-Real-IP $remote_addr; #获取真实ip6. #proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for; #获取代理者的真实ip7. client_max_body_size 10m;8. client_body_buffer_size 128k;9. proxy_connect_timeout 90;10. proxy_send_timeout 90;11. proxy_read_timeout 90;12. proxy_buffer_size 4k;13. proxy_buffers 4 32k;14. proxy_busy_buffers_size 64k;15. proxy_temp_file_write_size 64k;#!nginx (-)# proxy.confproxy_redirect off;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr; #获取真实ip#proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for; #获取代理者的真实ipclient_max_body_size 10m;client_body_buffer_size 128k;proxy_connect_timeout 90;proxy_send_timeout 90;proxy_read_timeout 90;proxy_buffer_size 4k;proxy_buffers 4 32k;proxy_busy_buffers_size 64k;proxy_temp_file_write_size 64k;编辑安装目录下conf文件夹中的nginx.conf,输入如下内容: Java代码1. #--------------------------------------------2. #运行nginx所在的用户名和用户组3.4. user nobody nobody;5.6. #启动进程数7. worker_processes 2;8. worker_cpu_affinity 0010 0001 ;9. #worker_cpu_affinity 0001 0100 1000 0010 0001 0100 1000 0010;10.11. #全局错误日志及PID文件12. error_log /usr/local/nginx/logs/nginx_error.log crit;13. pid /usr/local/nginx/logs/nginx.pid;14. worker_rlimit_nofile 65535;15.16. #工作模式及连接数上限17. events18. {19. use epoll;20. worker_connections 65535;21. }22.23. #设定http服务器,利用它的反向代理功能提供负载均衡支持24. http{25. include mime.types;26. default_type application/octet-stream;27. server_names_hash_bucket_size 128;28.29. #设定请求缓冲30. client_header_buffer_size 32k;31. large_client_header_buffers 4 32k;32. client_max_body_size 8m;33.34. sendfile on;35. tcp_nopush on;36. keepalive_timeout 60;37. tcp_nodelay on;38. fastcgi_connect_timeout 300;39. fastcgi_send_timeout 300;40. fastcgi_read_timeout 300;41. fastcgi_buffer_size 64k;42. fastcgi_buffers 4 64k;43. fastcgi_busy_buffers_size 128k;44. fastcgi_temp_file_write_size 128k;45.46. #开启gzip模块47. gzip on;48. gzip_min_length 1k;49. gzip_buffers 4 16k;50. gzip_http_version 1.0;51. gzip_comp_level 2;52. gzip_types text/plain application/x-javascript text/css application/xml;53. gzip_vary on;54.55.56. #设定负载均衡列表57. upstream backend58. {59. #down 表示单前的server暂时不参与负载60. #weigth参数表示权值,权值越高被分配到的几率越大61. #server 192.168.3.69:80 weight=1;62. #max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误63. #fail_timeout:max_fails次失败后,暂停的时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
nginx-0.8.38源码探秘先推荐几个研究nginx源码的好网址:/kenbinzhang/category/603177.aspx/p/nginxsrp/wiki/NginxCodeReview/langwan/blog/category/%D4%B4%C2%EB%B7%D6%CE%F6网上分析nginx源码的文章很多,但感觉分析的不够具体和完整,而且都是比较老的nginx版本。
本源码分析基于nginx-0.8.38版本,力求做到更具体和更完整,这是一种自我学习,希望和对此有兴趣的朋友一起探讨,有不正确的地方,也请各位指正。
那么一切从main开始吧!ngx_get_options函数是main调用的第一个函数,比较简单,它负责分析命令行参数,将相应的值赋给对应的全局变量,其中:1.ngx_prefix表示nginx的路径前缀,默认为/usr/local/nginx;2.ngx_conf_file表示nginx配置文件的路径,默认为/usr/local/nginx/conf/nginx.conf;3.ngx_test_config表示是否开启测试配置文件,如配置文件的语法是否正确,配置文件是否可正确打开。
ngx_time_init函数格式化nginx的日志时间,包括ngx_cached_err_log_time,ngx_cached_http_time,ngx_cached_http_log_time,ngx_cached_time。
主要操作在ngx_time_update 内,先获取系统当前时间,与之前保存的时间比较(注意slot),如果已经过时,则将时间重新更新,ngx_cached_time总是指向当前时间的cached_time。
最后还使用了内存屏障ngx_memory_barrier,确保读写顺序。
ngx_log_init函数初始日志结构,主要是对ngx_log变量操作。
初始log 级别为NGX_LOG_NOTICE。
接着分析error_log日志路径,获得完整的日志路径(默认为:/usr/local/nginx/logs/error.log)后,打开日志,获取对应的fd。
接下来碰到了ngx_cycle,这是一个非常重要的变量,初始指向init_cycle,然后创建了1024大小的内存池,在后面将会使用到。
ngx_save_argv函数将命令行参数浅拷贝一份到ngx_os_argv,深拷贝一份到ngx_argv(为什么要复制两份?)。
并将环境变量浅拷贝一份到ngx_os_environ。
ngx_process_options获取配置文件nginx.conf的绝对路径。
默认下,ngx_cycle的如下成员分别为:1. conf_prefix =/usr/local/nginx/conf;2. prefix = /usr/local/nginx/;3. conf_file = /usr/local/nginx/conf/nginx.conf。
ngx_os_init函数获取OS名称和版本号,CPU个数,单个进程能打开的最大文件数,修改ps命令显示的nginx进程名称。
获取OS信息是通过ngx_os_specific_init实现的,其内调用了uname,最重要的语句是ngx_os_io = ngx_linux_io,看看这个结构的组成:ngx_os_io_t ngx_os_io = {ngx_unix_recv,ngx_readv_chain,ngx_udp_unix_recv,ngx_unix_send,ngx_writev_chain,};static ngx_os_io_t ngx_linux_io = {ngx_unix_recv,ngx_readv_chain,ngx_udp_unix_recv,ngx_unix_send,#if (NGX_HAVE_SENDFILE)ngx_linux_sendfile_chain,NGX_IO_SENDFILE#elsengx_writev_chain,#endif};typedef struct {ngx_recv_pt recv;ngx_recv_chain_pt recv_chain;ngx_recv_pt udp_recv;ngx_send_pt send;ngx_send_chain_pt send_chain;ngx_uint_t flags;} ngx_os_io_t;更改了ngx_os_io 的默认配置,注册了linux系统的钩子函数,唯一不同的是ngx_linux_sendfile_chain,里面用系统函数sendfile实现两个文件之间的数据传输,它直接在内核空间拷贝数据,非常高效。
ngx_init_setproctitle实现更改进程名称,因为argv[]和environ[]是相续存储,先遍历完argv,这时ngx_os_argv_last=environ[0],并将environ保存在新分配的内存p中,最后ngx_os_argv_last=argv[0],此函数之前有详细注解,请仔细理解。
ngx_cpuinfo函数获取cpu信息,主要是得到缓存行大小,保存在ngx_cacheline_size中,也可以通过/proc/cpuinfo获取。
在linux中,ngx_inherited_nonblocking=0。
另外,ngx_ncpu最多为1?ngx_add_inherited_sockets函数打开上次保存在环境变量NGINX里的socket,linux一般不设置这个变量,直接返回。
接着遇到了ngx_modules变量,这是nginx模块化思想的实现核心。
每个模块都会注册自己需要的钩子函数。
for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]->index = ngx_max_module++;}以上代码主要是对每个模块建立索引,ngx_max_module保存总的模块数。
ngx_init_cycle函数是个庞然大物,嗯......那就把它留到下章讲解了。
可以看到,nginx大量使用全局变量,这是一个令人头疼的问题!继续分析ngx_init_cycle函数,该函数以init_cycle作为实参,而ngx_cycle是指向它的。
ngx_init_cycle一上来就是更新时区和时间,why?必要吗?紧跟着创建一个NGX_CYCLE_POOL_SIZE大小的内存池,并在该内存池上创建了新的cycle(类型为ngx_cycle_t),然后初始化成员pool、log、new_log、conf_prefix、prefix、conf_file、conf_param、pathes、open_files、shared_memory、listening,值得一提的是cycle->conf_ctx =ngx_pcalloc(pool, ngx_max_module * sizeof(void *)),这个成员在以后索引相应模块的context配置信息非常重要,很快就会看到它的用处。
下面的代码遍历类型为NGX_CORE_MODULE的各个模块,调用模块context 里注册的create_conf函数,该钩子函数基本是初始化配置信息,并将返回的配置信息保存在cycle->conf_ctx中。
for (i = 0; ngx_modules[i]; i++) {if (ngx_modules[i]->type != NGX_CORE_MODULE) {continue;}module = ngx_modules[i]->ctx;if (module->create_conf) {rv = module->create_conf(cycle);if (rv == NULL) {ngx_destroy_pool(pool);return NULL;}cycle->conf_ctx[ngx_modules[i]->index] = rv;}}开始深入到各NGX_CORE_MODULE模块里的create_conf分析:1.ngx_core_module模块,对应的钩子函数是ngx_core_module_create_conf,主要工作就是创建ngx_core_conf_t结构,该结构成员表示的意思可以查看网址/NginxChsHttpMainModule,thanks wiki;2.ngx_errlog_module模块,对应的钩子函数是NULL,让人省事的NULL;3.ngx_events_module模块,又见到可爱的NULL;4.ngx_http_module模块,多来些NULL吧。
这么看来,上面的代码好像也没做啥事情。
配置信息,嗯,到了初始化conf(类型为ngx_conf_t),注意conf.ctx = cycle->conf_ctx,conf.module_type = NGX_CORE_MODULE,conf.cmd_type = NGX_MAIN_CONF。
进入ngx_conf_param函数。
如果启动nginx时,使用了-g选项,那么这个函数就是用来分析后面所带的参数,否则,直接退出。
看看ngx_conf_parse,它的解析分三种类型:parse_file(如果形参带的filename有效,那就打开文件,建立缓冲区),parse_block(这个是文件的内容已经装到缓冲区了,分析{}里面的内容),parse_param(这个就是处理-g选项所带的参数或者是解析出来的参数)。
ngx_conf_read_token函数就是读取配置文件nginx.conf里的内容,取得name-value对。
cf->handler当前为NULL。
ngx_conf_handler函数遍历类型为NGX_CORE_MODULE或NGX_CONF_MODULE的模块,调用这些模块commands里的set钩子,取得相应的value。
如果commands 的type=NGX_CONF_BLOCK,那么则需last=NGX_CONF_BLOCK_START,否则,则需last=NGX_OK。
然后取得本地conf的地址,这个地址就是cycle->conf_ctx对应的模块索引(还记得conf.ctx = cycle->conf_ctx?)。
然后是各模块的set钩子分析:1.ngx_core_module模块,commands注册为ngx_core_commands,它里面注册的set钩子很多,但都比较简单,就是取得对应name的value,需要关注的是name=worker_processes,这是启动工作者进程的个数;2.ngx_errlog_module模块,commands注册为ngx_errlog_commands,它里面只注册了一个set钩子-----ngx_error_log。