了解 Nginx 基本概念

前言

本篇是我学习 Nginx 的一些笔记,主要内容讲述了一些了解 Nginx 需要的基本概念。然后探讨一下 Nginx 的模块化的组织架构,以及各个模块的分类、工作方式、职责和提供的相关指令。

主要达到以下目的:

  1. 了解 Nginx 的大概运行原理
  2. 了解 Nginx 的基本概念
  3. 知道怎么看官方文档。

关于Nginx

Nginx 是一款面向性能设计的 HTTP 服务器,能反向代理 HTTP,HTTPS 和邮件相关(SMTP,POP3,IMAP)的协议链接。并且提供了负载均衡以及 HTTP 缓存。
它的设计充分使用异步事件模型,削减上下文调度的开销,提高服务器并发能力。
采用了模块化设计,提供了丰富模块的第三方模块。

所以关于 Nginx,有这些标签:「异步」「事件」「模块化」「高性能」「高并发」「反向代理」「负载均衡」

基本概念

进程模型

Nginx 的进程是使用经典的「Master-Worker」模型。Nginx在启动后,会有一个 master 进程和多个 worker 进程。

master 进程主要用来管理 worker 进程,包含:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动重新启动新的 worker 进程。

worker
进程主要处理基本的网络事件,多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。需要注意的是,每个
Worker 只有主线程,即所谓的「单线程」。一个请求,只可能在一个 worker 进程中处理,一个 worker
进程,不可能处理其它进程的请求。

worker
进程的个数是可以设置的,一般会设置与机器 cpu 核数一致,这里面的原因与 nginx 的进程模型以及事件处理模型是分不开的。nginx
为了更好的利用多核特性,提供了 cpu 亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来 cache
的失效。更多的 worker 数,只会导致进程来竞争 cpu 资源。

事件模型

Nginx 对于事件,以「异步非阻塞」方式来实现。

异步和非异步,阻塞和非阻塞是两组不同的概念,前者更多对于应用程序而言,而后者更多对于 CPU 来说:

  1. 异步:执行一个动作之后,可以去操作别的操作,然后等待通知再回来执行刚才没执行完的操作。
  2. 非异步(同步):执行一个操作之后,等待结果,然后才继续执行下面的操作。
  3. 阻塞:给 CPU 传达任务之后,一直等待 CPU 处理完毕(即使会产生I/O),然后才执行下面操作。
  4. 非阻塞:给 CPU 传达任务之后,继续处理后面的操作,隔段时间再来询问之前的操作是否完成。这样的及过程也叫「轮询」

Nginx 的「异步非阻塞」方式,具体到系统调用的话,就是像 select/poll/epoll/kqueue 这样的系统调用。它们提供了一种机制,让你可以同时监控多个事件,调用他们是阻塞的,但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。

epoll 是在 Linux 上关于事件的实现,而 kqueue 是 OpenBSD 或 FreeBSD 操作系统上采用类似 epoll 的事件模型。

所以重点讲解一下 epoll 的模型:

该方案给是 Linux 下效率最高的 I/O 事件通知机制,在进入轮询的时候如果没有检查到 I/O 事件,将会进入休眠,直到事件将它唤醒。它是真实利用了事件通知、执行回调的方式,而不是遍历查询,所以不会浪费 CPU,执行效率较高。

反向代理

要了解「反向代理」,首先需要知道什么是「代理服务器」和「正向代理」

代理服务器

在网络中,客户端发起一个请求,获取服务器端的资源。它们之间并不是建立一条直接的通道,而是被代理服务器所转发。

代理服务器作为网络中的媒介将互联网上获取的资源返回给相关的客户端。我们通常所说的代理,一般都指的是「正向代理」,是相对于客户端来说的。比方说我链接了一个
VPN,我访问 Google 的时候,客户端发起的请求到了 VPN,VPN 帮忙转发请求 Google 的服务器,然后把 Google
响应返回给客户端。这个过程,VPN 就充当了「正向代理服务器」的角色。

反向代理

和「正向代理」不同,「反向代理」的说法面向于服务器端。一个客户端请求来到代理服务器,代理服务器根据客户端的请求的不同而把请求转发到不同的服务器,这个过程在「负载均衡」中,也会发生两个一样的请求,会转发到完全不一样的服务器中的情况。

