[TOC]
1、HTTP 介绍:
1.1 简介
HTTP协议是超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
1.2 HTTP 工作原理
HTTP(超文本传输协议)是应用层协议。它是整个数据通信的基础,基于请求/响应模式,客户端与服务器之间通过互相发送报文来通信,工作流程如下:
- 建立连接: 客户端(通常是Web浏览器)和服务器之间首先需要建立
一个TCP连接。这是因为HTTP协议通常承载于TCP协议之上,确保数据的可靠传输。 - 发送请求: 客户端向服务器发送一个HTTP请求,这个请求包含请求行、请求头和请求体。请求行包括请求方法(如GET或POST),所请求资源的URL以及HTTP协议版本。请求头包含附加信息,比如用户代理、Cookie等。如果是POST请求,请求体中还会包含提交的数据。
- 服务器响应: 服务器接收到请求后,根据请求内容和服务器上的资源生成HTTP响应。响应同样由三部分组成:状态行、响应头和响应体。状态行包括HTTP状态码和原因短语,响应头包含服务器类型、内容类型等附加信息,响应体则携带着实际返回给客户端的数据,例如HTML页面或图片等。
- 传输数据: 服务器将响应通过之前建立的TCP连接发送回客户端。客户端收到响应后,浏览器会根据返回的内容类型渲染出相应的页面或者处理其他类型的数据。
- 断开连接: 数据传输完成后,客户端和服务器关闭TCP连接并释放相关资源。由于HTTP是无状态的,每次通信都是独立的,不会默认保存之前的请求或响应信息。如果需要跟踪用户的状态,通常会使用Cookie或会话机制来实现。
1.3 常见的web服务器
Apache HTTP Server:也被称为阿帕奇服务器,它是最广泛使用的Web服务器之一。作为一个开源项目,Apache可以运行在各种操作系统上,包括Unix、Windows和Linux。它以稳定性、可扩展性和安全性著称,在处理大量请求时表现出色。
Nginx:Nginx是一个高性能的HTTP和反向代理服务器,它以处理高并发连接而闻名。Nginx消耗的资源较少,因此在负载较高的情况下仍能保持较低的内存和CPU使用率。
Tomcat:虽然Apache Tomcat主要是作为Java 容器,但它也可以作为独立的Web服务器使用,尤其适合需要动态生成内容的Web应用。

