一、Web服务介绍
Web 服务是在网络环境中运行的应用程序,负责处理客户端的请求并提供相应的响应。在众多 Web 服务中,Apache 和 Nginx 是两款备受关注和广泛使用的服务器软件。
Apache
Apache 是历史悠久且非常流行的开源 Web 服务器。它具有以下特点:
- 丰富的功能模块:提供了众多的模块,如 SSL 支持、虚拟主机配置、URL 重写等,可通过配置文件轻松启用或禁用。
- 稳定性和可靠性:经过长期的发展和优化,在处理大量并发连接时表现稳定。
- 良好的兼容性:几乎支持所有的操作系统和编程语言。
例如,许多大型企业网站和政府机构网站都选择 Apache 作为其 Web 服务,因为其稳定可靠的性能能够满足高流量和复杂业务需求。
Apache prefork 模型
在 Prefork 模型中,服务器会预先启动多个子进程。每个子进程在等待连接请求时处于空闲状态。当有新的连接请求到达时,一个空闲的子进程会被激活来处理该请求。
这种模型的优点包括:
-
稳定性较高:由于每个请求都由独立的子进程处理,一个进程的故障不会影响到其他进程,从而保证了服务的稳定性。
-
兼容性好:对于一些旧的、不支持多线程的模块能够很好地兼容。
然而,Prefork 模型也存在一些缺点:
-
资源消耗较大:因为预先启动了多个子进程,会消耗较多的系统资源,如内存等。
-
扩展性有限:在处理大量并发连接时,创建过多的进程可能会导致系统性能下降。
例如,在一个小型的企业内部网站,如果并发访问量不是特别大,且使用了一些旧的不支持多线程的模块,Prefork 模型可能是一个合适的选择。但对于像大型电商网站那样的高并发场景,可能就需要考虑其他更高效的模型或服务器软件。
Apache worker 模型
在 Worker 模型中,服务器会启动多个进程,每个进程又会生成多个线程。这些线程共同处理客户端的请求。
Worker 模型具有以下特点和优势:
优点:
-
资源利用率高:相比 Prefork 模型,Worker 模型在处理并发请求时能够更有效地利用系统资源,因为线程比进程更轻量级,创建和切换的开销较小。
-
并发处理能力强:多个线程可以同时处理多个请求,提高了服务器的并发处理能力,能够更好地应对高并发的场景。
-
内存使用更优化:由于线程共享进程的资源,相较于 Prefork 模型,内存的使用更加节省。
缺点:
-
稳定性稍逊:由于线程共享进程资源,如果一个线程出现问题,可能会影响到同一进程中的其他线程。
-
部分模块不兼容:某些不支持线程安全的模块可能无法在 Worker 模式下正常工作。
举例来说,对于一个流量适中、需要较好地节省资源并且对并发处理有一定要求的网站,Worker 模型可能是一个比较合适的选择。但如果网站使用了一些特定的不兼容模块,就需要谨慎考虑是否采用此模型。
Apache event模型
在 Event 模型中,它采用了异步非阻塞的方式来处理连接。这意味着服务器能够在一个线程中同时处理多个连接,而无需为每个连接创建新的进程或线程。
Event 模型的主要特点和优势包括:
优点:
-
极高的并发处理能力:能够处理大量的并发连接,尤其适合高并发的场景,如大型社交网站或热门的在线服务。
-
资源消耗低:由于采用异步方式,减少了进程和线程的创建,从而降低了系统资源的消耗。
-
响应迅速:能够更快地响应请求,减少了请求的等待时间,提供更流畅的用户体验。
缺点:
-
配置复杂:相比其他模型,Event 模型的配置可能更为复杂,需要对服务器的参数有更深入的理解和调整。
-
模块兼容性问题:某些模块可能不兼容 Event 模型,需要进行仔细的筛选和测试。
例如,对于像双十一期间的电商平台这种瞬间流量巨大的情况,Apache 的 Event 模型能够更好地应对,确保网站的稳定运行和快速响应,避免出现服务器崩溃或响应迟缓的问题。但在使用之前,需要对网站所依赖的模块进行充分的测试,以确保其在 Event 模型下正常工作。
Nginx
Nginx 是一款高性能的 Web 服务器和反向代理服务器。
- 高并发处理能力:采用异步非阻塞的方式处理请求,能够在高并发场景下快速响应。
- 轻量级和高效:资源消耗相对较少,启动速度快。
- 优秀的反向代理和负载均衡功能:可以有效地将请求分发到多个后端服务器,提高系统的整体性能和可用性。
比如,一些高流量的互联网公司,如淘宝、腾讯等,会使用 Nginx 来处理海量的用户请求,确保网站的快速响应和稳定运行。
二、服务端 I/O 流程
服务端的 I/O(输入 / 输出)流程是指服务器处理来自客户端的数据输入以及向客户端发送数据输出的过程。
一般来说,服务端的 I/O 流程可以分为以下几个主要步骤:
-
建立连接:客户端向服务器发起连接请求,服务器接受连接并建立通信通道。这通常基于网络协议,如 TCP 协议。
- 例如,在 Web 服务中,用户在浏览器中输入网址,浏览器通过 HTTP 协议向服务器发起连接请求。
-
接收请求:服务器等待并接收客户端发送的数据请求。
- 比如,客户端可能发送一个获取网页内容的请求。
-
解析请求:服务器对收到的请求数据进行解析,理解客户端的需求。
- 例如,解析请求的 URL、请求方法(GET、POST 等)、请求头和请求体中的参数等。
-
处理请求:根据解析出的请求内容,服务器执行相应的处理逻辑。这可能包括从数据库读取数据、进行计算、调用其他服务等。
- 假设请求是查询用户信息,服务器会从数据库中查找相关用户的数据。
-
准备响应:服务器根据处理结果准备要发送回客户端的数据。
- 如生成相应的网页内容、构建 JSON 格式的数据等。
-
发送响应:将准备好的响应数据通过网络发送回客户端。
- 继续以上例子,将查询到的用户信息发送回客户端的浏览器。
-
关闭连接:在完成数据交互后,根据协议和配置,关闭连接或保持连接以处理后续请求。
在整个 I/O 流程中,可能会涉及到不同的 I/O 模式,如阻塞 I/O、非阻塞 I/O、异步 I/O 等,以适应不同的性能和场景需求。
例如,在一个在线游戏服务器中,当玩家进行操作时,服务器按照上述流程接收、处理请求,并及时发送响应,以实现游戏的实时交互。又比如,在文件下载服务器中,服务器接收客户端的下载请求,读取文件数据并发送给客户端,完成文件传输的 I/O 过程。
磁盘 I/O
磁盘 I/O(输入 / 输出)是指计算机系统与磁盘设备之间的数据交换过程。
磁盘 I/O 主要包括读操作和写操作:
读操作:
当系统需要从磁盘获取数据时,会发出读请求。操作系统会将请求发送到磁盘控制器,磁盘控制器控制磁盘的机械部件定位到存储所需数据的磁道和扇区,然后将数据读取到磁盘缓冲区,并最终传输到系统内存供应用程序使用。
写操作:
当系统要将数据保存到磁盘时,会发起写请求。数据首先从内存传输到磁盘缓冲区,然后磁盘控制器将缓冲区中的数据写入到磁盘的指定位置。
磁盘 I/O 性能对计算机系统的整体性能有重要影响。一些影响磁盘 I/O 性能的因素包括:
- 磁盘转速:转速越高,数据传输速度通常越快。
- 寻道时间:磁头定位到数据所在磁道所需的时间,寻道时间越短,I/O 性能越好。
- 缓冲区大小:较大的磁盘缓冲区可以减少磁盘的实际读写次数,提高性能。
- 磁盘阵列(RAID)配置:不同的 RAID 级别可以提供不同的性能和数据冗余特性。
例如,在数据库服务器中,如果频繁进行大量数据的读写操作,磁盘 I/O 性能不足可能导致数据库响应迟缓,影响整个系统的运行效率。又比如,在视频编辑软件中,处理大型视频文件时,如果磁盘 I/O 速度跟不上,会导致视频编辑过程卡顿、渲染时间延长等问题
机械磁盘的寻道时间、旋转延迟和数据传输时间:寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则 I/O 处理就越快,目前磁盘的寻道时 间一般在3-15 毫秒左右。旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常 使用磁盘旋转一周所需要时间的1/2 之一表示,比如 7200 转的磁盘平均训传延迟大约为60*1000/7200/2=4.17毫秒,公式的意思为 (每分钟 60 秒 *1000 毫秒每秒 /7200 转每分 /2 ),如果是 15000转的则为 60*1000/15000/2=2 毫秒。数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速率,目前的磁盘接口每秒的传输速度可以达到 600MB ,因此可以忽略不计。常见的机械磁盘平均寻道时间值:7200 转 / 分的磁盘平均物理寻道时间: 9 毫秒10000 转 / 分的磁盘平均物理寻道时间: 6 毫秒15000 转 / 分的磁盘平均物理寻道时间: 4 毫秒常见磁盘的平均延迟时间:7200 转的机械盘平均延迟: 60*1000/7200/2 = 4.17ms10000 转的机械盘平均延迟: 60*1000/10000/2 = 3ms15000 转的机械盘平均延迟: 60*1000/15000/2 = 2ms每秒最大 IOPS 的计算方法:7200 转的磁盘 IOPS 计算方式: 1000 毫秒 /(9 毫秒的寻道时间 +4.17 毫秒的平均旋转延迟时间 )=1000/13.13=75.9 IOPS10000 转的磁盘的 IOPS 计算方式: 1000 毫秒 /(6 毫秒的寻道时间 +3 毫秒的平均旋转延迟时间 )=1000/9=111IOPS15000 转的磁盘的 IOPS 计算方式: 15000 毫秒 /(4 毫秒的寻道时间 +2 毫秒的平均旋转延迟时间 )=1000/6=166.6 IOPS
网络 I/O
网络 I/O(输入 / 输出)是指计算机系统通过网络进行数据的接收和发送过程。
在网络 I/O 中,主要包括以下几种常见的操作模式:
-
阻塞式 I/O:在进行数据读取或发送时,程序会一直等待,直到操作完成。如果数据尚未准备好,程序会被阻塞,无法进行其他操作。
- 例如,使用传统的
socket
编程,在调用recv
函数接收数据时,如果没有数据到达,程序会一直阻塞在那里。
- 例如,使用传统的
-
非阻塞式 I/O:程序不会被阻塞,而是立即返回一个状态,表示操作是否完成。如果操作未完成,需要通过轮询不断检查状态,直到数据准备好。
- 比如,在不断轮询检查网络套接字是否有数据可读的过程中,程序可以同时处理其他任务。
-
I/O 多路复用:通过一个线程或进程同时监控多个网络连接,当有数据可读写时,通知相应的程序进行处理。常见的实现方式有
select
、poll
和epoll
等。- 假设一个服务器同时处理多个客户端连接,使用
epoll
可以高效地管理这些连接,而无需为每个连接创建单独的线程。
- 假设一个服务器同时处理多个客户端连接,使用
-
异步 I/O:程序发起一个 I/O 操作后,无需等待操作完成,操作完成后会通过回调函数或其他方式通知程序。
网络 I/O 性能受到多种因素的影响,如网络带宽、延迟、数据包丢失率等。
例如,在一个高并发的 Web 服务器中,如果采用不合适的网络 I/O 模式,可能会导致大量连接请求被阻塞,服务器响应变慢。而使用高效的 I/O 多路复用或异步 I/O 模式,可以显著提高服务器的并发处理能力和性能。又如,在实时在线游戏中,低延迟的网络 I/O 对于保证游戏的流畅性和玩家体验至关重要,如果网络 I/O 出现延迟或卡顿,可能会导致游戏中的操作不及时响应
网络I/O 处理过程
网络 I/O 的处理过程通常包括以下几个主要阶段:
-
创建套接字(Socket):应用程序创建一个套接字来与网络进行通信。套接字是网络通信的端点,它定义了通信的协议(如 TCP 或 UDP)、本地地址和端口以及远程地址和端口等信息。
-
绑定(Binding):如果需要指定本地的地址和端口,应用程序将套接字与这些信息进行绑定。
-
连接(Connecting)(对于 TCP):在使用 TCP 协议时,如果是客户端,需要向服务器发起连接请求。服务器端则会监听并接受连接请求。
-
监听(Listening)(对于服务器):服务器端通过监听套接字等待客户端的连接请求。
-
数据发送(Sending Data):应用程序将要发送的数据写入到套接字的发送缓冲区。
-
数据传输:
- 操作系统将发送缓冲区中的数据通过网络协议栈进行封装和发送。
- 网络中的路由器和交换机根据目标地址将数据包转发到目的地。
-
数据接收(Receiving Data):
- 当数据包到达接收端时,操作系统将其存储在接收缓冲区中。
- 应用程序从接收缓冲区读取数据。
-
错误处理:在整个网络 I/O 过程中,可能会出现各种错误,如连接失败、数据包丢失、超时等,应用程序需要进行相应的错误处理。
例如,在一个文件下载的场景中:
- 客户端创建套接字并连接到服务器的指定端口。
- 服务器接受连接,并准备接收客户端的请求。
- 客户端发送请求下载特定文件的消息。
- 服务器从磁盘读取文件数据并通过网络发送给客户端。
- 客户端接收数据并保存到本地磁盘。
在一个在线聊天应用中:
- 用户输入消息并点击发送,应用将消息写入套接字发送缓冲区。
- 消息通过网络传输到接收方。
- 接收方应用从套接字接收缓冲区读取消息并显示给用户。
这些阶段共同构成了网络 I/O 的处理过程,不同的应用和网络环境可能会对这些阶段进行优化和调整,以实现更高效和可靠的网络通信。
不论磁盘和网络I/O
三、I/O 模型
I/O 模型相关概念
同步与异步:
- 同步 I/O:在同步 I/O 操作中,调用者在发出 I/O 请求后会等待 I/O 操作完成,然后才继续执行后续的代码。在整个 I/O 操作期间,调用者处于阻塞或忙碌等待的状态。
- 例如,使用传统的读文件操作,如果文件数据还未准备好,程序会一直等待直到数据可读。
- 异步 I/O:在异步 I/O 操作中,调用者发起 I/O 操作后立即返回,不会等待 I/O 操作完成。当 I/O 操作完成时,通过某种方式(如回调函数、事件通知等)通知调用者。
- 比如,在异步文件读取中,发起读取请求后程序可以继续执行其他任务,当文件读取完成时,系统通过回调函数告知程序读取结果。
阻塞与非阻塞:
- 阻塞 I/O:当进行 I/O 操作时,如果数据尚未准备好,调用者会被阻塞,不能进行其他操作,直到数据准备好或者操作完成。
- 假设进行网络连接,如果连接尚未建立成功,程序会一直阻塞在连接操作上。
- 非阻塞 I/O:当进行 I/O 操作时,如果数据尚未准备好,调用者不会被阻塞,而是立即返回一个状态,表示当前操作无法完成。调用者可以通过轮询或者其他方式来检查操作是否完成。
- 比如,在非阻塞网络套接字读取中,如果没有数据可读,立即返回一个特定的状态值,程序可以继续做其他事情,并定期检查是否有数据可读。
网络 I/O 模型
-
阻塞型 I/O 模型:
- 特点:在进行 I/O 操作时,如果数据未准备好,进程或线程会被阻塞,直到操作完成。
- 示例:当使用阻塞型套接字进行网络通信时,如果接收缓冲区没有数据,调用
recv
函数的线程会被阻塞,直到有数据到达。 - 优点:编程简单,逻辑清晰。
- 缺点:在高并发场景下,大量线程被阻塞会导致系统资源浪费,性能低下。
-
非阻塞型 I/O 模型:
- 特点:进程或线程在数据未准备好时不会被阻塞,而是立即返回一个错误或特定的状态。
- 示例:使用非阻塞套接字,当调用
recv
函数而没有数据时,函数会立即返回-1
和错误码EWOULDBLOCK
,表示当前没有数据可接收。 - 优点:不会因为等待 I/O 操作而阻塞线程,提高了资源利用率。
- 缺点:需要通过轮询不断检查 I/O 状态,增加了 CPU 开销。
-
复用型 I/O 模型(select、poll、epoll):
- 特点:通过一个函数同时监听多个文件描述符(套接字)的状态,当有任何一个描述符准备好进行 I/O 操作时,函数返回。
- 示例:使用
select
函数可以同时监听多个套接字,当其中某个套接字有数据可读或可写时,select
函数返回,并告知哪些套接字处于就绪状态。 - 优点:避免了对单个套接字的频繁轮询,减少了系统开销。
- 缺点:
select
和poll
在处理大量文件描述符时效率较低,epoll
在大规模并发场景下表现更好。
-
信号驱动型 I/O 模型:
- 特点:进程通过安装一个信号处理函数,当数据准备好时,内核发送一个信号通知进程。
- 示例:在网络编程中,设置好信号处理函数后,当网络数据到达时,内核发送信号通知进程。
- 优点:避免了阻塞和轮询。
- 缺点:在实际应用中较少使用,因为信号处理可能会比较复杂。
-
异步 I/O 模型:
- 特点:进程发起 I/O 操作后立即返回,内核在完成 I/O 操作后通知进程。
- 示例:使用异步 I/O 接口,如
aio_read
,发起读操作后进程继续执行其他任务,当读操作完成时,通过回调函数或其他方式通知进程。 - 优点:提供了最高的并发性能和响应性。
- 缺点:实现复杂,依赖操作系统的支持。
I/O 的常见具体实现方式
-
select
:- 工作方式:通过轮询的方式检查文件描述符集合中哪些描述符就绪。
- 缺点:能监视的文件描述符数量有限,通常为 1024 个;每次调用都需要重新设置文件描述符集合;返回时需要遍历整个集合来确定哪些描述符就绪。
-
poll
:- 类似于
select
,但没有文件描述符数量的限制。 - 缺点:与
select
一样,每次调用都需要重新设置描述符集合,并且返回时需要遍历。
- 类似于
-
epoll
:- 工作方式:基于事件驱动,当文件描述符就绪时,内核将事件通知给应用程序。
- 优点:没有最大文件描述符数量的限制;高效的事件通知机制,不需要每次都重新设置和遍历描述符集合。
四、零拷贝
零拷贝(Zero-Copy)是一种在计算机系统中优化数据传输操作的技术,旨在减少数据在内存之间的不必要复制,从而提高数据传输的性能和效率。
在传统的数据传输过程中,通常需要多次的数据拷贝操作。例如,从磁盘读取文件并通过网络发送时,数据可能要从磁盘拷贝到内核缓冲区,然后再从内核缓冲区拷贝到用户空间缓冲区,最后从用户空间缓冲区拷贝到网络缓冲区进行发送。
而零拷贝技术通过避免或减少这些不必要的拷贝,直接将数据从源(如磁盘)传输到目标(如网络),或者在某些情况下,只进行一次必要的拷贝。
零拷贝技术的优点包括:
- 显著提高数据传输的性能,减少了 CPU 开销和内存带宽的占用。
- 降低了数据传输的延迟,特别是在处理大量数据时效果更为明显。
常见的实现零拷贝的方式有:
mmap
(内存映射):将文件映射到进程的地址空间,减少了一次数据拷贝。sendfile
系统调用:在支持的操作系统中,可以直接将数据从文件描述符传输到网络套接字,避免了用户空间和内核空间之间的数据拷贝。
例如,在一个高性能的文件服务器中,如果需要频繁地将大文件发送给客户端,使用零拷贝技术可以极大地提高文件传输的速度,提升服务器的整体性能和响应能力。
五、Nginx 架构和安装
Nginx 介绍
Nginx 是一款轻量级、高性能的 Web 服务器和反向代理服务器,具有以下显著特点和优势:
特点:
- 高并发处理能力:采用异步非阻塞的方式处理请求,能够高效应对大量并发连接。
- 低资源消耗:相较于其他服务器,Nginx 对系统资源的需求较少,尤其是内存占用低。
- 反向代理和负载均衡:可以将请求分发到多个后端服务器,提高系统的可用性和扩展性。
- 灵活的配置:通过简单易懂的配置文件,实现各种复杂的功能和策略。
优势:
- 快速响应:能够迅速处理请求,减少用户等待时间,提供良好的用户体验。
- 稳定性高:在高负载情况下仍能保持稳定运行,不易出现故障。
- 易于扩展:可以方便地添加模块和功能,以满足不同的需求。
应用场景:
- Web 服务器:为静态网页和动态内容提供服务。
- 反向代理:隐藏后端服务器的真实 IP,增强安全性。
- 负载均衡:将流量均匀分配到多个服务器,提高系统整体性能。
例如,许多大型网站如淘宝、腾讯等都使用 Nginx 来处理高并发的用户请求,保证网站的快速稳定运行。对于中小企业的网站,Nginx 也能以其高效的性能和简单的配置,满足业务需求,降低服务器成本。
Nginx 功能介绍
-
Web 服务器功能:
- 高效处理静态文件请求,如 HTML、CSS、JavaScript、图片等,速度极快。
- 支持动态页面的反向代理,将请求转发到后端的应用服务器(如 PHP、Python 等)。
-
反向代理功能:
- 隐藏后端服务器的真实 IP 地址,增加安全性。
- 对客户端请求进行过滤和预处理,减轻后端服务器的压力。
-
负载均衡功能:
- 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希等,将请求均匀分配到多个后端服务器。
- 检测后端服务器的健康状态,自动剔除故障服务器,保证服务的高可用性。
-
缓存功能:
- 可以对静态文件和动态页面的响应进行缓存,减少重复请求对后端服务器的压力,提高响应速度。
-
SSL/TLS 加密支持:
- 能够配置 SSL 证书,实现 HTTPS 协议,保障数据传输的安全性。
-
访问控制和权限管理:
- 通过配置 IP 访问限制、用户认证等规则,控制对网站资源的访问。
-
Gzip 压缩:
- 对响应数据进行 Gzip 压缩,减少数据传输量,提高传输效率。
-
Rewrite 重写规则:
- 灵活地修改请求的 URL,实现 URL 重定向和优化。
-
监控和日志记录:
- 提供详细的访问日志和错误日志,方便监控服务器的运行状态和排查问题
Nginx 安装
Nginx 编译安装
上传安装包
解压缩
[root@nginx ~]# tar zxf nginx-1.24.0.tar.gz
下载存在的依赖关系
[root@nginx nginx-1.24.0]# yum install gcc pcre-devel zlib-devel openssl-devel -y
环境检测
注意不能有报错
开始编译
创建用户
启动
关闭
测试
关闭nginx的debug功能
编写环境变量(把nginx软件的命令执行路径添加到环境变量中)
[root@nginx ~]# vim ~/.bash_profile
[root@nginx ~]# source ~/.bash_profile
nginx的平滑升级及版本回滚
下载安装包
上传需要加载的模块
解压缩
[root@nginx ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx ~]# tar zxf nginx-1.26.2.tar.gz
开始编译新版本
需要加入echo-nginx-module-0.63这个模块
编译完成make一下,注意不能make install
![](https://i-blog.csdnimg.cn/direct/131bd6abe9084a6fb98427f0f61c11af.png)
![](https://i-blog.csdnimg.cn/direct/4ba7f56c6fe849f59f70f485264a3e87.png)
![](https://i-blog.csdnimg.cn/direct/c46d126cc61349b4a36fb123269c3424.png)
![](https://i-blog.csdnimg.cn/direct/59904696d83f4f76b5b6cb97165ed854.png)
![](https://i-blog.csdnimg.cn/direct/f727548494dd4c26bf66cd9e3ea6cee0.png)
![](https://i-blog.csdnimg.cn/direct/ce8d494ab40f4833b570bf9ff30843c9.png)
![](https://i-blog.csdnimg.cn/direct/a62d52ba215c47f8a6a20f2004c08283.png)
![](https://i-blog.csdnimg.cn/direct/cf22d6cb0bb9493099eb8e1efbefbad2.png)
可以选择隐藏nginx的版本
需要编辑/root/nginx-1.24.0/src/core下的nginx.h这个文件
修个这块即可
Nginx的进程结构
主进程(Master Process):
- 负责读取和验证配置文件。它会确保配置的正确性和完整性,如果配置存在错误,主进程会阻止 Nginx 启动,并给出相应的错误提示。
- 启动、管理和监控工作进程。主进程会根据配置文件中指定的工作进程数量创建相应数量的工作进程。
- 处理系统信号。例如,当接收到
SIGHUP
信号(通常用于重新加载配置)时,主进程会重新读取配置文件,并向工作进程发送指令以重新加载配置。 - 负责平滑升级。在进行 Nginx 版本升级时,主进程可以在不中断服务的情况下完成升级操作。
工作进程(Worker Process):
- 工作进程是实际处理客户端请求的部分。它们直接与客户端进行通信,接收和处理请求,并返回响应。
- 每个工作进程都是独立运行的,它们之间不会共享状态信息,这提高了系统的稳定性和容错性。即使某个工作进程出现故障,其他工作进程仍然能够正常工作,不会导致整个服务中断。
- 工作进程采用事件驱动的方式工作。这意味着它们会高效地等待和处理网络事件(如连接建立、数据接收、数据发送等),从而能够同时处理大量的并发连接。
缓存加载进程(Cache Loader Process):
- 主要负责在启动时将磁盘中的缓存数据加载到内存中,以提高缓存的访问速度。
缓存管理器进程(Cache Manager Process):
- 负责定期检查缓存的有效性和过期情况,并对过期或无效的缓存数据进行清理和更新,以保证缓存的准确性和有效性。
例如,假设一个网站在高峰期每秒收到 1000 个请求,Nginx 的多个工作进程可以同时处理这些请求,快速地将响应返回给客户端。而主进程则在后台监控整个系统的运行状态,确保一切正常。如果需要修改配置,比如增加新的虚拟主机配置,主进程会重新读取配置并指示工作进程应用新的配置,而整个过程中服务不会中断。
Nginx 进程间通信
信号(Signals):
- Nginx 的主进程可以通过向工作进程发送信号来实现控制和通信。常见的信号如
SIGHUP
用于重新加载配置,SIGTERM
用于优雅地关闭进程等。 - 例如,当管理员修改了 Nginx 的配置文件后,可以向主进程发送
SIGHUP
信号,主进程接收到信号后会重新读取配置并通知工作进程重新加载配置。
共享内存(Shared Memory):
- Nginx 可以使用共享内存来在进程之间共享数据。比如共享一些全局的配置信息、统计数据等。
- 例如,统计网站的访问量、请求的处理状态等信息可以存储在共享内存中,以便各个进程都能够访问和更新。
套接字(Sockets):
- 进程之间可以通过套接字进行通信,包括 Unix 域套接字和网络套接字。
- 例如,工作进程可以通过套接字向主进程报告一些运行时的状态信息。
文件锁(File Locks):
- 当多个进程需要对同一文件进行操作时,可以使用文件锁来保证操作的原子性和一致性。
- 比如在更新一些关键的配置文件或日志文件时。
六、 Nginx 模块介绍
核心模块(Core Modules):
http_module
:处理 HTTP 相关的基本功能,如请求解析、响应生成等。event_module
:提供了对不同事件模型的支持,如epoll
、kqueue
等,以提高网络性能。
HTTP 模块(HTTP Modules):
http_gzip_module
:对响应数据进行 Gzip 压缩,减少数据传输量,提高传输效率。http_rewrite_module
:用于重写 URL,实现 URL 跳转和规则匹配。http_proxy_module
:支持反向代理功能,将请求转发到后端服务器。http_ssl_module
:处理 HTTPS 协议相关的配置和加密解密操作。
负载均衡模块(Load Balancing Modules):
upstream_module
:定义上游服务器组,并实现负载均衡策略,如轮询、加权轮询、IP 哈希等。
访问控制模块(Access Control Modules):
http_access_module
:基于 IP 地址或网络段来控制对服务器的访问权限。http_auth_basic_module
:实现基本的 HTTP 认证功能。
缓存模块(Caching Modules):
proxy_cache_module
:为反向代理提供缓存功能,提高响应速度。
七、Nginx常用命令及参数
[root@nginx ~]# nginx -vnginx version: nginx/1.18.0Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]Options:-?,-h : this help-v : show version and exit-V : show version and configure options then exit # 显示版本和编译参数-t : test configuration and exit # 测试配置文件是否异-T : test configuration, dump it and exit # 测试并打印-q : suppress non-error messages during configuration testing # 静默模式-s signal : send signal to a master process: stop, quit, reopen, reload #发送信号 ,reload 信号 会生成新的 worker, 但 master 不会重新生成-p prefix : set prefix path (default: /etc/nginx/) # 指定 Nginx 目录-c filename : set configuration file (default: /etc/nginx/nginx.conf) #配置文件路径-g directives : set global directives out of configuration file # 设置全局指令 , 注意和配置文件不要同时配置 , 否则冲突
八、Nginx服务的启动脚本编写
[root@nginx ~]# vim /lib/systemd/system/nginx.service
Description 描述
After 启动nginx服务时,这些服务会被自动激活
wants 依赖性
Type 类型
PIDFile pid的路径
ExecStartPre 启动nginx服务时,检查配置文件是否有错误
ExecStart 真实启动的命令
九、Nginx全局配置参数优化调整
配置文件说明
nginx 官方帮助文档: http://nginx.org/en/docs/Nginx 的配置文件的组成部分:主配置文件: nginx.conf子配置文件 : include conf.d/*.conffastcgi , uwsgi , scgi 等协议相关的配置文件mime.types :支持的 mime 类型, MIME(Multipurpose Internet Mail Extensions) 多用途互联网邮件扩展类型, MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
nginx 配置文件格式说明
配置文件由指令与指令块构成每条指令以 ; 分号结尾,指令与值之间以空格符号分隔可以将多条指令放在同一行 , 用分号分隔即可 , 但可读性差 , 不推荐指令块以 { } 大括号将多条指令组织在一起 , 且可以嵌套指令块include 语句允许组合多个配置文件以提升可维护性使用 # 符号添加注释,提高可读性使用 $ 符号使用变量部分指令的参数支持正则表达式
主配置文件结构:四部分
main block :主配置段,即全局配置段,对 http,mail 都有效# 事件驱动相关的配置event {...}#http/https 协议相关配置段http {...}# 默认配置文件不包括下面两个块#mail 协议相关配置段mail {...}#stream 服务器相关配置段stream {...}
默认的nginx.conf 配置文件格式说明
# 全局配置端,对全局生效,主要设置 nginx 的启动用户 / 组,启动的工作进程数量,工作模式, Nginx 的 PID 路径,日志路径等。user nginx nginx;worker_processes 1; # 启动工作进程数数量events { #events # 设置快,主要影响 nginx 服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型 # 处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。worker_connections 1024; # 设置单个 nginx 工作进程可以接受的最大并发,作为 web 服务器的时候最大并发数为 #worker_connections *worker_processes ,作为反向代理的时候为#(worker_connections * worker_processes)/2}http { #http 块是 Nginx 服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都 # 可以在这设置, http 块可以包含多个 server 块,而一个 server 块中又可以包含多个 location 块,#server 块可以配置文件引入、 MIME-Type 定义、日志自定义、是否启用 sendfile 、连接超时时间和 # 单个链接的请求上限等。include mime.types;default_type application/octet-stream;sendfile on; # 作为 web 服务器的时候打开 sendfile 加快静态文件传输,指定是否使用#sendfile 系统调用来传输文件#sendfile 系统调用在两个文件描述符之间直接传递数据 ( 完全在内核中操作 )# 从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,# 硬盘 >> kernel buffer ( 快速拷贝到 kernelsocketbuffer) >> 协议栈。keepalive_timeout 65; # 长连接超时时间,单位是秒server { # 设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个 location 模块# 比如本虚拟机监听的端口、本虚拟机的名称和 IP 配置,多个server 可以使用一个端口比如都使用 #80 端口提供 web 服务listen 80; # 配置 server 监听的端口server_name localhost; # 本 server 的名称,当访问此名称的时候 nginx 会调用当前 serevr内部的配置进程匹配。location / { #location 其实是 server 的一个指令,为 nginx 服务器提供比较多而且灵活的指令# 都是在 location 中体现的,主要是基于 nginx 接受到的请求字符串# 对用户请求的 UIL 进行匹配,并对特定的指令进行处理# 包括地址重定向、数据缓存和应答控制等功能都是在这部分实现# 另外很多第三方模块的配置也是在 location 模块中配置。root html; # 相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。index index.html index.htm; # 默认的页面文件名称}error_page 500 502 503 504 /50x.html; # 错误页面的文件名称location = /50x.html { #location 处理对应的不同错误码的页面定义到 /50x.html# 这个跟对应其 server 中定义的目录下。root html; # 定义默认页面所在的目录}}# 和邮件相关的配置#mail {# ...# } mail 协议相关配置段#tcp 代理配置, 1.9 版本以上支持#stream {# ...# } stream 服务器相关配置段# 导入其他路径的配置文件#include /apps/nginx/conf.d/*.conf}
[root@nginx ~]# vim /etc/security/limits.conf
十、Nginx配置中的root和alias
root # 给定的路径对应于 location 中的 /uri 左侧的 /alias # 给定的路径对应于 location 中的 /uri 的完整路径
我们新建一个子配置文件(注意要写在前面,写到后面不生效)
写解析
root
alias
十一、Nginx-location用法详解
在一个 server 中 location 配置段可存在多个,用于实现从 uri 到文件系统的路径映射;ngnix 会根据用户请求的 URI 来检查定义的所有 location ,按一定的优先级找出一个最佳匹配,而后应用其配置在没有使用正则表达式的时候, nginx 会先在 server 中的多个 location 选取匹配度最高的一个 uriuri 是用户请求的字符串,即域名后面的 web 文件路径然后使用该 location 模块中的正则 url 和字符串,如果匹配成功就结束搜索,并使用此 location 处理此请求。
# 语法规则:location [ = | ~ | ~* | ^~ ] uri { ... }= # 用于标准 uri 前,需要请求字串与 uri 精确匹配,大小敏感 , 如果匹配成功就停止向下匹配并立即处理请求^~ # 用于标准 uri 前,表示包含正则表达式 , 并且匹配以指定的正则表达式开头# 对 uri 的最左边部分做匹配检查,不区分字符大小写~ # 用于标准 uri 前,表示包含正则表达式 , 并且区分大小写~* # 用于标准 uri 前,表示包含正则表达式 , 并且不区分大写不带符号 # 匹配起始于此 uri 的所有的 uri\ # 用于标准 uri 前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号优先级
(~* = ~)> 不带符号 > ^~ > =
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立
两个比较一下(无符号的优先级大于 “=” 的优先级)
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
十二、Nginx下的用户认证
由 ngx_http_auth_basic_module 模块提供此功能
十三、Nginx自定义错误页面
十四、Nginx自定义日志
十五、Nginx中的文件检测
Syntax: try_files file ... uri;try_files file ... =code;Default: —Context: server, location
![](https://i-blog.csdnimg.cn/direct/a62e49cff5ab473ab40475c9eb55cf02.png)
十六、Nginx中的长链接的管理
keepalive_timeout timeout [header_timeout]; # 设定保持连接超时时长, 0 表示禁止长连接,默认为 75s# 通常配置在 http 字段作为站点全局配置keepalive_requests 数字 ; # 在一次长连接上所允许请求的资源的最大数量# 默认为 100 次 , 建议适当调大 , 比如 :500keepalive_requests 3;keepalive_timeout 65 60;# 开启长连接后,返回客户端的会话保持时间为 60s ,单次长连接累计请求达到指定次数请求或 65 秒就会被断开,第二个数字 60 为发送给客户端应答报文头部中显示的超时时间设置为 60s :如不设置客户端将不显示超时时间。Keep-Alive:timeout=60 # 浏览器收到的服务器返回的报文# 如果设置为 0 表示关闭会话保持功能,将如下显示:#Connection:close 浏览器收到的服务器返回的报文
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
这里是主配置文件不是子配置文件
下载测试工具
![](https://i-blog.csdnimg.cn/direct/b7ef758c603142dca83ef122b271974f.png)
![](https://i-blog.csdnimg.cn/direct/dcfbe3f35ab2487dbdec6f94ba53cf80.png)
![](https://i-blog.csdnimg.cn/direct/3661e052dbec42f09b8f99bd7b720137.png)
十七、Nginx下载服务器的设定及优化
相关指令:
autoindex on | off; # 自动文件索引功能,默为 offautoindex_exact_size on | off; # 计算文件确切大小(单位 bytes ), off 显示大概大小(单位 K 、M) ,默认 onautoindex_localtime on | off ; # 显示本机时间而非 GMT( 格林威治 ) 时间,默认 offautoindex_format html | xml | json | jsonp; # 显示索引的页面文件风格,默认 htmllimit_rate rate; # 限制响应客户端传输速率 ( 除 GET 和 HEAD 以外的所有方法 ) ,单位 B/s,bytes/second, # 默认值 0, 表示无限制 , 此指令由ngx_http_core_module 提供set $limit_rate 4k; # 也可以通变量限速 , 单位 B/s, 同时设置 , 此项优级高 .
点击可直接下载
这里的时间不是本地的时间,是格林尼治时间
文件粗略大小
限速(默认不限速)
十八、Nginx的状态页面
# 配置示例:location /nginx_status {stub_status;auth_basic "auth login";auth_basic_user_file /apps/nginx/conf/.htpasswd;allow 192.168.0.0/16;allow 127.0.0.1;deny all;}# 状态页用于输出 nginx 的基本状态信息:# 输出信息示例:Active connections: 291server accepts handled requests16630948 16630948 31070465上面三个数字分别对应 accepts,handled,requests 三个值Reading: 6 Writing: 179 Waiting: 106Active connections: # 当前处于活动状态的客户端连接数# 包括连接等待空闲连接数 =reading+writing+waitingaccepts : # 统计总值, Nginx 自启动后已经接受的客户端请求连接的总数。handled: # 统计总值, Nginx 自启动后已经处理完成的客户端请求连接总数# 通常等于 accepts ,除非有因 worker_connections 限制等被拒绝的连接requests: # 统计总值, Nginx 自启动后客户端发来的总的请求数Reading: # 当前状态,正在读取客户端请求报文首部的连接的连接数# 数值越大 , 说明排队现象严重 , 性能不足Writing: # 当前状态,正在向客户端发送响应报文过程中的连接数 , 数值越大 , 说明访问量很大Waiting: # 当前状态,正在等待客户端发出请求的空闲连接数开启 keep-alive 的情况下 , 这个值等于 active –(reading+writing)
但是状态也不能随便让人去看,需要指定
十九、Nginx的数据压缩功能
# 启用或禁用 gzip 压缩,默认关闭gzip on | off;# 压缩比由低到高从 1 到 9 ,默认为 1 ,值越高压缩后文件越小,但是消耗 cpu 比较高。基本设定未 4 或者 5gzip_comp_level 4;# 禁用 IE6 gzip 功能,早期的 IE6 之前的版本不支持压缩gzip_disable "MSIE [1-6]\.";#gzip 压缩的最小文件,小于设置值的文件将不会压缩gzip_min_length 1k;# 启用压缩功能时,协议的最小版本,默认 HTTP/1.1gzip_http_version 1.0 | 1.1;# 指定 Nginx 服务需要向服务器申请的缓存空间的个数和大小 , 平台不同 , 默认 :32 4k 或者 16 8k;gzip_buffers number size;# 指明仅对哪些类型的资源执行压缩操作 ; 默认为 gzip_types text/html ,不用显示指定,否则出错gzip_types mime-type ...;# 如果启用压缩,是否在响应报文首部插入 “Vary: Accept-Encoding”, 一般建议打开gzip_vary on | off;# 预压缩,即直接从磁盘找到对应文件的 gz 后缀的式的压缩文件返回给用户,无需消耗服务器 CPU# 注意 : 来自于 ngx_http_gzip_static_module 模块gzip_static on | off;
在nginx的主配置文件加入
二十、Nginx中的变量
内置变量
常用内置变量
$remote_addr;# 存放了客户端的地址,注意是客户端的公网 IP$args;# 变量中存放了 URL 中的所有参数# 例如 :https://search.jd.com/Search?keyword= 手机 &enc=utf-8# 返回结果为 : keyword= 手机 &enc=utf-8$is_args# 如果有参数为 ? 否则为空$document_root;# 保存了针对当前资源的请求的系统根目录 , 例如 :/webdata/nginx/timinglee.org/lee 。$document_uri;# 保存了当前请求中不包含参数的 URI ,注意是不包含请求的指令# 比如 :http://lee.timinglee.org/var?\id=11111 会被定义为 /var# 返回结果为 :/var$host;# 存放了请求的 host 名称limit_rate 10240;echo $limit_rate;# 如果 nginx 服务器使用 limit_rate 配置了显示网络速率,则会显示,如果没有设置, 则显示 0$remote_port;# 客户端请求 Nginx 服务器时随机打开的端口,这是每个客户端自己的端口$remote_user;# 已经经过 Auth Basic Module 验证的用户名$request_body_file;# 做反向代理时发给后端服务器的本地资源的名称$request_method;# 请求资源的方式, GET/PUT/DELETE 等$request_filename;# 当前请求的资源文件的磁盘路径,由 root 或 alias 指令与 URI 请求生成的文件绝对路径,# 如 :webdata/nginx/timinglee.org/lee/var/index.html$request_uri;# 包含请求参数的原始 URI ,不包含主机名,相当于 :$document_uri?$args,# 例如: /main/index.do?id=20190221&partner=search$scheme;# 请求的协议,例如 :http , https,ftp 等$server_protocol;# 保存了客户端请求资源使用的协议的版本,例如 :HTTP/1.0 , HTTP/1.1 , HTTP/2.0 等$server_addr;# 保存了服务器的 IP 地址$server_name;# 虚拟主机的主机名$server_port;# 虚拟主机的端口号$http_user_agent;# 客户端浏览器的详细信息$http_cookie;# 客户端的所有 cookie 信息$cookie_<name>#name 为任意请求报文首部字部 cookie 的 key 名$http_<name>#name 为任意请求报文首部字段 , 表示记录请求报文的首部字段, ame 的对应的首部字段名需要为小写,如果有横线需要替换为下划线
自定义变量
假如需要自定义变量名称和值,使用指令set $variable value;
二十一、Nginx中的rewrite模块功能
Nginx 服务器利用 ngx_http_rewrite_module 模块解析和处理 rewrite 请求此功能依靠 PCRE(perl compatible regular expression) ,因此编译之前要安装 PCRE 库rewrite 是 nginx 服务器的重要功能之一,用于实现 URL 的重写, URL 的重写是非常有用的功能比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问另外还可以在一定程度上提高网站的安全性。
if 指令
if (条件匹配) {action}
= # 比较变量和字符串是否相等,相等时 if 指令认为该条件为 true ,反之为 false!= # 比较变量和字符串是否不相等,不相等时 if 指令认为条件为 true ,反之为 false~ # 区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假!~ # 区分大小写字符 , 判断是否匹配,不满足匹配条件为真,满足匹配条件为假~* # 不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假!~* # 不区分大小字符 , 判断是否匹配,满足匹配条件为假,不满足匹配条件为真-f 和 !-f # 判断请求的文件是否存在和是否不存在-d 和 !-d # 判断请求的目录是否存在和是否不存在-x 和 !-x # 判断文件是否可执行和是否不可执行-e 和 !-e # 判断请求的文件或目录是否存在和是否不存在 ( 包括文件,目录,软链接 )# 注意:# 如果 $ 变量的值为空字符串或 0 ,则 if 指令认为该条件为 false ,其他条件为 true 。#nginx 1.0.1 之前 $ 变量的值如果以 0 开头的任意字符串会返回 false
break 指令
return 指令
rewrite 指令
rewrite regex replacement [flag];
. # 匹配除换行符以外的任意字符\w # 匹配字母或数字或下划线或汉字\s # 匹配任意的空白符\d # 匹配数字\b # 匹配单词的开始或结束^ # 匹配字付串的开始$ # 匹配字符串的结束* # 匹配重复零次或更多次+ # 匹配重复一次或更多次? # 匹配重复零次或一次(n) # 匹配重复 n 次{n,} # 匹配重复 n 次或更多次{n,m} # 匹配重复 n 到 m 次*? # 匹配重复任意次,但尽可能少重复+? # 匹配重复 1 次或更多次,但尽可能少重复?? # 匹配重复 0 次或 1 次,但尽可能少重复{n,m}? # 匹配重复 n 到 m 次,但尽可能少重复{n,}? # 匹配重复 n 次以上,但尽可能少重复\W # 匹配任意不是字母,数字,下划线,汉字的字符\S # 匹配任意不是空白符的字符\D # 匹配任意非数字的字符\B # 匹配不是单词开头或结束的位置[^x] # 匹配除了 x 以外的任意字符[^lee] # 匹配除了 magedu 这几个字母以外的任意字符
rewrite flag 使用介绍
Syntax: rewrite regex replacement [flag]; # 通过正则表达式处理用户请求并返回替换后的数据包。Default: —Context: server, location, if
flag 说明
redirect;# 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新 URL 给客户端# 由客户端重新发起请求 ; 使用相对路径 , 或者 http:// 或 https:// 开头,状态码: 302permanent;# 重写完成后以永久重定向方式直接返回重写后生成的新 URL 给客户端# 由客户端重新发起请求,状态码: 301break;# 重写完成后 , 停止对当前 URL 在当前 location 中后续的其它重写操作# 而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在 location 中使用# 适用于一个 URL 一次重写last;# 重写完成后 , 停止对当前 URI 在当前 location 中后续的其它重写操作,# 而后对新的 URL 启动新一轮重写检查,不建议在 location 中使用# 适用于一个 URL 多次重写,要注意避免出现超过十次以及 URL 重写后返回错误的给用户
rewrite案例: 域名永久与临时重定向
![](https://i-blog.csdnimg.cn/direct/1d3251ef1a3b416d90246de8dd6e83cd.png)
![](https://i-blog.csdnimg.cn/direct/2d8276d576ef4258bbac369b3e8953c6.png)
rewrite 案例: break 与 last
二十二、Nginx-rewrite的企业示例及防盗链
rewrite案例: 自动跳转 https
创建目录
制作认证文件
编写配置文件
测试访问
不用输https直接跳转
判断文件是否存在
防盗链
none : # 请求报文首部没有 referer 首部,# 比如用户直接在浏览器输入域名访问 web 网站,就没有 referer 信息。blocked : # 请求报文有 referer 首部,但无有效值,比如为空。server_names : #referer 首部中包含本主机名及即 nginx 监听的 server_name 。arbitrary_string : # 自定义指定字符串,但可使用 * 作通配符。示例 : *.timinglee.orgwww.timinglee.*regular expression : # 被指定的正则表达式模式匹配到的字符串 , 要使用 ~ 开头,例如:~.*\.timinglee\.com
二十三、Nginx的反向代理及动静分离实现
什么是反向代理
反向代理是位于客户端和后端服务器之间的服务器。与正向代理(代表客户端向服务器发起请求)不同,反向代理接收来自客户端的请求,并将这些请求转发给后端的一个或多个服务器。然后,它将后端服务器的响应返回给客户端,就好像这个响应是直接来自反向代理服务器本身一样。
Nginx 反向代理的工作原理
- 客户端向 Nginx 服务器发送请求,请求的目标通常是一个域名或 IP 地址及端口号。
- Nginx 接收到请求后,根据配置的规则确定将请求转发到哪个后端服务器。
- Nginx 将请求转发给后端服务器,这个过程可以是通过不同的协议(如 HTTP、HTTPS、TCP 等)进行。
- 后端服务器处理请求,并将响应返回给 Nginx。
- Nginx 再将后端服务器的响应返回给客户端。
Nginx 反向代理的优势
-
负载均衡
- 通过将请求分发到多个后端服务器,可以平衡服务器的负载,避免单个服务器过载。Nginx 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希等,可以根据实际需求进行选择。
- 例如,在一个高流量的网站中,可以使用 Nginx 反向代理将请求分发到多个 Web 服务器上,以确保每个服务器都不会承受过大的压力。
-
安全防护
- 可以隐藏后端服务器的真实 IP 地址,增加系统的安全性。客户端只能看到 Nginx 的 IP 地址,而无法直接访问后端服务器。
- Nginx 还可以配置各种安全策略,如限制访问频率、过滤恶意请求等,进一步保护后端服务器。
-
缓存加速
- Nginx 可以缓存后端服务器的响应结果,当相同的请求再次到来时,直接返回缓存的结果,而无需再次向后端服务器发送请求。这可以大大提高响应速度,减少后端服务器的负载。
- 可以根据不同的请求路径、文件类型等设置缓存策略,以优化缓存效果。
-
动静分离
- 将静态资源(如图片、CSS、JavaScript 文件等)和动态资源(如 PHP、Java 等动态生成的页面)分别部署在不同的服务器上,然后通过 Nginx 反向代理进行请求分发。
- 对于静态资源,可以设置较长的缓存时间,以提高访问速度;对于动态资源,可以根据实际情况进行负载均衡和优化
ngx_http_proxy_module: # 将客户端的请求以 http 协议转发至指定服务器进行处理ngx_http_upstream_module # 用于定义为 proxy_pass,fastcgi_pass,uwsgi_pass# 等指令引用的后端服务器分组ngx_stream_proxy_module: # 将客户端的请求以 tcp 协议转发至指定服务器处理ngx_http_fastcgi_module: # 将客户端对 php 的请求以 fastcgi 协议转发至指定服务器助理ngx_http_uwsgi_module: # 将客户端对 Python 的请求以 uwsgi 协议转发至指定服务器处理
反向代理配置参数
proxy_pass; # 用来设置将客户端请求转发给的后端服务器的主机# 可以是主机名 ( 将转发至后端服务做为主机头首部 ) 、 IP 地址:端口的方式# 也可以代理到预先设置的主机群组,需要模块 ngx_http_upstream_module 支持proxy_hide_header field; # 用于 nginx 作为反向代理的时候# 在返回给客户端 http 响应时# 隐藏后端服务器相应头部的信息# 可以设置在 http,server 或 location 块proxy_pass_header field; # 透传# 默认 nginx 在响应报文中不传递后端服务器的首部字段 Date, Server, X-Pad, X-Accel 等参数# 如果要传递的话则要使用 proxy_pass_header field 声明将后端服务器返回的值传递给客户端#field 首部字段大小不敏感proxy_pass_request_body on | off;# 是否向后端服务器发送 HTTP 实体部分 , 可以设置在 http,server 或 location 块,默认即为开启proxy_pass_request_headers on | off;# 是否将客户端的请求头部转发给后端服务器,可以设置在 http,server 或 location 块,默认即为开启proxy_set_header;# 可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实 IP 的时候,就要更改每一个报文的头部proxy_connect_timeout time;# 配置 nginx 服务器与后端服务器尝试建立连接的超时时间,默认为 60 秒用法如下: proxy_connect_timeout 6s;#60s 为自定义 nginx 与后端服务器建立连接的超时时间 , 超时会返回客户端 504 响应码proxy_read_timeout time;# 配置 nginx 服务器向后端服务器或服务器组发起 read 请求后,等待的超时时间,默认 60sproxy_send_timeout time;# 配置 nginx 项后端服务器或服务器组发起 write 请求后,等待的超时 时间,默认 60sproxy_http_version 1.0;# 用于设置 nginx 提供代理服务的 HTTP 协议的版本,默认 http 1.0proxy_ignore_client_abort off;# 当客户端网络中断请求时, nginx 服务器中断其对后端服务器的请求。即如果此项设置为 on 开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off ,则客户端中断后 Nginx 也会中断客户端请求并立即记录499 日志,默认为 off 。
![](https://i-blog.csdnimg.cn/direct/73a5880c37f44587a04d4af3175b3a5c.png)
![](https://i-blog.csdnimg.cn/direct/4114d5e87cc04e4bac461006bf090290.png)
动静分离
二十四、Nginx反向代理的缓存功能
缓存的作用
-
提高响应速度
- 当客户端请求一个资源时,如果 Nginx 缓存中已经有该资源,就可以直接从缓存中返回响应,而无需再次向后端服务器请求,大大减少了响应时间。
- 尤其对于动态内容,缓存可以减少后端服务器的负载,提高整个系统的吞吐量。
-
减轻后端服务器压力
- 大量的重复请求可以由 Nginx 缓存来处理,后端服务器只需处理那些不在缓存中的请求或者缓存过期的请求,从而降低了后端服务器的负载。
缓存的工作原理
-
缓存存储
- Nginx 将反向代理获取到的资源存储在本地磁盘或内存中,具体的存储位置可以通过配置指定。
- 缓存的资源包括静态文件(如图片、CSS、JavaScript 文件等)和动态内容(如由后端服务器生成的 HTML 页面)。
-
缓存命中与未命中
- 当客户端发起请求时,Nginx 首先检查缓存中是否存在该请求的资源。
- 如果缓存命中,Nginx 直接从缓存中读取资源并返回给客户端。
- 如果缓存未命中,Nginx 会将请求转发到后端服务器,获取资源后再返回给客户端,并将资源缓存起来,以便下次请求时使用。
-
缓存过期策略
- Nginx 可以根据不同的策略来确定缓存的过期时间。常见的策略包括:
- 时间过期:设置一个固定的时间,例如 1 小时或 1 天,超过这个时间后缓存的资源被认为过期。
- 条件过期:根据后端服务器返回的响应头中的信息来判断缓存是否过期。例如,如果后端服务器返回的响应头中包含 “Cache-Control” 或 “Expires” 字段,Nginx 可以根据这些字段的值来确定缓存的过期时间。
- Nginx 可以根据不同的策略来确定缓存的过期时间。常见的策略包括:
proxy_cache zone_name | off; 默认 off# 指明调用的缓存,或关闭缓存机制 ;Context:http, server, location#zone_name 表示缓存的名称 . 需要由 proxy_cache_path 事先定义proxy_cache_key string;# 缓存中用于 “ 键 ” 的内容,默认值: proxy_cache_key $scheme$proxy_host$request_uri;proxy_cache_valid [code ...] time;# 定义对特定响应码的响应内容的缓存时长,定义在 http{...} 中在 http 配置定义缓存信息proxy_cache_path /var/cache/nginx/proxy_cache # 定义缓存保存路径, proxy_cache 会自动创建levels=1:2:2 #定义缓存目录结构层次#1:2:2 可以生成 2^4x2^8x2^8=2^20=1048576个目录keys_zone=proxycache:20m # 指内存中缓存的大小,主要用于存放 key 和 metadata(如:使用次数)# 一般 1M 可存放 8000 个左右的 keyinactive=120s # 缓存有效时间max_size=10g; # 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值# 调用缓存功能,需要定义在相应的配置段,如 server{...}; 或者 location 等proxy_cache proxycache;proxy_cache_key $request_uri; # 对指定的数据进行 MD5 的运算做为缓存的 keyproxy_cache_valid 200 302 301 10m; # 指定的状态码返回的数据缓存多长时间proxy_cache_valid any 1m; # 除指定的状态码返回的数据以外的缓存多长时间 , 必须设置 ,否则不会缓存proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |http_502 | http_503 | http_504 | http_403 | http_404 | off ; # 默认是 off# 在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端# 示例proxy_cache_use_stale error http_502 http_503;proxy_cache_methods GET | HEAD | POST ...;# 对哪些客户端请求方法对应的响应进行缓存, GET 和 HEAD 方法总是被缓存
非缓存场景压测
[root@web1 ~]# ab -n1000 -c100 http://www.timingtc.org/static/index.html
主配置文件
测试
[root@web1 ~]# ab -n1000 -c100 http://www.timingtc.org/static/index.html
二十五、Nginx的反向代理负载均衡
负载均衡的作用
-
提高系统可用性
- 通过将请求分发到多个后端服务器上,即使其中一台服务器出现故障,其他服务器仍然可以继续处理请求,从而提高了整个系统的可用性。
- 避免了单点故障,确保系统能够持续稳定地运行。
-
提升系统性能
- 负载均衡可以将请求均匀地分配到不同的服务器上,充分利用各服务器的资源,避免某些服务器负载过高而其他服务器闲置的情况。
- 提高了系统的吞吐量和响应速度,能够更好地满足大量用户的并发请求。
负载均衡的工作原理
-
客户端请求
- 当客户端发送请求时,请求首先到达 Nginx 服务器。
-
Nginx 分配请求
- Nginx 根据预先配置的负载均衡算法,将请求转发到后端的一个或多个服务器上。
- 常见的负载均衡算法有轮询(round-robin)、加权轮询(weighted round-robin)、IP 哈希(ip_hash)等。
-
后端服务器处理请求
- 后端服务器接收到请求后,进行相应的处理,并将响应返回给 Nginx。
-
Nginx 返回响应
- Nginx 收到后端服务器的响应后,将其转发给客户端。
http upstream配置参数
# 自定义一组服务器,配置在 http 块内upstream name {server ...........}# 示例upstream backend {server backend1.example.com weight=5;server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;server unix:/tmp/backend3;server backup1.example.com backup;}server address [parameters];# 配置一个后端 web 服务器,配置在 upstream 内,至少要有一个 server 服务器配置。#server 支持的 parameters 如下:weight=number # 设置权重,默认为 1, 实现类似于 LVS 中的 WRR,WLC 等max_conns=number # 给当前后端 server 设置最大活动链接数,默认为 0 表示没有限制max_fails=number # 后端服务器的下线条件 , 当客户端访问时 , 对本次调度选中的后端服务器连续进行检测多少次 , 如果都失败就标记为不可用 , 默认为 1 次 , 当客户端访问时 , 才会利用 TCP 触发对探测后端服务器健康性检查 , 而非周期性的探测fail_timeout=time # 后端服务器的上线条件 , 对已经检测到处于不可用的后端服务器 , 每隔此时间间隔再次进行检测是否恢复可用,如果发现可用 , 则将后端服务器参与调度 , 默认为 10 秒backup # 设置为备份服务器,当所有后端服务器不可用时 , 才会启用此备用服务器down # 标记为 down 状态 , 可以平滑下线后端服务器resolve # 当 server 定义的是主机名的时候,当 A 记录发生变化会自动应用新 IP 而不用重启Nginxhash KEY [consistent];# 基于指定请求报文中首部字段或者 URI 等 key 做 hash 计算,使用 consistent 参数,将使用 ketama 一致性hash 算法,适用于后端是 Cache 服务器(如 varnish )时使用, consistent 定义使用一致性 hash 运算,一致性 hash 基于取模运算hash $request_uri consistent; # 基于用户请求的 uri 做 hashhash $cookie_sessionid # 基于 cookie 中的 sessionid 这个 key 进行 hash 调度 , 实现会话绑定ip_hash;# 源地址 hash 调度方法,基于的客户端的 remote_addr( 源地址 IPv4 的前 24 位或整个 IPv6 地址 ) 做 hash 计算,以实现会话保持least_conn;# 最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器 , 相当于 LVS 中的 WLC
反向代理示例: 后端多台 web服务器
172.25.254.129 #Nginx 代理服务器172.25.254.128 # 后端 web A , Apache 部署172.25.254.10 # 后端 web B , Apache 部署
加入算法
实现 Nginx 四层负载均衡
tcp负载均衡配置参数
stream { # 定义 stream 相关的服务;Context:mainupstream backend { # 定义后端服务器hash $remote_addr consistent; # 定义调度算法server backend1.example.com:12345 weight=5; # 定义具体 serverserver 127.0.0.1:12345 max_fails=3 fail_timeout=30s;server unix:/tmp/backend3;}upstream dns { # 定义后端服务器server 10.0.0.1:53; # 定义具体 serverserver dns.example.com:53;}server { # 定义 serverlisten 12345; # 监听 IP:PORTproxy_connect_timeout 1s; # 连接超时时间proxy_timeout 3s; # 转发超时时间proxy_pass backend; # 转发到具体服务器组}server {listen 127.0.0.1:53 udp reuseport;proxy_timeout 20s;proxy_pass dns;}server {listen [::1]:12345;proxy_pass unix:/tmp/stream.socket;}}
负载均衡实例: MySQL
![](https://i-blog.csdnimg.cn/direct/8d3c96844269434686bd81c726d35f4d.png)
![](https://i-blog.csdnimg.cn/direct/2a25fd329b684703b7d1dc9585592d2d.png)
![](https://i-blog.csdnimg.cn/direct/a940f7bc2f034ad7bfbe0cd9e9764fbf.png)
![](https://i-blog.csdnimg.cn/direct/2f05090e33b648088acd9c51b36689af.png)
![](https://i-blog.csdnimg.cn/direct/44a79625bead42ccb94dd04c973b7f57.png)
[root@web1 ~]# mysql -utc -ptc -h172.25.254.129 -e "select @@server_id"
[root@web2 ~]# mysql -utc -ptc -h172.25.254.129 -e "select @@server_id"
二十六、Nginx源码编译php
CGI 的由来:最早的 Web 服务器只能简单地响应浏览器发来的 HTTP 请求,并将存储在服务器上的 HTML 文件返回给浏 览器,也就是静态html 文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技术,比如像php(1995 年 ) 、 java(1995) 、 python(1991) 语言开发的网站,但是 nginx/apache 服务器并不能直接运行 php 、 java 这样的文件, apache 实现的方式是打补丁,但是 nginx 缺通过与第三方基于协议实现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户的请求,处理完成后返回数据给 Nginx 并回收进程,最后 nginx 在返回给客户端,那这个约定就是通用网关接口(common gateway interface ,简称 CGI) , CGI (协议) 是 web 服务器和外部应用程序之间的接口标准,是cgi 程序和 web 服务器之间传递信息的标准化接口。
为什么会有 FastCGI ?CGI 协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server每收到一个请求都会创建一个CGI 进程, PHP 解析器都会解析 php.ini 文件,初始化环境,请求结束的时候再关闭进程,对于每一个创建的CGI 进程都会执行这些操作,所以效率很低,而 FastCGI 是用来提高 CGI 性能的, FastCGI 每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。什么是 PHP-FPM ?PHP-FPM(FastCGI Process Manager :FastCGI 进程管理器 ) 是一个实现了 Fastcgi 的程序,并且提供进程管理的功能。进程包括 master 进程和 worker 进程。 master 进程只有一个,负责监听端口,接受来自 web server的请求worker 进程一般会有多个,每个进程中会嵌入一个 PHP 解析器,进行 PHP 代码的处理。
FastCGI配置指令
# 转发请求到后端服务器, address 为后端的 fastcgi server 的地址,可用位置: location, if inlocationfastcgi_index name;#fastcgi 默认的主页资源,示例: fastcgi_index index.php;fastcgi_param parameter value [if_not_empty];# 设置传递给 FastCGI 服务器的参数值,可以是文本,变量或组合,可用于将 Nginx 的内置变量赋值给自定义keyfastcgi_param REMOTE_ADDR $remote_addr; # 客户端源 IPfastcgi_param REMOTE_PORT $remote_port; # 客户端源端口fastcgi_param SERVER_ADDR $server_addr; # 请求的服务器 IP 地址fastcgi_param SERVER_PORT $server_port; # 请求的服务器端口fastcgi_param SERVER_NAME $server_name; # 请求的 server nameNginx 默认配置示例:location ~ \.php$ {root /scripts;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # 默认脚本路径#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params; # 此文件默认系统已提供 , 存放的相对路径为prefix/conf}
源码编译PHP
上传需要的安装包
解压缩
编译nginx
下载可能需要的依赖
开始编译php
注意编译过程中的报错
出现下面的界面表示成功
二十七、Nginx-PHP的配置方法
生成php主配置文件
修改时区
生成启动脚本
二十八、Nginx和php的整合
写入环境变量
测试一下
二十九、Nginx和php的缓存优化
测试一下
[root@nginx ~]# ab -n1000 -c10 http://www.timingtc.org/index.php
上传相关的压缩包
解压缩
测试
三十、Nginx-memcache高速缓存
上传需要的压缩包并解压缩
编写配置文件
[root@nginx conf.d]# vim php.conf
测试
[root@nginx conf.d]# ab -n1000 -c10 http://www.timingtc.org/index.php