「正向代理」是「负载均衡」实现的前提,正因为代理服务器有了解析请求,分发请求的能力,才能实现负载均衡,降低每一台服务器的负荷。利用「反向代理」,除了实现负载均衡,还可以实现诸如:SSL 加密,静态内容缓存,gzip 压缩,减速上传,安全等功能

负载均衡

负载均衡(Load balancing)是一种计算机网络技术,用来在多个服务器中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。

使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务的实现可以通过软件和硬件来实现。

负载均衡的分发,一般都会有多套算法来处理分发问题。

连接 Connection

在 nginx 中 connection 就是对 tcp 连接的封装,其中包括连接的 socket,读事件,写事件。利用 nginx 封装的 connection,我们可以很方便的使用 nginx 来处理与连接相关的事情,比如,建立连接,发送与接受数据等。

而 nginx 中的 http 请求的处理就是建立在 connection 之上的,所以 nginx 不仅可以作为一个 web 服务器,也可以作为邮件服务器。当然,利用 nginx 提供的 connection,我们可以与任何后端服务打交道。

最大连接数

在nginx中,每个进程会有一个连接数的最大上限,这个上限与系统对fd的限制不一样。

在操作系统中,通过
ulimit -n,我们可以得到一个进程所能够打开的 fd 的最大数,即 nofile,因为每个socket连接会占用掉一个
fd,所以这也会限制我们进程的最大连接数,当然也会直接影响到我们程序所能支持的最大并发数,当 fd 用完后,再创建 socket 时,就会失败。

nginx 通过设置worker_connectons来设置每个进程支持的最大连接数。如果该值大于 nofile,那么实际的最大连接数是 nofile,nginx 会有警告。

nginx 在实现时,是通过一个连接池来管理的,每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx 会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。

所以,一个 nginx 能建立的最大连接数:worker_connections * worker_processes,如果当 nginx 作为反向代理的话,因为一个请求 nginx 要建立客户端和服务器的请求,所以最大连接数是:worker_connections * worker_processes / 2

请求 Request

在 nginx 中我们指 http 请求,具体到 nginx 中的数据结构是ngx_http_request_t。它是对一个 http 请求的封装,nginx 通过ngx_http_request_t来保存解析请求与输出响应相关的数据。一个 http 请求,包含请求行、请求头、请求体、响应行、响应头、响应体。

一般性的网络请求处理过程是:

  1. 客户端会发送请求过来。
  2. 然后我们读取一行数据,分析出请求行中包含的 method、uri、http_version 信息。
  3. 然后再一行一行处理请求头,并根据请求 method 与请求头的信息来决定是否有请求体以及请求体的长度,然后再去读取请求体。
  4. 得到请求后,我们处理请求产生需要输出的数据,然后再生成响应行,响应头以及响应体。
  5. 在将响应发送给客户端之后,一个完整的请求就处理完了。

而 nginx 处理请求的时候会有一些小小的区别,比如,当请求头读取完成后,就开始进行请求的处理了。

Nginx 处理请求过程

nginx 处理一个请求的抽象概念过程:

  1. request 请求进来
  2. 初始化www1.qixoo.com HTTP Request, 生成 HTTP Request 对象
  3. 处理请求头
  4. 处理请求体
  5. 调用与此请求关联的 handler(根据你URL或者Location配置)
  6. 依次调用各 phase handler 进行处理
    1. 获取 location 配置
    2. 产生适当的响应
    3. 发送 response header
    4. 发送 response body

基本数据结构

nginx 的作者为追求极致的高效,自己实现了很多颇具特色的 nginx 风格的数据结构以及公共函数。比如,nginx 提供了带长度的字符串,根据编译器选项优化过的字符串拷贝函数 ngx_copy 等。

ps: 下横线分割是C语言的变量名风格

Data Structure Description
ngx_str_t 字符串封装
ngx_pool_t 提供一种机制,帮助管理一系列的资源(内存,文件)
ngx_array_t 数组结构
ngx_chain_t 主要用于模块之间数据传递的链表实现
ngx_buf_t 就是 ngx_chain_t 链表的每个节点的实际实现,代表某种具体的数据。
ngx_list_t list 数据结构的实现,以及增强
ngx_queue_t 实现的双向链表
ngx_hash_t hash 表的实现
ngx_hash_wildcard_t 为处理带有通配符域名的匹配问题实现的 hash 表结构
ngx_combinded_t 在于提供一个方便的容器包含三个类型的 hash 表
ngx_hash_keys_arrays_t 用于构建其他类型的 hash 的辅助类