HTTPD和NGINX的区别
处理客户端请求:Apache采用同步多进程模型,为每个请求创建一个新线程。这意味着在高并发场景下,Apache会为每个连接分配一个独立的进程或线程,这可能会导致资源使用量随着并发数的增加而线性增长。Nginx则采用异步非阻塞方式,使用事件驱动架构在一个线程中处理多个请求。这种模型使得Nginx在处理大量并发连接时更为高效,尤其是在静态内容服务和反向代理方面。
性能和稳定性:Nginx因其轻量级和高效的事件驱动架构,在性能上通常优于Apache。它特别适用于需要处理高并发请求的场景。而Apache在低至中等流量的环境中表现良好,其模块化设计和丰富的功能使得它在稳定性和模块化方面有一定的优势。
1.4 HTTP注意事项:
无连接性:HTTP通常是一种无连接协议,这意味着每次连接只处理一个请求。一旦服务器处理完客户端的请求并且客户端接收到响应,连接就会断开。这种机制有助于节省传输时间,但同时也意味着每次新的请求都需要建立新的连接。无状态性:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。缓存控制:为了提高加载速度和减少带宽消耗,HTTP提供了缓存机制。持久连接:虽然HTTP/1.1默认是持久连接(也称为HTTP Keep-Alive),但这需要Web服务器和客户端的支持。持久连接可以减少TCP连接的建立和关闭所带来的开销,提高传输效率。
1.5 HTTP 消息结构
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个HTTP”客户端”是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。
一个HTTP”服务器”同样也是一个应用程序(通常是一个Web服务,如Nginx、Apache Web服务器),通过接收客户端的请求并向客户端发送HTTP响应数据。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。用来标识互联网上某一资源的地址,通常用于访问网页、文件、图片等。
协议:例如,
http://或https://。域名:例如,
www.tabke.love。路径:指向具体的资源,例如,
/tanke/tanke.html。查询参数(可选):用于传递附加信息,例如,
?id=123&name=test。
https://www.kengni.com:80/tanke.html?id=123&name=test
1.6 客户端请求消息
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
(https://www.baidu.com/s?ie=UTF-8&wd=QQ%E9%9F%B3%E4%B9%90,此链接可看请求头的内容)


- GET /wzt/favicon.ico HTTP/1.1:表示请求方法为GET,请求的资源路径为/wzt/favicon.ico,使用的HTTP协议版本为1.1。
- Accept: image/avif,image/webp,image/apng,image/svg+xml,image/,/*;q=0.8:表示客户端接受的图像类型和质量。
- Accept-Encoding: gzip, deflate:表示客户端接受的压缩格式。
- Accept-Language: zh-CN,zh;q=0.9:表示客户端接受的语言和优先级。
- Connection: keep-alive:表示客户端希望保持连接,以便进行后续请求。
- Cookie: _ga_C569W2WCN6=GS1.1.1712754252.1.0.1712754252.0.0.0; …:表示客户端发送的Cookie信息,用于服务器识别用户。
- Host: www.mobiletrain.org:表示请求的目标主机名为www.mobiletrain.org。
- Referer: http://www.mobiletrain.org/?pinzhuanbdtg=biaoti:表示请求的来源页面URL。
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36:表示客户端的浏览器信息和操作系统信息。

这段响应信息是HTTP协议的一部分,它包含了服务器对客户端请求的响应。以下是各个字段的含义:
- HTTP/1.1 200 OK:这是HTTP协议的版本和状态码,表示请求成功。
- Server: nginx:服务器使用的是nginx。
- Date: Wed, 10 Apr 2024 13:04:29 GMT:响应生成的时间。
- Content-Type: image/x-icon:响应的内容类型是图像,具体格式为.ico。
- ETag: “63478391-47e”:ETag是用于缓存控制的标识符。
- Access-Control-Allow-Origin: *:允许任何来源访问该资源。
- Accept-Ranges: bytes:服务器接受字节范围请求。
- X-Cache-Lookup: Cache Miss:表示请求的资源未在缓存中找到。
- Last-Modified: Thu, 13 Oct 2022 03:18:41 GMT:资源的最后修改时间。
- Content-Length: 1150:响应内容的长度,单位为字节。
- X-NWS-LOG-UUID: 3120119176189980775:这可能是一个自定义的头部字段,用于日志记录。
- Connection: keep-alive:表示客户端和服务器之间的连接将保持活动状态,以便进行后续请求。
1.7 服务器响应消息
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

*实例 *
下面实例是一点典型的使用GET来传递数据的实例:
客户端请求:
1 | Connected to www.testpm.cn (47.244.247.240) port 80 (#0) |
服务端响应:
1 | < HTTP/1.1 200 OK #请求返回的状态码 |
1.8 描述HTTP 的工作过程
HTTP协议的工作过程可以通过一个简单的例子来解释,例如,当你在浏览器中输入一个URL(例如:www.qf.com/test/index.html?name=qf&age=18)并按下回车键时,背后发生了什么?
- 浏览器首先会解析你输入的URL,确定你要访问的是哪个网站,以及具体的页面路径。在这个例子中,你要访问的网站是www.qf.com。
- 浏览器会向DNS服务器发送一个请求,要求解析www.qf.com的IP地址。DNS服务器会返回对应的IP地址。
- 浏览器会向这个IP地址发送一个HTTP GET请求。这个请求包含了一些信息,例如你的浏览器类型,你接受的语言等。
- 服务器收到这个HTTP请求后,会解析这个请求,确定你要获取的是哪个页面。然后,服务器会从硬盘中找到这个页面,然后返回一个HTTP响应。这个响应包含了页面的内容,以及一些元信息,例如页面的类型,编码方式等。
- 浏览器收到HTTP响应后,会解析这个响应,然后将页面的内容显示在浏览器中。
1.9 HTTP 请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
重点方法:
GET:用于向服务器请求获取某个资源。(获取一个index.html页面)
POST:用于向服务器提交数据,通常用于表单提交、文件上传等场景。(会产生新的数据)
PUT:用于向服务器更新或保存某个资源,通常用于上传文件、更新数据等场景。(覆盖/更新文件、图片等,不会产生新的数据)
DELETE:用于向服务器删除某个资源,通常用于删除文件、删除数据等场景。

GET和POST是HTTP协议中两种常见的请求方法,它们的工作细节如下:
GET请求是最常见的请求方法,通常用于获取资源。
GET请求的参数会附加在URL之后,通过问号(?)分隔,参数之间用&符号连接。例如,http://www.qf.com/index.html?name=John&age=22。这种方式的缺点是传输数据的大小有限制(因为浏览器对URL的长度有限制),并且不适合传输敏感信息(如密码),因为参数会直接暴露在URL中。
POST请求通常用于提交数据。
POST请求将参数放在HTTP请求的主体中(HTTP的请求主体(Request Body)是HTTP请求消息的一部分,用于在客户端向服务器发送请求时附带额外的数据。这些数据可以是文本、JSON、XML或其他格式,具体取决于请求的类型和客户端与服务器之间的约定。),而不是URL中。POST请求没有对传输数据的大小进行限制,而且可以传输任何类型的数据,包括二进制数据。因此,POST请求通常用于提交表单数据。
下面是一个GET请求和POST请求的例子:
GET请求示例:
1 | GET /index.html?name=maoxiansheng&age=18 HTTP/1.1 |
POST请求示例:
1 | POST /api/users HTTP/1.1 |
在GET请求示例中,参数name=John&age=22附加在URL之后。在POST请求示例中,参数"name": "qianfeng",
"email": "qianfeng@1000phone.com"放在HTTP请求的主体中。
需要注意的是,虽然POST请求在传输大量或敏感数据时更安全,但无论是GET还是POST,都不能提供真正的安全性。为了保护数据的安全,应该使用HTTPS协议,它可以对传输的数据进行加密。
1.10 HTTP 状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
下面是常见的HTTP状态码:
- 200 - 请求成功,表示成功处理了请求的状态代码。
301 - 表示被请求的资源已永久移动到新的位置。当服务器返回301状态码时,它会告诉客户端(如浏览器)请求的资源已被永久移动到另一个URL,客户端在接收到301响应后,应该使用新的URL发起后续的请求。
比如建设一个网站后,将网站的url变换了,重新申请一个域名,但是希望之前的用户访问之前url仍然可以访问到,就可以做一个重定向新的url下面。比如京东最早域名www.360buy.com名重定向到现在www.jd.com
- 302 - 302状态码表示临时重定向。当服务器收到请求时,如果资源暂时不可用或已经移动到其他位置,服务器会返回一个HTTP 302状态码,客户端会自动发送一个新的请求到这个新的URL地址,以获取所需的资源。
404- 表示客户端请求的资源在服务器上不存在或无法找到。当浏览器或客户端尝试访问一个网页或资源,但服务器无法找到与请求URL对应的文件或页面时,就会返回这个错误。HTTP 404错误可能由以下原因引起:
- URL错误:输入的URL可能有误,比如拼写错误、大小写错误、路径错误或者参数错误等。
- 页面被删除或移动:请求的页面可能已经被删除,或者移动到了其他位置,而URL没有相应地更新。
- 服务器配置问题:服务器的配置可能存在问题,导致无法正确解析URL或找到相应的资源。
- 资源不存在:请求的资源(如文件、图片等)可能从未在服务器上创建或已被删除。
403- 表示服务器理解了客户端的请求,但是拒绝执行此请求。这通常意味着客户端没有访问所请求资源的权限。HTTP 403错误可能由多种原因引起,包括:- 权限不足:服务器可能要求客户端提供有效的身份验证凭据,以便确定其是否具有访问请求资源的权限。如果客户端没有提供正确的凭据或凭据无效,服务器将返回403状态码。
- IP地址限制:服务器可能根据IP地址对访问进行限制。如果客户端的IP地址被服务器列入黑名单或没有被列入白名单,服务器将返回403状态码。
- 文件权限设置:服务器上的文件或目录可能设置了访问权限,如果客户端没有足够的权限访问这些文件或目录,服务器将返回403状态码。
503-错误表示服务不可用,这通常意味着服务器暂时无法处理请求。- 服务器过载:当服务器接收到的请求过多,超过了其处理能力时,就可能导致服务器过载。这可能是由于服务器硬件性能不足、网络带宽不足或应用程序代码存在问题等原因引起的。
- 服务器维护:服务器可能需要定期进行维护和升级,以保持其稳定性和性能。在这种情况下,服务器可能会暂时关闭,以便进行必要的更新和修复。
- 错误的服务器配置:Web服务器或应用服务器配置错误也可能导致HTTP 503错误。这包括代理服务器的配置错误或应用程序池的错误配置等。
504-也称为“网关超时”(Gateway Timeout)错误,通常发生在作为网关或代理的服务器没有从上游服务器(如另一个代理服务器或Web服务器)收到及时的响应时。这通常意味着代理服务器等待上游服务器的响应时间过长,超出了设定的等待时间阈值。- 上游服务器过载:上游服务器可能由于处理过多的请求或资源不足而无法及时响应代理服务器的请求。
- 网络延迟或故障:代理服务器与上游服务器之间的网络连接可能存在问题,导致请求和响应的传输延迟或失败。
- 上游服务器配置错误:上游服务器的配置可能存在问题,导致它无法正确处理代理服务器的请求。
HTTP状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
- 1xx(信息性状态码) : 这类状态码表示请求已被服务器接收,需要客户端继续操作。
- 2xx(成功状态码) : 这类状态码表示服务器已成功处理了请求。
- 3xx(重定向状态码) : 这类状态码表示需要客户端采取进一步的操作才能完成请求。例如,301 Moved Permanently表示被请求的资源已永久移动到新位置,302 Found表示请求的资源现在临时从不同的URI响应请求。
- 4xx(客户端错误状态码) : 这类状态码表示客户端似乎发生了错误,妨碍了服务器的处理。
- 5xx(服务器错误状态码) : 这类状态码表示服务器在尝试处理请求时发生了错误。

HTTP状态码列表:
| 状态码 | 状态码英文名称 | 中文描述 |
|---|---|---|
| 100 | Continue | 继续。客户端应继续其请求 |
| 101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
| 200 | OK | 请求成功。一般用于GET与POST请求 |
| 201 | Created | 已创建。成功请求并创建了新的资源 |
| 202 | Accepted | 已接受。已经接受请求,但未处理完成 |
| 203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
| 204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
| 205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
| 206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
| 300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
| 301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
| 302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
| 303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
| 304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
| 305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
| 306 | Unused | 已经被废弃的HTTP状态码 |
| 307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
| 400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
| 401 | Unauthorized | 请求要求用户的身份认证 |
| 402 | Payment Required | 保留,将来使用 |
| 403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
| 404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面 |
| 405 | Method Not Allowed | 客户端请求中的方法被禁止 |
| 406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
| 407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
| 408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
| 409 | Conflict | 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突 |
| 410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
| 411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
| 412 | Precondition Failed | 客户端请求信息的先决条件错误 |
| 413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
| 414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
| 415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
| 416 | Requested range not satisfiable | 客户端请求的范围无效 |
| 417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
| 500 | Internal Server Error | 服务器内部错误,无法完成请求 |
| 501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
| 502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
| 503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
| 504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
| 505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
2、Nginx 服务
2.1 Nginx 介绍
Nginx (engine x) 是一个高性能的 HTTP 和反向代理服务,也是一个IMAP/POP3/SMTP服务。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。
创始人伊戈尔·赛索耶夫

2.2 为什么选择 Nginx
Nginx(engine x)是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它最初由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发,自发布以来,因其稳定性、丰富的功能集、简单的配置文件和低系统资源消耗而广受好评。
Nginx的特点包括:
- 高性能:Nginx使用
事件驱动模型,可以同时处理大量的并发连接,而且在高负载和大流量情况下仍然能够保持良好的性能。 - 轻量级:Nginx的代码量较少,占用的内存也较少,使其可以在资源受限的系统中运行,并且在高负载下也不易崩溃。
- 可扩展性:Nginx支持众多的第三方模块,可以根据需要进行自定义开发,实现更多的功能。
- 高度可靠性:Nginx是基于稳定的、成熟的事件驱动架构开发的,能够有效地避免因代码错误或第三方库问题导致的崩溃,从而保证了服务的高可靠性。
- 热部署:Nginx支持在不停止服务的情况下更新配置文件和软件升级,为用户提供了极大的便利。
在功能方面,Nginx具有:
- HTTP代理与反向代理:作为web服务器,Nginx最常用的功能之一是反向代理。它可以根据不同的正则匹配,采取不同的转发策略,并且能够对返回结果进行错误页跳转、异常判断等。如果被分发的服务器存在异常,Nginx可以将请求重新转发给另一台服务器。
- 负载均衡:Nginx提供了多种负载均衡策略,如轮询、加权轮询和ip hash等,以优化请求的分配和处理方式,从而平均分配后端服务器的负载,提高系统的可用性和可靠性。
- Web缓存:Nginx支持对不同的文件做不同的缓存处理。
2.3 IO多路复用
2.3.1 I/O multiplexing【多并发】
- 第一种方法就是最传统的多线程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
多进程并发模型是一种传统的服务器架构模式,它的核心思想是利用操作系统的多进程机制来实现并发处理多个客户端请求。在这种模型中,主进程负责监听客户端的连接请求,一旦接收到新的请求,主进程会通过fork()操作创建一个子进程(线程)来独立处理这个请求。这样,父进程可以继续回到监听状态,等待其他客户端的连接。每个子进程处理完一个请求后就会退出,释放资源。这种模型的优点是可以快速响应客户请求,尤其是在客户与服务器交互频繁的场景下。
然而,这种模型也存在一些缺点:
- 资源消耗:进程是操作系统资源分配的基本单位,每个进程都需要占用一定的内存和CPU资源。在高并发环境下,如果创建大量进程,会导致服务器资源消耗过快,增加服务器负载。

- 第二种方法就是
I/O多路复用(单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因,是尽量多的提高服务器的吞吐能力。I/O多路复用是一种高效处理多个I/O流的技术,它允许单个线程通过记录和跟踪每个流的状态来同时管理多个I/O流,而不是为每个流创建单独的线程。这样做可以提高服务器应用程序的性能,尤其是在需要处理成千上万并发连接的情况下。
在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流。这句话描述的是一种单线程中管理多个I/O流的方法,其中“拨开关”的比喻可能是指通过在多个I/O流之间切换来实现并发处理的方式。这里的“拨开关”可以理解为线程在多个I/O流之间快速切换,检查哪个流准备好进行读或写操作。当一个流准备好时,线程就与之交互(读取数据或发送数据),然后迅速切换到下一个流。这种快速的切换给人的感觉就像是在“拨动开关”,在一个流和另一个流之间来回切换

一个请求到来了,nginx使用epoll接收请求的过程是怎样的?
- 建立监听:Nginx通过epoll创建一个事件监听的集合,这个集合能够同时监控多个网络连接的文件描述符。
- 事件注册:对于每一个进入的连接,Nginx会将其文件描述符注册到epoll中,以便对这些连接进行事件监听。
- 事件检测:epoll机制允许Nginx高效地检测哪些注册的连接有活动(比如数据可读或可写),而不需要像传统的轮询那样检查每个连接。
- 事件处理:一旦某个连接上有数据到来,epoll通知Nginx,然后Nginx可以立即响应该连接,处理传入的数据,例如读取HTTP请求。
- 动态调整:epoll能够动态地添加或移除所监听的文件描述符,这使得Nginx在处理大量并发连接时非常灵活和高效。
- 资源优化:由于不是所有连接在任何时刻都是活跃的,epoll只关注那些真正有事件发生的连接,从而节省了系统资源,提高了性能。
- 非阻塞I/O:Nginx利用epoll实现非阻塞I/O操作,这意味着内核在没有数据可读时不会将进程置于等待状态,而是让其继续执行其他任务。
2.3.2 异步,非阻塞
1 | [root@web01 ~]# ps -aux | grep nginx |

1个master进程,2个work进程
master进程只负责监听用户的请求,但并不处理请求。work进程才处理请求。
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向后端服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker进程才会来接手,这个request才会接着往下走。这就是异步回调。
3、Nginx安装部署和配置管理
3.1 Nginx部署-Yum安装方式
访问nginx的官方网站:http://www.nginx.org/
Nginx版本类型
- Mainline version: 主线版,即开发版
Stable version:最新稳定版,生产环境上建议使用的版本
- Legacy versions: 遗留的老版本的稳定版

1 | >>> 编写nginx yum源文件(稳定版) |
1 | >>> 查看nginx相关信息 |

1 | >>> 查看NGINX版本信息 |
1 | >>> 关闭安全策略 |
浏览器输入ip访问:

3.2 Nginx 编译安装
1 | >>> 安装gcc |
自动化安装NGINX脚本(生产勿用,需要修改其中的相关配置信息)
1 | #>>> NGINX自动化安装脚本 |
1 | #>>> nginx systemd 启动脚本 |
Nginx 编译参数
1 | 查看 nginx 安装的模块 |
3.3 NGINX配置文件详解
- 全局模块
1 | user nobody; |
user nobody;:指定 Nginx 进程运行的用户。worker_processes 1;:指定 Nginx 启动的工作进程数。通常设置为 CPU 核心数。error_log logs/error.log;:指定错误日志文件的路径和日志级别。pid logs/nginx.pid;:指定存储 Nginx 主进程 PID 的文件路径。
- events模块
1 | events { |
worker_connections 1024;:每个工作进程允许的最大连接数。设置为 1024。该参数用于设置每个worker进程允许的最大并发连接数。worker_connections参数用于指定每个Nginx worker进程可以同时处理的最大连接数。在这个例子中,worker_connections- 设置为1024,表示每个worker进程最多可以同时处理1024个连接。通过设置worker_connections,可以限制每个worker进程的负载,避免因过多的并发连接导致服务器资源耗尽或性能下降。
- HTTP模块
1 | http { |
include mime.types;:包含 MIME 类型映射文件,告诉 Nginx 如何处理不同类型的文件。default_type application/octet-stream;:默认的 MIME 类型,如果没有其他匹配的类型,使用这个。log_format和access_log:指定日志格式和访问日志路径。sendfile on;:启用 sendfile 选项,提高文件传输效率。允许在内核级别直接将文件数据从磁盘传输到网络,而不需要通过用户空间的缓冲区。这样可以减少CPU和内存的开销,提高文件传输的效率。通过将sendfile设置为on,可以启用sendfile选项,从而优化文件传输的性能。这对于大文件传输或者需要快速响应的场景非常有用。tcp_nopush on;:提高网络传输效率。允许在发送HTTP响应时控制数据包的发送方式。当TCP_NOPUSH选项被设置为on时,Nginx会在发送HTTP响应头之后立即发送响应体的数据,而不是等待整个响应体都准备好后再一起发送。这样可以减少延迟,提高传输效率。keepalive_timeout 65;:保持连接超时时间,设置为 65 秒。允许在一个TCP连接上发送多个HTTP请求和响应,而不需要每次都重新建立连接。通过使用keepalive,可以减少TCP连接的建立和关闭次数,从而提高服务器的性能和效率。gzip on;:启用 gzip 压缩。Gzip 压缩可以显著提高网站性能,通过减少传输数据的大小,加快网页加载速度。
- server模块
1 | server { |
listen 80;:指定虚拟主机监听的端口,设置为 80(HTTP)。server_name localhost;:指定虚拟主机名称。charset koi8-r;:设置字符集。access_log logs/host.access.log main;:指定访问日志路径和格式。
- location 模块
1 | location / { |
location /:匹配根路径。root html;:指定根目录路径为html目录。index index.html index.htm;:指定默认的索引文件。
- 错误页面配置
1 | error_page 500 502 503 504 /50x.html; |
error_page 500 502 503 504 /50x.html;:指定在发生 500、502、503、504 错误时,显示/50x.html页面。location = /50x.html:精确匹配/50x.html,并指定根目录为html。
代理和 FastCGI 配置
FastCGI 是一种改进的CGI协议,通过优化性能和资源利用率,使得Web服务器能够更有效地处理动态内容的生成和处理,特别是在高流量和高并发的网络环境中表现出色。
1 | proxy the PHP scripts to Apache listening on 127.0.0.1:80 |
location ~ \.php$:使用正则表达式匹配以.php结尾的请求。proxy_pass http://127.0.0.1;:将匹配到的请求代理到本地端口80上。location ~ \.php$:使用正则表达式匹配以.php结尾的请求。root html;:设置根目录为html。表示根目录在html文件夹中。fastcgi_pass 127.0.0.1:9000;:将匹配到的请求传递给本地运行的 FastCGI 服务器,该服务器监听在127.0.0.1的端口9000上。fastcgi_index index.php;:使用index.php作为索引文件。fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;:设置SCRIPT_FILENAMEFastCGI 参数,该参数指定了请求的 PHP 脚本文件的路径。$fastcgi_script_name是请求的 URI,/scripts是在服务器根目录中的路径。include fastcgi_params;:包含 FastCGI 参数文件,该文件定义了一组 FastCGI 参数,通常存储在 Nginx 安装目录的conf或conf.d目录中。
当 Nginx 收到一个以
.php结尾的请求时,这个请求将被传递给本地的 FastCGI 服务器进行处理。FastCGI 服务器通常是 PHP-FPM(PHP FastCGI Process Manager),它负责处理 PHP 脚本。Nginx 在这里充当一个 FastCGI 客户端,将请求转发给 FastCGI 服务器,然后将服务器的响应返回给客户端。
- 拒绝访问 .ht 文件
1 | deny access to .htaccess files, if Apache's document root |
location ~ /\.ht:匹配.ht文件。deny all;:拒绝所有访问。被注释掉了。
- HTTPS 服务器
1 | HTTPS server |
listen 443 ssl;:指定服务器监听 443 端口,这是标准的 HTTPS 端口,并启用 SSL 功能。server_name localhost;:指定服务器名称,这里设置为localhost。ssl_certificate cert.pem;:指定服务器的 SSL 证书文件路径。cert.pem是证书文件。ssl_certificate_key cert.key;:指定服务器的 SSL 证书私钥文件路径。cert.key是私钥文件。ssl_session_cache shared:SSL:1m;:启用共享的 SSL 会话缓存,大小为 1MB。这有助于提高 SSL 握手的性能,因为客户端可以重用现有的 SSL 会话。ssl_session_timeout 5m;:设置 SSL 会话超时时间为 5 分钟。ssl_ciphers HIGH:!aNULL:!MD5;:指定允许使用的 SSL 加密套件。HIGH表示高安全性套件,!aNULL排除不带认证的套件,!MD5排除使用 MD5 算法的套件。ssl_prefer_server_ciphers on;:指示服务器优先使用自己的加密套件,而不是客户端的套件顺序。这有助于确保使用强加密。
Nginx配置文件组成部分
- 全局块:这是配置文件的最顶层,用于定义对整个Nginx服务器生效的参数。例如,可以设置工作进程数、错误日志的位置等。全局块中配置的指令作用于整个Nginx服务器,而不是某个特定的server或location。
- events块:位于全局块下面,用来设置与连接处理相关的参数,比如每个工作进程允许的最大并发连接数等。这个块通常用来调整Nginx如何处理网络连接和请求的传输速率。
- http块:包含了所有与HTTP服务相关的设置,如路由匹配、静态文件服务、反向代理和负载均衡等。在http块内部,可以包含http全局块、多个server块以及每个server块中的多个location块。每个server块代表一个虚拟主机的配置,而location块则用于匹配并处理特定的URL请求。
检测nginx配置文件是否正确
1 | [root@localhost ~]# ln -s /usr/local/nginx/sbin/nginx /sbin/ |
通过 nginx 命令控制 nginx 服务
a、常用命令
1 | nginx -c /path/nginx.conf # 以特定目录下的配置文件启动nginx: |
3.4 Nginx 日志文件详解
nginx 日志文件分为 log_format 和 access_log 两部分
log_format 定义记录的格式,其语法格式为
log_format 样式名称 样式详情
配置文件中默认有
1 | log_format main 'remote_addr - remote_user [time_local] "request" ' |
log_format
log_format:定义日志格式。main:这是日志格式的名称。在access_log指令中引用这个日志格式。
remote_addr
$remote_addr:记录客户端的 IP 地址。这个字段表示请求是从哪个 IP 地址发出的。
remote_user
$remote_user:记录客户端通过 HTTP 基本认证的用户名。如果请求没有进行认证,则这个字段为空。
time_local
$time_local:记录请求的本地时间和日期。格式通常为day/month/year:hour:minute:second timezone(例如:03/Jul/2024:08:33:00 +0800)。
request
$request:记录请求行,包含了请求方法、请求 URI 和 HTTP 协议版本。例如:GET /index.html HTTP/1.1。
status
$status:记录响应的 HTTP 状态码。
body_bytes_sent
$body_bytes_sent:记录发送给客户端的响应主体的字节数,不包括响应头。如果响应没有主体,则这个字段为0。
$http_referer
$http_referer:记录请求的Referer头部字段的值。这个字段表示客户端从哪个页面链接到当前请求的页面。
http_user_agent
$http_user_agent:记录请求的User-Agent头部字段的值。这个字段包含了客户端浏览器的详细信息。
http_x_forwarded_for
$http_x_forwarded_for:记录请求的X-Forwarded-For头部字段的值。这个字段通常由代理服务器添加,表示原始客户端的 IP 地址。
日志示例如下:

3.5 使用 limit_rate 限制客户端传输数据的速度
限制客户端的下载速度。这个功能对于控制带宽、优化服务器性能以及防止带宽滥用。
在这个例子中,limit_rate设置为50k,表示每个客户端连接的最大传输速率为50KB/s。通过设置limit_rate,可以控制客户端请求的传输速率,避免因单个客户端占用过多带宽而导致其他客户端无法正常访问。
1 | >>> 修改nginx配置文件 |

% Total: 文件的总大小。% Received: 已接收的百分比。% Xferd: 已传输的数据量。Average Speed: 平均下载速度。Time Total: 总时间。Time Spent: 已经花费的时间。Time Left: 剩余时间。Current Speed: 当前下载速度。
Current Speed显示为 52668 bytes/sec(约为 51.43359375 KB/sec),接近设置的50k限制。ZZ
3.6 Nginx 虚拟主机配置
什么是虚拟主机?
虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供web服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。

Nginx 支持三种类型的虚拟主机配置,具体包括基于域名、基于IP和基于端口的虚拟主机。
- 基于域名的虚拟主机:这种类型的虚拟主机使用server_name指令来区分不同的虚拟主机,适用于外部网站的发布。通过域名系统(DNS)解析到同一个IP地址的不同域名可以指向不同的网站内容。
- 基于IP的虚拟主机:一块主机绑定多个IP地址,每个IP地址对应一个虚拟主机。这种方式要求服务器有多个IP地址,每个虚拟主机通过不同的IP进行访问。
- 基于端口的虚拟主机:通过不同的端口号来区分不同的虚拟主机,适用于需要在同一台物理服务器上运行多个服务的情况。
Nginx通过提供虚拟主机的功能,允许用户在单一服务器上部署多个网站或应用,而无需安装多个Nginx实例。
1. 基于域名的虚拟主机
1 | >>> 修改配置文件 |
注意:如果修改的是nginx的资源文件,则不需要进行服务重启和热更新。
2. 基于ip的虚拟主机
1 | [root@localhost ~]# ip a |
3. 基于端口的虚拟主机
1 | [root@localhost ~]# vim /etc/nginx/conf.d/port_server.conf |
4、Nginx proxy 代理
4.1 反向代理产生背景
反向代理产生的背景是互联网的高速发展和用户需求的激增。
- 提高服务器性能:随着用户数量的增加,单个服务器处理大量请求的能力有限,通过使用反向代理,可以将请求分散到多个服务器上,从而提高整体的处理能力和效率。
- 负载均衡:反向代理可以作为负载均衡器,将客户端的请求均匀地分配到后端的
相同服务器群中,确保每个服务器的负载处于合理水平,避免某单一服务器过载而影响服务质量。 - 安全性提升:反向代理可以隐藏后端服务器的真实IP地址,增加系统的安全性。保护内部网络不受外界直接访问。
- 缓存静态内容:反向代理服务器可以缓存静态内容,如图片、CSS和JavaScript文件,这样可以减少对后端服务器的重复请求,加快内容的加载速度。
4.2 反向代理服务的实现
- 配置反向代理服务器:首先需要设置一个反向代理服务器,可以是Nginx、Apache等常见的Web服务器软件。在服务器上进行相应的配置,指定后端服务器的地址和端口号。
- 安装和配置后端服务器:根据具体需求,选择并安装适当的后端服务器软件,如Tomcat、Node.js等。然后对后端服务器进行配置。
- 配置反向代理规则:在反向代理服务器上配置转发规则,将客户端的请求转发到正确的后端服务器。这可以通过修改配置文件或使用特定的命令来实现。


4.3 正向代理和反向代理的区别
- 代理对象不同:
正向代理的代理对象是客户端,它位于客户端和目标服务器之间,客户端通过代理服务器发送请求到目标服务器,并从目标服务器获取内容。反向代理的代理对象是服务器,它位于客户端和目标服务器之间,客户端的请求直接发送到反向代理服务器,然后由反向代理服务器将请求转发给目标服务器。 - 使用场景不同:正向代理通常用于访问被限制或不可访问的内容,或者在内部网络中提供对外访问的方式。反向代理则主要用于实现负载均衡、安全策略、缓存等功能,提高网站性能和可用性。
- 设置需求不同:正向代理通常需要客户端进行设置,以使其通过代理服务器进行访问,这通常涉及到在客户端的网络设置中指定代理服务器的IP地址和端口号。反向代理则通常不需要客户端进行任何设置,客户端发出的请求直接发送到反向代理服务器,然后由反向代理服务器转发请求到后端真实服务器。
- 安全性不同:正向代理隐藏客户端的IP地址和身份信息,因为请求是通过代理服务器发出的。反向代理隐藏服务器的真实IP地址和身份信息,
客户无需知道后端服务的真实地址。因为请求是直接发送到反向代理服务器,然后由反向代理服务器将请求转发给目标服务器。


反向代理中,proxy和server同属一个LAN,反向代理中代理的对象是服务端,proxy和server同属一个LAN,对client透明。

正向代理和反向代理对比示意图,正向代理中代理的对象是客户端,proxy和client同属一个LAN,对server透明;

4.4 常用的集群软件
- 开源:LVS,Keepalived,Haproxy,Nginx
- 商业:F5
4.5 Nginx proxy模块配置
4.5.1 Nginx proxy代理模块
1 | ngx_http_proxy_module |
4.5.2 代理配置
准备两台nginx主机,一台为代理服务器,一台为后端服务器。
1 | #>>> nginx 01代理服务器配置修改 |
注意事项: buffer 缓冲区
- 并发连接数:更多的并发连接意味着需要更多的繁忙缓冲区。每个连接可能会使用一个繁忙缓冲区,因此需要根据预期的并发量来设置繁忙缓冲区的数量。
- 响应大小:如果后端服务器返回的响应体通常较大,可能需要增加繁忙缓冲区的大小以避免性能问题。同时,如果响应体很小,那么过多的繁忙缓冲区或过大的繁忙缓冲区可能会浪费内存。
- 内存限制:Nginx的繁忙缓冲区大小不能无限制地增加,因为服务器的内存是有限的。必须确保繁忙缓冲区的配置不会消耗过多的内存,影响其他进程或服务的性能。
- 后端服务器性能:后端服务器的响应速度也会影响繁忙缓冲区大小的设置。如果后端服务器响应迅速,可能不需要很大的繁忙缓冲区;如果响应慢,较大的繁忙缓冲区可以减少Nginx等待数据的时间。
4.5.3 服务端配置
1 | [root@localhost ~]# cat /etc/nginx/conf.d/default.conf |
4.5.4 测试访问
1 | # 访问代理服务器域名 |
服务端查看/var/log/nginx/access.log 访问日志

192.168.174.20 反向代理服务器地址
192.168.174.21 客户端真实地址
5、Nginx 负载均衡
5.1 负载均衡作用
- 提高并发处理能力:通过将网络流量
平均分发到多个服务器上,负载均衡器能够提高系统整体的响应速度和并发处理能力。 - 增强系统的伸缩性:当需要增加或减少服务器数量时,负载均衡器可以重新分配请求,确保系统可以根据需求进行扩展或缩减。
- 提升系统的可用性:负载均衡器会监控各个服务器的状态,自动跳过不可用的服务器,确保请求只被分发给可用的服务器,从而保证服务的连续性。
- 安全防护功能:一些负载均衡解决方案提供了安全功能,如黑白名单处理、防火墙以及防御DDoS攻击等。
- 优化资源使用:负载均衡技术可以确保没有单个服务器承受过多的负载,从而避免过载,实现资源的最优使用。
- 最小化响应时间:通过智能地将请求分配给多个服务器,负载均衡有助于减少用户的等待时间,提供更快的服务响应。
5.2 Nginx 负载均衡模块
1 | ngx_http_upstream_module |
- ngx_http_upstream_module:用于定义负载均衡策略和后端服务器组的模块。
upstream指令用于定义后端服务器组,这些服务器组会被Nginx用来进行负载均衡。 - ngx_http_proxy_module:负责将客户端的请求转发到
upstream模块定义的后端服务器组。通过proxy_pass指令,Nginx可以将请求发送到指定的服务器组,从而实现负载均衡。
5.3 Nginx upstream 配置
upstream 配置与http块下,和server块同级。
1 | #>>> 代理服务器配置 |
5.3.1 Nginx负载均衡策略
轮询(Round Robin):这是默认的负载均衡策略。在这种策略下,每个请求会按时间顺序逐一分配到不同的后端服务器节点,确保每个节点平均处理请求。- 优点:
- 简单高效:轮询策略实现起来相对简单,不需要复杂的算法支持,因此在处理请求时效率较高。
- 自动故障转移:如果某个后端服务器宕机或无法响应,Nginx能够自动检测到并将请求转发到其他健康的服务器上,这样可以提高系统的整体可用性。
- 均匀分配:在大多数情况下,轮询策略能够保证请求被均匀地分配到各个后端服务器上,从而提高了系统的吞吐量和资源的利用率。
- 缺点:
- 会话一致性问题:由于请求可能会被随机分配到不同的服务器上,这可能会导致同一个用户的连续请求落在不同服务器上,从而影响会话的一致性。
- 缺乏灵活性:轮询策略不会考虑后端服务器的实际处理能力,也不会根据请求的内容进行优化分配,这可能会导致某些服务器过载而其他服务器却处于空闲状态。
- 优点:
加权轮询(Weighted Round Robin):这种策略允许根据服务器的性能为其分配权重,性能更好的服务器可以处理更多的请求。- 优点:
- 性能优化:允许性能更强的服务器处理更多的请求,这样可以充分利用资源,提高整体的处理能力。
- 灵活性:可以根据实际情况调整服务器的权重,以适应不同的负载需求和服务器性能。
- 适应性:在服务器性能差异较大时,能够更好地平衡负载,避免某些服务器过载而其他服务器空闲的情况发生。
- 缺点:
- 压力集中:在系统启动初期,高权重的节点可能会承受较大的压力,导致机器负载突然增高,而其他机器则处于低负载状态,这可能会影响服务的平滑性。
- 复杂性:相比简单的轮询策略,加权轮询需要更多的配置和管理,增加了系统的复杂性。
- 会话一致性:尽管加权轮询考虑了服务器的性能,但仍然可能导致同一用户的请求被分配到不同服务器,影响会话一致性。
- 优点:
最少连接(Least Connections):在这个策略下,Nginx会将新请求分配给当前连接数最少的服务器,这样可以保证服务器间的负载更加均衡。- 优点:
- 提高服务器利用率:在高负载情况下,将请求转发给当前连接数较少的后端服务器,可以更有效地利用服务器资源,避免某些服务器过载。
- 适应性强:适用于处理时间不确定或服务器性能差异较大的环境,能够根据实际情况动态调整请求分配,提高整体的处理能力和效率。
- 减少响应时间:通过将请求分配给当前连接数较少的服务器,可以减少用户的等待时间,提高服务的响应速度。
- 缺点:
- 可能导致空闲:在某些情况下,如果某个服务器的处理能力非常强,可能会导致其他服务器长期处于空闲状态,从而影响其性能和稳定性。
- 可能不公平:如果服务器的处理能力不同,仅仅根据连接数来分配请求可能会导致某些服务器承担更多的负载,而其他服务器则相对较少,这在一定程度上违背了负载均衡的公平性原则。
- 优点:
IP Hash:这种策略会根据客户端IP地址的哈希值来选择服务器,这样可以确保同一用户的请求总是被发送到同一台服务器,有助于实现会话保持。- 优点:
- 会话保持:根据客户端IP的哈希值来分配请求,确保来自同一IP的请求被发送到相同的后端服务器。这有助于维持客户端与服务器之间的会话状态,特别是对于需要保持登录状态或其他会话信息的应用来说非常重要。
- 减少响应时间:由于同一用户的请求被定向到同一台服务器,可以减少因服务器间会话恢复而产生的延迟,提高应用的响应速度。
- 缺点:
- 无法处理高并发:当某个客户端的请求量异常增加时,可能会导致该客户端对应的后端服务器负载过高,而其他服务器却处于相对空闲的状态。
- 优点:
URL Hash:这种策略会根据请求的URL的哈希值来选择服务器,适用于需要根据URL分配请求到特定服务器的场景。优点:
- 会话保持:确保相同URL的请求始终被分配到同一台后端服务器,有助于保持会话的一致性,特别适用于需要维护用户登录状态等场景。
- 提高效率:由于相同URL的请求被定向到同一服务器,这可以减少服务器间状态复制的需要,提高缓存效率,尤其适用于后端服务器使用缓存的场景。
缺点:
- 服务器动态变化敏感:如果后端服务器列表发生变化(如增加或减少服务器),可能会导致哈希结果的变化,进而影响到之前已经分配的服务器,这需要在使用中特别注意。
Fair:根据后端服务器的响应时间进行动态分配请求,实现更合理的负载均衡。nginx本身不支持fair,需要独立安装upstream_fair模块。- 优点:
- 动态调整:Fair策略能够动态地根据服务器的实际处理能力来分配请求,这样可以更合理地利用服务器资源,提高整体的处理效率。
- 适应性强:对于那些处理能力不一或处理时间不确定的服务器集群,Fair策略能够更好地平衡负载,避免某些服务器过载而其他服务器空闲的情况发生。
- 缺点:
- 对突发流量敏感:由于Fair策略是根据服务器当前的响应时间来分配请求,因此对于突发流量的处理可能不够迅速,需要一段时间来调整分配策略。
- 可能引起资源分配不均:在服务器性能差异较大的情况下,Fair策略可能会导致性能较好的服务器承担更多的请求,而性能较差的服务器则可能处于较为空闲的状态。
- 优点:
轮询策略
1 | upstream test { |
负载均衡状态配置参数:
down;表示不在将用户的请求转发到此主机中;backup;预留的备份机器。当其他所有的非backup机器出现故障时,才会请求backup机器,因此这台机器的压力最轻。max_fails:表示允许的最大失败次数。当一个后端服务器在fail_timeout时间内连续失败这么多次后,Nginx 会将该服务器标记为不可用,不再向其转发请求。默认值为 1。fail_timeout:表示失败检查的时间间隔。在这个时间段内,如果一个后端服务器的失败次数达到了max_fails,那么 Nginx 会将其标记为不可用。默认值为 10s。# down http { upstream backend { server 192.168.174.21 down; server 192.168.174.22; } ... } # backup; http { upstream backend { server 192.168.174.21 backup; server 192.168.174.22; } ... } # max_fails fail_timeout http { upstream backend { server 192.168.174.21 max_fails=3 fail_timeout=30s; server 192.168.174.22 max_fails=3 fail_timeout=30s; } ... }1
2
3
4
5
6
7
8
9
10
11
##### **加权轮询**
```bash
http {
upstream backend {
server 192.168.174.21 weight=2;
server 192.168.174.22 weight=1;
}
...
}
ip_hash
1 | http { |
URL Hash
1 | http { |
最少连接
1 | http { |
fair
1 | http { |
参考链接:https://github.com/gnosek/nginx-upstream-fair
6、Nginx会话保持
6.1 什么是会话保持
会话保持是一种在负载均衡环境中维持客户端和服务器之间的交互状态的机制。
会话保持的目的是确保来自同一用户的连续请求被分配到同一台服务器上处理,从而保持用户会话的连续性。这对于维护用户登录状态等敏感信息至关重要。以下是一些关键点:
- 识别关联性:会话保持可以识别客户端与服务器之间交互过程的关联性。
- Web开发技术:在Web开发中,会话保持通常通过Session和Cookie机制来实现。
- Session与Cookie:Session是一种服务器端的会话管理机制,而Cookie是客户端的一种缓存机制,两者都可以用于跟踪用户会话。
- 粘滞会话(Sticky Sessions):会话保持有时也称为粘滞会话,它确保一系列相关联的访问请求会被分配到同一台服务器上处理。
6.2 什么是Cookie和Session
Cookie和Session都是用于跟踪和管理网站用户状态的技术,但它们的存储位置和使用方式有所不同。
Cookie 是一种存储在用户浏览器中的小型文本文件,它可以用来记录用户信息,如登录状态、网站偏好设置等。当用户访问一个网站时,服务器会向用户的浏览器发送Cookie,浏览器会保存这些信息。下次用户再次访问该网站时,浏览器会将这些Cookie信息发送回服务器,服务器通过这些信息来识别用户并生成个性化的内容。
Session 则是在服务器端记录用户信息的一种机制。当用户访问服务器时,服务器会创建一个新的Session,并将其唯一标识(如ID)存储在Cookie中,然后发送给客户端浏览器。这样,每次用户与服务器交互时,服务器都可以通过这个Session标识来识别用户,并获取与之相关的信息,如登录状态或购物车内容等。
6.3 Nginx实现回话保持的手段
- 基于客户端IP地址的会话保持:
ip_hash:这种方法使用源地址哈希算法,确保来自同一客户端的请求总是被发送到相同的后端服务器。这有助于保持客户端与服务器之间的会话状态,特别是对于需要维持登录状态或其他会话信息的应用来说非常重要。然而,这种方法的缺点是如果后端服务器宕机,会话信息可能会丢失,同时如果多个客户端处于同一局域网内,可能会导致负载不均衡。
1
2
3
4
5
6
7
8http {
upstream backend {
ip_hash;
server 192.168.174.21;
server 192.168.174.22;
}
...
}
- 基于后端存储的会话保持:(了解)
- 可以通过数据库、Redis或Memcached等后端存储服务来实现Session的复制和同步。这种方法不依赖于Nginx本身,而是通过后端存储服务的会话同步机制来保持用户会话状态。
我们知道一个请求在经过一个服务器处理时,服务器会保存相关的会话信息,比如session,但是该请求如果第一个服务器没处理完,通过nginx轮询到第二个服务器上,那么这个服务器是没有会话信息的。
最典型的一个例子:用户第一次进入一个系统是需要进行登录身份验证的,首先将请求跳转到Tomcat1服务器进行处理,登录信息是保存在Tomcat1 上的,这时候需要进行别的操作,那么可能会将请求轮询到第二个Tomcat2上,那么由于Tomcat2 没有保存会话信息,会以为该用户没有登录,然后继续登录一次,如果有多个服务器,每次第一次访问都要进行登录,这显然是很影响用户体验的。
这里产生的一个问题也就是集群环境下的 session 共享,如何解决这个问题?
- 选择一个中间件,将登录信息保存在一个中间件上,这个中间件可以为Redis这样的数据库。那么第一次登录,我们将session 信息保存在 Redis 中,跳转到第二个服务器时,我们可以先去Redis上查询是否有登录信息,如果有,就能直接进行登录之后的操作了,而不用进行重复登录。
7、Nginx动静分离
7.1 介绍
Nginx 动静分离是指将动态和静态资源请求分开处理,以提高网站性能和稳定性。
Nginx作为一个高性能的Web服务器,可以有效地处理静态资源,如HTML、JavaScript、CSS和图片等文件,而将动态资源请求,通常是指需要后端服务器处理的请求,如PHP、Java等,交给专门的应用服务器处理,如Tomcat。
- 提高响应速度:Nginx对静态资源的处理非常高效,可以快速响应客户端的请求,减少页面加载时间。
- 减轻后端压力:动态资源请求通常涉及到数据库操作,将这些请求交给专门的应用服务器处理,可以避免Nginx承担过多的计算任务,从而保证动态内容的生成和处理更加专注和高效。
- 提升网站稳定性:动静分离可以有效分散服务器负载,避免单点故障,提高整个网站的稳定性和可靠性。
- 优化资源利用:通过合理配置Nginx,可以实现客户端缓存,减少不必要的数据传输,节省带宽。

7.2 环境准备
1 | 192.168.174.20 # 反向代理服务器 |
7.2.1 代理服务器配置
1 | #>>> 修改配置文件 |
7.2.2 静态资源服务器配置
1 | #>>> 修改配置文件 |
7.2.3 动态资源服务器配置
1 | #>>> 安装 PHP 所需的epel源 |
8、Nginx防盗链
7.1 介绍
Nginx可以通过配置实现防盗链,以保护网站资源不被未经授权的使用。两个网站 A 和 B, B网站引用了A网站上的图片,这种行为就叫做盗链。 防盗链,就是要防止B引用A的图片。以下是一些常用的方法:
使用refer模块:这是Nginx中一个用于检查HTTP请求头中的Referer字段的模块。通过配置valid_referers指令,可以指定允许访问资源的合法来源域名或URL模式。如果请求的Referer头部与这些模式匹配,则认为请求是合法的,否则拒绝访问。这种方法相对简单,但可能受到伪造Referer头的影响。
Nginx防盗链模块
1 | ngx_http_referer_module |
如何区分哪些是不正常的用户?
HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况。7.2 Nginx防盗链配置
环境准备:
1 | 192.168.174.20 #受害者(被盗链者) |
简单了解Nginx默认access日志格式

1 | 192.168.174.1 # 客户端地址 |

上图红色方框中,显示上一级链接地址。如果存在则显示,无则显示
"-"
受害者环境准备
1 | 192.168.174.20 #受害者(被盗链者) |
非法者环境准备
1 | 192.168.174.21 #违法者(盗链者) |
查看被盗链主机的访问日志

“http://192.168.174.21/" 盗链者地址
禁用盗链IP/URL,受盗链主机配置
1 | [root@nginx-server ~]# vim /etc/nginx/nginx.conf |
盗链者再次访问图片
1 | 在其中一台机器测试: |

9、Nginx重定向
9.1 Nginx rewrite介绍
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
- URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.com/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。
- 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。
- 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的80端口时,将其跳转到443端口。
9.2 Rewrite 相关指令
- return指令:用于返回指定的HTTP状态码,通常与重定向一起使用,例如
return 301 $uri会将请求重定向到新的URI。 - if语句:允许根据某些条件执行特定的重写规则。这个指令可以让你根据不同的请求头或请求参数来应用不同的重写规则。
- set指令:用于设置变量,这些变量可以在rewrite规则中被引用,或者在其他地方用于进一步的处理。
- rewrite指令:这是实现URL重写的关键指令,它根据正则表达式部分的内容,将请求重定向到替换(replacement)部分,结尾是标志(flag)。
9.2.1 if语句
应用环境
1 | server块,location块 |
语法:
1 | if (condition) { … } |
9.2.2 Rewrite flag标记位
Nginx的rewrite指令支持多种flag,用于控制重写规则的行为。以下是一些常用的flag:
- last:表示完成当前的重写规则后,停止处理后续的重写规则,从头再匹配。
- break:表示完全停止处理后续的重写规则。
- redirect:表示将请求重定向到新的URI,并返回HTTP状态码为302。
- permanent:表示将请求永久重定向到新的URI,并返回HTTP状态码为301。
这些flag可以根据需要组合使用,以实现不同的URL重写和重定向行为。例如,rewrite ^/old-url/(.*)$ /new-url/$1 permanent;中的permanent flag表示将请求永久重定向到新的URI,并返回HTTP状态码为301。
last和break区别
1 | [root@localhost ~]# vim /etc/nginx/conf.d/last_break.conf |
last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;
redirect 和 permanent区别
则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。
9.2.3 Rewrite 常见案例
1 | 192.168.174.20 rewrite.tanke.love |
上述案例使用游览器访问http://rewrite.tanke.love/a后会永久重定向至http://rewrite.tanke.love/b/index.html
1 | 192.168.174.20 rewrite.tanke.love |
上述案例:当用户游览器访问http://rewrite.tanke.love/2023/a时,将永久重定向至http://rewrite.tanke.love/2024/a/index.html
1 | 192.168.174.20 rewrite.tanke.love |
上述案例:当用户访问http://rewrite.tanke.love/是永久重定向至http://baidu.com
$host为客户端访问的域名。
1 | 192.168.174.20 rewrite.tanke.love |
上述案例:当用户访问http://rewrite.tanke.love/a是永久重定向至http://192.168.174.21/a
1 | 192.168.174.20 rewrite.tanke.love |
定义了两个路径:/login和/reg。
对于/login路径,它设置了根目录为”/usr/share/nginx/html”。它还使用了一个正则表达式重写规则,将URL中的”/login/“后面的内容作为参数传递给”/reg/login.html”页面,并附加在URL中作为查询参数”user”的值。
对于/reg路径,它同样设置了根目录为”/usr/share/nginx/html”,并将默认索引文件设置为”login.html”。
这段配置的作用是将访问/login路径的请求重定向到/reg路径下的”login.html”页面,并将原始路径中的参数传递给该页面。
1 | 192.168.174.20 rewrite.tanke.love |
定义了两个路径:/qf和/qf/11/22/33。
对于/qf路径,它使用了一个正则表达式重写规则,将URL中的”/qf/“后面的内容按照数字进行分组,并将这些数字作为参数传递给新的URL路径。新的URL路径为”/qf/11/22/33”,其中
$1、$2、$3分别代表第一组、第二组和第三组的数字,$4表示剩余的字符串。这个重写规则使用了”permanent”标志,表示返回301永久重定向。对于/qf/11/22/33路径,它设置了根目录为”/html”,并将默认索引文件设置为”1.html”。
这段配置的作用是将访问/qf路径的请求重定向到/qf/11/22/33路径下的”1.html”页面,并根据原始路径中的参数进行URL的重新组织。
9.2.4 set指令使用
set 指令是用于定义一个变量,并且赋值
1 | server,location,if |
举例:
1 | C:\Windows\System32\drivers\etc\hosts # win域名解析 |
该配置文件定义了一个监听在端口 80 上的服务器,并指定了服务器名称为 “rewrite.tanke.love”。它包含三个
location块,分别对应不同的路径:
/:根路径,将请求映射到/usr/share/nginx/html目录下的index.html或index.htm文件。如果请求的主机名是 “rewrite.tanke.love”,则直接返回该文件;否则,如果主机名匹配正则表达式^(.*)\.tanke\.love$,则将主机名中的第一个部分作为变量$user的值,并将请求重定向到http://rewrite.tanke.love/$user,使用永久重定向(301)。/liubei:将请求映射到/usr/share/nginx/html目录下的index.html或index.hml文件。/guanyu:将请求映射到/usr/share/nginx/html目录下的index.html或index.hml文件。这个配置文件的作用是根据请求的主机名和路径来处理请求,并根据需要进行重定向。
9.2.5 return指令使用
return 指令用于返回状态码给客户端
1 | # 作用域 |
举例:
1 | # 如果访问的.sh结尾的文件则返回403操作拒绝错误 |
定义了一个监听在端口 80 上的服务器,并指定了服务器名称为 “rewrite.tanke.love”。它包含两个
location块,分别对应不同的路径:
/:根路径,将请求映射到/usr/share/nginx/html目录下的index.html或index.htm文件。~* \.sh$:匹配以.sh结尾的文件名,返回 HTTP 状态码 403(禁止访问)。这个配置文件的作用是处理请求,并根据请求的文件类型进行相应的操作。
1 | # https重定向 |
10、Nginx Location 指令详解
Nginx 的 HTTP 配置主要包括三个区块,结构如下:
1 | http { # 这个是协议级别 |
协议级别:这部分配置指定了使用的协议为HTTP,并包含了一个名为mime.types的文件,用于定义文件扩展名与MIME类型的映射关系。服务级别:这部分配置指定了监听的端口号为80,服务器名称为localhost。虚拟主机。请求级别:这部分配置指定了根目录为html,默认的索引文件为index.html和index.htm。
10.1 Location 区块
- location 是在
server块中配置,根据不同的 URl使用不同的配置,来处理不同的请求。 - location 是
有顺序的,会被第一个匹配的location 处理。
基本语法如下:
1 | location [=|~|~*|^~|@] pattern{……} |
10.2 location 前缀含义
1 | = 表示精确匹配,优先级也是最高的,只有请求的 URI 与指定的字符串完全相等时才会匹配。 |
10.2.1 location 配置示例
- 没有修饰符
/表示:必须以指定模式开始
1 | [root@localhost ~]# mkdir -p /home/www/nginx/abc |
=表示:必须与指定的模式精确匹配
1 | [root@localhost ~]# echo "a" > /usr/share/nginx/html/a.html |
~表示:指定的正则表达式要区分大小写
1 | [root@localhost ~]# mkdir -p /home/www/nginx/{abc,ABC} |
~*表示:指定的正则表达式不区分大小写
1 | server { |
^~:类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了。
10.2.2 location 查找顺序、优先级
1 | = 大于 ^~ 大于 ~|~*|!~|!~* 大于 / |
1 | location 区段匹配示例 |
10.2.3 root 和alias 指令区别
在 Nginx 配置中,location 指令用于定义如何处理不同的 URL 请求。其中 root 和 alias 是两个常用的指令,它们的含义如下:
- root:
root指令用于指定请求的根目录。当客户端发起请求时,Nginx 会将请求的 URI 与指定的根目录进行拼接,以确定实际的文件路径。例如,如果root设置为/var/www/html,而客户端请求的是/index.html,那么 Nginx 将会查找文件/var/www/html/index.html。 - alias:
alias指令用于指定请求的别名目录。与root不同,alias不会将请求的 URI 与指定的目录进行拼接,而是直接使用指定的目录作为请求的根目录。例如,如果alias设置为/var/www/images,而客户端请求的是/index.jpg,那么 Nginx 将会查找文件/var/www/images/index.jpg。
需要注意的是,root 和 alias 只能选择其中一个来使用,不能同时使用。通常情况下,建议使用 root 指令来指定请求的根目录,因为它更加直观和简单。
举例:
1 | server { |
alias是一个目录别名的定义;root则是最上层目录的定义。- 还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无。










