`
冰糖葫芦
  • 浏览: 297849 次
社区版块
存档分类
最新评论

nginx介绍(三) 配置篇

阅读更多

 

3. nginx配置

nginx配置系统受益于Igor Sysoev(nginx创始人)Apache(阿帕奇软件基金会)的经历。Igor Sysoev洞察出可扩展的配置系统对于一个web服务器来说是必不可少的。当维持众多虚拟服务器、目录库、地址信息和数据集的大规模结构复杂的配置时,扩展中的主要问题便不期而遇。如果在应用端和系统工程师设计方面处理的不恰当,对于配置一个相对大的web服务器来说将会是一个噩梦。

因此,nginx配置旨在简化日常的操作和为进一步扩展web服务器配置提供一个简单的方法。

nginx配置信息存放在一些位于 /usr/local/etc/nginx或者/etc/nginx等目录下的纯文本文件里主要的配置文件通常被称为nginx.conf为了保持配置系统结构清晰,部分的配置信息保存在单独的文件里,这些文件可以自动被nginx.conf文件调用。然而,这里应该指出目前nginx并不支持Apache风格的分布式配置(.htaccess文件)。所有和nginx web服务器操作有关的配置信息都应该集中存放在一组配置文件里。

主进程会对这些配置文件执行初始化读取和验证操作。由于是主进程的分支,被编译成只读形式的nginx配置对worker进程也是可见的。配置结构自动分享给虚拟的内存管理机制。

nginx配置系统为main, http, server, upstream, location(还有提供邮件代理功能的 mail )块的指令集设置了不同的上下文环境。这些上下文环境从不重叠。例如,不会有像location块和main块的指令集混在一起这样的事情发生。而且,为避免不必要的歧义,nginx 不存在一个全局的web服务器配置。nginx 配置是结构清晰、有逻辑的,而且同时允许用户维护包含成千上万指令的复杂配置文件。在和Sysoev私下谈话中,他曾说:“在Apache中全局服务器配置中的地址、目录和其它配置块是我所不喜欢的功能,因此这也是我没有把它们在nginx中实现的原因”。

nginx配置中的语法、格式和定义采用了C语言风格的规则。这些生成配置文件的方式已经在各种各样的开源的和商业的软件应用中使用。通过设计,C语言风格的配置很适合嵌套和逻辑描述,而且容易创建、阅读、和维护,同时被许多工程师所喜爱。nginxC语言风格的配置也方便自动部署。

虽然nginx的一些指令和Apache设置的部分指令相似,但设置一个nginx实例有相当大的不同之处。例如,nginx支持重写规则,但却需要管理员动手适应从apache风格的rewrite配置文件到nginx风格的转变。重写引擎的实现也有所不同。

一般情况下,nginx设置也对几种原始机制提供了支持,这些机制可以非常有用的作为一个精巧的web服务器配置的一部分。有必要简短地介绍一下nginx独特的变量和try_files命令。为了控制web服务器运行时的配置,nginx中生成的变量提供了一种附加的甚至更强大的机制。为了快速计算,nginx优化了变量和做了内部预编译处理。计算按需完成;也就是说,变量的值通常只被计算一次并且保存在缓存里在特定的请求生命周期内。变量被用于不同的配置指令,为描述条件请求处理行为提供额外的灵活性。

try_files命令最初的目的是以一种恰当的方式逐渐取代 if条件配置语句,而且快速高效地匹配不同的uri到内容的映射。总的来说,try_files命令非常高效有用。建议读者全面核对try_files命令,尽可能的使用其用法。

4nginx内部构件

正如之前提到的,nginx代码库由一个内核和多个模块组成。nginx内核负责提供web服务器的基础功能以及web和邮件的反向代理功能;它允许使用底层的网络协议,建立必要的运行时环境,以及确保不同模块之间的无缝交互。然而,大多数协议和应用程序特定的功能都是由nginx模块完成的,而非nginx内核。

nginx在内部通过管道或链模块处理连接。换句话说,对于每个操作都有一个模块在做相关的工作;例如,压缩,修改内容,执行服务器端的包含文件,通过FastCGI uwsgi协议和上行应用服务器通信,或者和缓存通话。

nginx有两个位于内核和真正的“功能”模块之间的模块,它们就是httpmail模块。这两个模块提供位于内核和下层组件之间的额外的抽象。在这些模块中,实现了与像http,smtp,imap这些应用层协议相关的事件序列的处理。结合nginx内核,这些上层模块负责维护正确调用各功能模块的顺序。尽管http协议目前作为http模块的一部分,由于需要支持像SPDY(请参考:"SPDY: An experimental protocol for a faster web")的其它协议,计划将来把它拆分为一个功能模块。

功能模块可以拆分为事件模块、状态处理程序、输出过滤器、变量处理程序、协议、上行流和负载平衡器。虽然事件模块和协议也用于 mail , 这些模块中的大多数补充了nginxHTTP功能。事件模块提供了一个特别依赖于操作系统的像kqueue epoll的事件通知机制。 nginx使用的模块依赖操作系统的性能和构建配置。协议模块允许通过HTTPS, TLS/SSL, SMTP, POP3 IMAP协议和 nginx进行通信。

一个典型的HTTP请求处理周期如下所示:

1、客户端发送HTTP请求

2nginx内核选择合适的基于配置地址和匹配请求的状态处理程序

3、如果进行了此项配置,一个负载均衡器选择一个上游的代理服务器

4、状态处理程序把每一个输出缓存区传递到第一个过滤器

5、第一个过滤器把输出结果传递到第二个过滤器

6、第二个过滤器把输出结果传递到第三个过滤器(以此类推)

7、最终的处理结果被发送到客户端

nginx模块调用是非常可定制的。这是通过一系列的回调方法实现的。然而,这样做有一个缺点:对于那些喜欢自己编写模块的程序员来说,由于他们必须要准确地定义这些模块应该怎样运行和什么时候运行,所以他们也许会面临一个巨大的负担。为了解决这些问题,nginx API 和开发者文档正在尽可能的改进。

下面是一些模块可附加地址的例子:

在配置文件被读取和处理前

遍历地址和服务器的每一个配置指令

在服务器配置和主要配置合并的时候

在地址配置初始化或与其父服务器配置合并的时候

在主进程启动或退出时

在一个新的 worker 进程启动或退出时

在处理一个请求时

在过滤响应的头部和主体数据时

当向上游服务器执行选择、启动、重新启动一个请求的操作时

在处理来自上游服务器的响应信息时

当完成与上游服务器交互时

worker模块内部,在生成响应的地方,导致运行循环的操作顺序如下所示:

1、开启ngx_worker_process_cycle()方法

2、用操作系统特定的机制(例如:kqueue epoll)处理事件

3、接受事件并调度相关的行动

4、处理或代理请求的头部和主体信息

5、生成响应的内容(头部、主体)并以数据流的形式发送到客户端

6、完成请求

7、重新初始化计时器和事件

运行循环(步骤56)确保增量生成一批响应并且把它们以数据流的形式发送到客户端。

处理一个HTTP请求的更详细的视图如下所示:

1、初始化请求处理

2、处理请求头部信息

3、处理请求主体信息

4、调用关联的处理程序

5、运行处理阶段

下面我们谈谈具体的过程。当nginx 处理一个HTTP请求时,它将通过一系列的处理阶段。在每个阶段都有可调用的处理程序。一般来说,阶段处理程序处理一个请求并且生成相应的输出信息。阶段处理程序附加到配置文件中定义的地址。

阶段处理程序通常做四件事情:获取地址的配置信息、生成恰当的响应信息、发送响应的头信息、发送响应的主体信息。处理程序有一个这样的参数:描述请求的特定结构。请求结构有许多关于客户端请求的有用的信息,比如请求的方法和URI以及头信息。

当读取一个HTTP请求头时,nginx查找相关的虚拟服务器的配置。如果找到了虚拟服务器,请求将会经过6个阶段:

1、服务器重写阶段

2、定位阶段

3、地址重写阶段(此阶段可以把请求返回到前一个阶段)

4、访问控制阶段

5try_files阶段

6、日志记录阶段

尝试在响应信息中生成所需的内容来回复请求时,nginx将请求传递给合适的内容处理程序。根据准确的地址配置信息, nginx首先会尝试像perlproxy_pass, flv, mp4一样所谓的非条件式处理程序。如果请求不符合上面的任何一个处理程序,它将被下面的任意一个处理程序捕获并处理,顺序如下:random index, index, autoindex,gzip_static, static索引模块的细节可以在nginx文档中找到,这些模块使用尾部斜杠处理请求。如果一个像mp4autoindex一样的专用模块匹配不上,那么内容是磁盘上的文件或目录(静态数据)并交给static内容处理程序处理。对于目录,静态内容处理程序会自动重写URI(然后发出HTTP重定向请求)。

内容处理程序的内容传递给过滤器。过滤器也可以关联到地址,一个地址可以配置多个过滤器。过滤器负责操作处理程序产生的输出结果。过滤器执行的顺序在编译时确定。现成的过滤器是预定义的,第三方的过滤器可以在构建阶段配置。在现有的nginx实例中,过滤器只能做输出改变,并且目前没有机制来编写和附加过滤器以实现输入内容转换。nginx未来的版本中将会实现输入过滤。

过滤器遵循一个特定的设计模式。一个过滤器被调用,开始工作,并且调用下一个过滤器直到过滤器链中的最后一个过滤器被调用为止。之后,nginx生成最终的响应信息。过滤器不必等待上一个过滤器操作完成。一得到上一个过滤器的输入信息,过滤器链中的下一个过滤器就开始工作 (此功能很像Unix pipeline)。 相应地, 在接收来自上游服务器的整个响应之前,生成的输出响应可以被传送到客户端。

nginx有响应头过滤器和响应主体过滤器;nginx提供响应的头和主体分别给关联的过滤器。

响应头过滤器的操作由三个步骤组成:

1、决定是否对此响应进行操作

2、在响应中做操作

3、调用下一个过滤器

响应主体过滤器转换生成的内容。例子如下:

1服务器端包含

2XSLT过滤

3、图形过滤(例如,动态调整图像)

4、字符集更改

5gzip 压缩

6、分块编码

在过滤器链之后,响应被传送到写入器。有两个额外的专用过滤器伴随着写入器,也就是 copy过滤器 和 postpone 过滤器。 copy过滤器负责使用可能存储在代理临时目录中相关的响应内容来填充内存缓冲区。postpone 过滤器被用于子请求。

对处理请求/响应来说,子请求是一个非常重要的机制。子请求也是nginx最强大

的方面之一。使用子请求,nginx可以从一个不同的URL返回结果而不仅仅是客户的原始请求URL 。一些web框架把这种方式叫做内部重定向。然而,nginx更进一步----

不仅过滤器可以执行多个子请求并把输出合并到一个响应,而且子请求也可以层层嵌套,例如,一个 subrequest 可以执行它本身的sub-subrequest,并且一个sub-subrequest触发 sub-sub-subrequest (子请求可以为自己创建二级子请求,而且二级子请求可以进一步创建三级子请求)

子请求可以映射到硬盘上的文件,其它处理程序,或上游服务器。子请求最大的用处在于插入基于原始响应数据的新增内容。例如,SSI(服务器端包含) 模块使用过滤器来解析返回文档的内容, 然后使用指定 url 的内容来替换include指令。 或者,它可以成为把整个文档内容当做一个url的过滤器被检索的一个例子,然后把新文档添加到url本身。

upstream和负载平衡器也值得简要描述。Upstream用于实现什么可以被确认是一个反向代理的内容处理程序(proxy_pass处理程序)。upstream模块大多预备发送到上行服务器或后台的请求,并且接收来自上行服务器的响应信息。这里没有调用输出过滤器。当上行服

务器准备写入和读取时,上行模块负责设置要调用的回调方法。回调方法实现以下功能:

1、制作一个发送到上行服务器的请求缓冲区或者请求链

2、重新初始化/重置到上行服务器的连接(再一次创建请求之前)

3、处理上行响应第一个比特位(bit)的数据并且保存从上行服务器接收的有效负载指针

4、退出请求处理(当客户端过早终止请求时)

5、当 nginx 完成从上游服务器的读操作时,结束请求处理

6、修整响应主体(例如,移除尾部)

当有多个上游服务器可供选择时,负载均衡器模块附加到 proxy_pass 处理程序以提供选择一个上游服务器的功能。一个负载均衡器注册一个可启用的配置文件指令,提供附加的上行初始化函数(以解析DNS中上行名称等等),初始化连接结构,决定在什么地方路由请求,和更新统计信息。目前nginx对上游服务器负载均衡支持两种标准的准则:轮询 和 IP哈希 。

upstream和负载均衡处理机制包含检测连接失败的服务器,并将新的请求重新路由至仍然正常的服务器的算法,但是计划要做很多额外的工作来加强这方面的功能。一般来说,关于负载均衡有更多的工作计划去做,而且在下一个版本的nginx中,把负载分布到不同的上行服务器以及健康检查的机制将会大大改善。

还有其它几个有趣的模块,这些模块在配置文件中提供附加的变量以供使用。尽管nginx的变量在不同的模块中被创建和修改,有两个模块是完全专用于变量:geo  map geo 模块是用于基于ip地址跟踪客户端。该模块基于客户端ip地址可以创建任意的变量。另外一个模块 map 允许从其他变量创建新变量,提供灵活映射主机名和其他运行时变量的能力。这种类型的模块可以称为变量处理程序。

在某种程度上受到了Apache的启发,单个nginxworker 中实现了内存分配机制。nginx内存管理进一步的描述如下:对每一个连接,内存缓冲区动态分配、链接、用于存储和操作请求和响应的头以及主体、然后释放连接。注意到这一点是非常重要的:nginx 试图尽可能避免在内存中复制数据,大多数数据传递使用指针而非调用 memcpy

再深入一些,当一个模块生成响应时,检索的内容放入一个内存缓冲区,然后此内存缓冲区被添加到一个缓冲区链。此缓冲区链进行后续的处理工作。nginx 的缓冲区链之所以十分复杂,是因为有几种处理情景因模块类型而异。比如,在实现一个主体过滤模块时,精确的管理缓冲区是相当棘手的一件事情。这样的模块一次只能操作一个缓冲区(),它必须要决定是否要重写输入缓冲区、用新分配的缓冲区替换当前

的缓冲区、或者在缓冲区之前或之后插入一个新的缓冲区。更复杂一些的情况,有时候一个模块将接收多个缓冲数据导致该模块在一些必要处理操作上会持有不完整的缓冲区链。然而,目前nginx 只提供了一个低级的API用于操作缓冲区链,因此在实现第三方模块之前开发人员应该熟悉nginx这部分特性。

以上这些需要注意的是,在连接的整个生命周期中,都为其分配了内存缓冲区;因此要为长期连接保留一些额外的内存。然而,保留一个空闲的持久连接,nginx仅仅使用了 550 字节的内存。在未来版本的 nginx 中,一些可能的优化:可复用、长

期连接共享内存缓冲区。

nginx 分配器池负责管理内存分配。共享内存被用于:接受互斥锁、缓存元数据、SSL会话缓存、和带宽管理(限制)有关的信息。 nginx 实现了slab分配器用于管理共享内存分配。为了能够同时安全使用共享内存,nginx 提供了许多锁定机制(互斥锁和信号量)。为了组织复杂的数据结构,nginx还提供了红黑树的实现。 红黑树用来保存共享内存中的缓存元数据,跟踪非正则表达式地址定义和一些其他任务。

遗憾的是,从未使用过一个一致且简单的方式描述过上面所说的内容,为nginx进行第三方扩展开发是一项相当复杂的工作。虽然nginx内部有一些很好的文档-----例如, Evan Miller编写的文档-----这些文档是经过巨大的逆向工程努力产生的,而 nginx模块的实现仍然有黑色艺术性。

不管与第三方模块开发相关的困难,nginx用户社区最近出现很多有用的第三方模块。例如,nginx嵌入Lua解释器模块, 负载均衡的附加模块, 完全支持WebDAV 高级高速缓存控制以及本章作者鼓励和将来支持的其他有趣的第三方工作。

 

(未完,待续。。。)

 

1. 本文由mathew翻译,程序员学架构校审

2. 本文译自The Architecture of Open Source Applications

3. 转载请务必注明本文出自程序员学架构(微信号:archleaner )

4. 更多文章请扫码:


 

 

 

 

  • 大小: 44 KB
2
1
分享到:
评论

相关推荐

    linux下nginx安装、配置实战

    本篇将详细介绍如何在Linux系统上安装Nginx,以及进行基本的配置实践。 首先,我们需要了解Nginx的安装过程。在大多数Linux发行版中,可以通过包管理器来安装Nginx。例如,在Ubuntu或Debian系统中,可以使用`apt-...

    nginx的各项详细配置-超多注释

    Nginx配置项详解 - **server_name**: 指定服务器域名,可以是多个,支持通配符。 - **root**: 设置网站根目录,用于定位静态资源。 - **index**: 指定默认首页文件,如"index.html index.htm"。 - **listen**: ...

    实战Nginx及基础配置与管理

    在学习Nginx配置与管理之前,首先需要了解其基本概念和用途。Nginx在设计之初就非常注重高并发连接的处理,采用了基于事件驱动的架构模式,而且因为其代码的模块化,可以轻松地实现功能的扩展。Nginx的处理速度和高...

    Nginx动态配置conf

    4. **使用配置管理工具**:如Ansible、Chef、Puppet等自动化工具,可以自动化地更新Nginx配置,并确保配置一致性。这些工具通常会在更新配置后发送`HUP`信号给Nginx。 5. **配置文件监控**:通过inotify等文件系统...

    nginx转发sftp、ftp的配置

    - **安全性考量**:考虑到安全性问题,建议仅在受信任的网络环境中使用此配置,同时加强对Nginx配置的安全性审查和日志监控。 - **性能优化**:根据实际情况调整 `proxy_connect_timeout` 和 `proxy_timeout` 参数,...

    【Nginx】Windows平台下配置Nginx服务实现负载均衡.doc

    #### 三、Nginx安装与配置 1. **安装Nginx:** 下载完成后,在Windows环境下解压Nginx压缩包即可完成安装。 2. **启动Nginx:** 可以通过命令行运行`nginx.exe`或`start nginx`命令启动Nginx服务。启动后,在浏览器...

    nginx配置tomcat

    总结来说,通过Nginx配置多个Tomcat实例,可以实现高可用性和负载均衡,提升Web服务的性能和稳定性。这个方案在实际应用中非常常见,尤其对于大型的Java Web应用,能够有效管理和扩展服务架构。

    docker下载nginx镜像并配置,然后通过公网ip访问

    系统中具有docker环境(如果没有的话,可以查看我的另一篇文章docker的安装https://blog.csdn.net/weixin_42431676/article/details/105291832) 执行命令: docker pull nginx //从docker自带的源把nginx的镜像...

    Nginx安装配置

    本篇文章将详细讲解如何安装Nginx以及对其进行基本配置。 首先,我们需要在Linux系统上安装Nginx。通常,我们可以使用包管理器进行安装,例如在Ubuntu或Debian上: ```bash sudo apt update sudo apt install ...

    Nginx 1.11.8 安装与配置

    在本篇指导手册中,我们将详细介绍如何在CentOS 6.6 64位系统上安装和配置Nginx版本1.11.8,包括安装编译工具及库文件、安装PCRE(Perl Compatible Regular Expressions)以及配置和安装Nginx。以下是详细步骤: ...

    nginx配置文件

    **Nginx配置文件详解** Nginx是一款高性能的HTTP和反向代理服务器,广泛应用于Web服务领域。其配置文件是Nginx的核心部分,它决定了Nginx如何响应请求和处理网络流量。本篇文章将深入探讨Linux环境下Nginx的配置...

    nginx优化配置,搭建高性能服务器

    在Nginx配置文件中,通过`location`指令指定PHP文件的处理方式,使用`fastcgi_pass`指向下述FastCGI服务地址。 2. **FastCGI参数**:`fastcgi_param`用于传递环境变量给FastCGI,如`SCRIPT_FILENAME`表示请求的脚本...

    nginx-vhost-conf.zip_nginx_nginx虚拟机配置

    本篇文章将深入探讨如何通过Nginx配置文件来设置虚拟主机,特别关注如何实现Nginx运行PHP文件。 ### 1. Nginx虚拟主机基础 虚拟主机是Nginx中的一项核心特性,它允许我们基于域名或者IP的不同端口,将不同的请求...

    Linux配置nginx为服务

    总结起来,配置Nginx在Linux上作为服务,主要涉及下载源码、编译安装、创建启动脚本和服务文件,以及根据需求定制Nginx配置文件。通过熟练掌握这些步骤,你可以灵活地部署和管理Nginx服务器,满足各种Web服务需求。

    nginx+rtmp服务器配置

    本篇文章将详细介绍如何在Windows操作系统上配置Nginx+RTMP服务器,并提供相关文档和配置文件的使用指南。 首先,你需要下载Nginx及其RTMP模块。Nginx可以从其官方网站获取,而RTMP模块是由arut开发的,可以从...

    nginx与php分别部署在不同的主机上配置方法

    在本篇文章中,我们将详细介绍如何将 Nginx 与 PHP 分别部署在不同的主机上,以实现 Web 应用程序的高效运行。这种配置方法可以提高 Web 应用程序的性能、安全性和可维护性。 Nginx 配置 首先,我们需要配置 Nginx...

    Nginx配置防盗链的完整步骤

    编辑Nginx配置文件 打开Nginx的配置文件(通常是`/etc/nginx/nginx.conf`或`/usr/local/nginx/conf/nginx.conf`),找到`http`或`server`块,并在其中添加一个针对特定文件类型的location块,例如: ```nginx ...

    基于CentOS 7.6 配置Nginx + Tomcat

    在本篇文章中,作者介绍了如何在CentOS 7.6上配置Nginx和Tomcat,使得Nginx可以作为反向代理服务器将不同路径的HTTP请求转发给不同的Tomcat实例。这种方式可以用来部署多个Web应用,同时还可以通过Nginx进行负载均衡...

Global site tag (gtag.js) - Google Analytics