配置

nginx 的配置系统由一个主配置文件和其他一些辅助的配置文件构成。这些配置文件均是纯文本文件,全部位于 nginx 安装目录下的 conf 目录下。

指令由 nginx 的各个模块提供,不同的模块会提供不同的指令来实现配置。
指令除了 Key-Value 的形式,还有作用域指令。

nginx.conf 中的配置信息,根据其逻辑上的意义,对它们进行了分类,也就是分成了多个作用域,或者称之为配置指令上下文。不同的作用域含有一个或者多个配置项。

下面的这些上下文指令是用的比较多:

Directive Description Contains Directive
main nginx 在运行时与具体业务功能(比如 http 服务或者 email 服务代理)无关的一些参数,比如工作进程数,运行的身份等。 user, worker_processes, error_log, events, http, mail
http 与提供 http 服务相关的一些配置参数。例如:是否使用 keepalive 啊,是否使用 gzip 进行压缩等。 server
server http 服务上支持若干虚拟主机。每个虚拟主机一个对应的 server 配置项,配置项里面包含该虚拟主机相关的配置。在提供 mail 服务的代理时,也可以建立若干 server. 每个 server 通过监听的地址来区分。 listen, server_name, access_log, location, protocol, proxy, smtp_auth, xclient
location http 服务中,某些特定的 URL 对应的一系列配置项。 index, root
mail 实现 email 相关的 SMTP/IMAP/POP3 代理时,共享的一些配置项(因为可能实现多个代理,工作在多个监听地址上)。 server, http, imap_capabilities

模块

nginx

将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块,进行处理。每个模块实现特定的功能。例如,实现对请求解压缩的模块,实现
SSI 的模块,实现与上游服务器进行通讯的模块,实现与 FastCGI 服务进行通讯的模块。
模块分三类:

  1. 核心模块
  2. 辅助模块
  3. 第三方模块

根据官方文档排版,辅助模块还分了以下几类:

  1. http
  2. mail
  3. stream

而根据其功能可以分成这几大类:

  1. handler 模块
    此类型的模块也被直接称为 handler 模块。主要负责处理客户端请求并产生待响应内容,比如 ngx_http_static_module 模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。
  2. filter 模块
    过滤响应头和内容的模块,可以对回复的头和内容进行处理。它的处理时间在获取回复内容之后,向用户发送响应之前。
  3. upstream 模块
    upstream 模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream 模块是一种特殊的 handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。
  4. load balance 模块
    负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器

结尾

本文讲述了 Nginx 的一些基本概念。

Nginx
是线程模型是 Master-Worker 模式的,每个 worker
是单线程的,也就是处理请求是单线程处理的。而单线程并发的事件模型是「异步非阻塞 I/O」模型。并且讲述了「反向代理」「负载均衡」的概念,这是
nginx 能高性能处理高并发的原因之一。Nginx 对于网络请求是有 Connection 和 Request 的概念和封装的。

Nginx 的源码组织架构是模块化的,不同的模块实现不一样的职责,然后它们被连接起来一起干一件大事,知道模块有哪些分类,可以让我们知道怎么查找官方文档。
在没有看过有哪些指令,哪些指令有什么功能之前,是不能完全知道 nginx 提供什么样的功能的,那就抱着,那就抱着「能想到的别人都想到并实现了」的想法来使用 nginx 吧。Nginx 作为一个代理服务,在中间想做什么都可以啦。

时间: 2024-09-30 20:00:50

了解 Nginx 基本概念的相关文章

nginx模型概念和配置文件结构

一. nginx模型概念: Nginx会按需同时运行多个进程: 一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等. 所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信. 主进程以root用户身份运行,而worker.cache loader和cache manager均应以非特权用户身份(user配置项)运行. 主进程主要完成如下工作: 1. 读取并验正配置信

Nginx(三):Nginx基本概念以及用法

目录结构 Nginx conf   配置目录 nginx.conf 主配置文件 fastcgi.conf fastcgi的配置文件 mime.types 支持的mime.types资源类型 sbin   启动目录 nginx. 默认启动nginx的二进制文件 logs  日志目录 access.log 默认访问日志文件 error.log    默认错误日志文件 nginx.pid   nginx的pid文件 html 静态页面目录 index.html 默认首页文件 50x.html    错

Nginx之概念和简介

Nginx是什么? 代理服务器,处于客户端和服务器端之间的一台服务器,不负责处理请求. 主要作用是什么? 1.负载均衡: 高并发场景下,Nginx代理服务器按一定规则将请求分发,从而使服务器能有条不紊地处理请求: 2.反向代理: 处于客户端和服务器端之间的一台服务器,不负责处理请求,向客户端屏蔽服务器端信息: 特点: 1.占CPU.内存较小:  2.但和Apache相比,它不太擅长处理动态资源,对平台有使用上的局限,不太适用于 windows系统: 经典架构: linux+Nginx+mysql

[转自SA]浅谈nginx的工作原理和使用

nginx apache 简单对比 nginx 相对 apache 的优点: 轻量级,同样起web 服务,比apache 占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的,而 apache 则是阻塞型的,在高并发下 nginx 能保持低资源低消耗高性能 高度模块化的设计,编写模块相对简单 社区活跃 配置简洁 apache 相对nginx 的优点: rewrite ,比 nginx 的 rewrite 强大 模块超多 少 bug ,nginx 的 bug 相对较多 超稳定 配置复杂

Nginx虚拟主机配置实践之nginx访问同一个地址方法(二)

Nginx虚拟主机配置实践之nginx访问同一个地址方法(二) 一.虚拟主机别名介绍 虚拟主机别名就是为虚拟主机设置除了主域名以外的另一个或多个域名名字,这样就能实现用户访问的多个域名对应于同一个虚拟主机网站的功能.在生产环境中,以www.afeilinux.com域名的虚拟主机为例,为其增加一个别名afeilinux.com时,在该域名出现的网站内容和访问www.afeilinux.com得到的结果是一样的. 二.实施方法 第一种方法:Nginx虚拟主机的别名配置 更改wtf.conf配置文件

nginx平台初探(100%)

http://tengine.taobao.org/book/chapter_02.html 初探nginx架构(100%)¶ 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来初识一下nginx框架吧. nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程.我们也可以手动地关掉后台模式,让nginx在前台运行,并且通过配置让nginx取消master进程,从而

Nginx实现tomcat集群进行负载均衡

一.背景 随着业务量和用户数量的激增,单一的tomcat部署应用已经无法满足性能需求,而且对于每次发布项目期间服务不可用的问题也凸显,既然出现了这个问题,那么我们本文就借助nginx来完美的解决这个问题. 二.基本概念 1.说明:关于Nginx的概念和介绍以及Centos7下安装步骤,请移步:Centos7安装Nginx实战 2.正向代理和反向代理 假设我们给定客户端A.代理服务器B.以及最终服务器C 正向代理:代理服务器B来代替客户端A来访问最终服务器C并将最终结果转发给客户端A,站在客户端A

nginx -- nginx平台初探(100%)

初探nginx架构(100%) 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来初识一下nginx框架吧. nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程.我们也可以手动地关掉后台模式,让nginx在前台运行,并且通过配置让nginx取消master进程,从而可以使nginx以单进程方式运行.很显然,生产环境下我们肯定不会这么做,所以关闭后台模式,一般是

使用Nginx实现Tomcat集群负载均衡

一.背景 随着业务量和用户数量的激增,单一的tomcat部署应用已经无法满足性能需求,而且对于每次发布项目期间服务不可用的问题也凸显,既然出现了这个问题,那么我们本文就借助nginx来完美的解决这个问题. 二.基本概念 1.说明:关于Nginx的概念和介绍以及Centos7下安装步骤,请移步:Centos7安装Nginx实战 2.正向代理和反向代理 假设我们给定客户端A.代理服务器B.以及最终服务器C 正向代理:代理服务器B来代替客户端A来访问最终服务器C并将最终结果转发给客户端A,站在客户端A