探秘 Nginx:为何它成为服务器领域的宠儿?

一、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 流程可以分为以下几个主要步骤:

  1. 建立连接:客户端向服务器发起连接请求,服务器接受连接并建立通信通道。这通常基于网络协议,如 TCP 协议。

    • 例如,在 Web 服务中,用户在浏览器中输入网址,浏览器通过 HTTP 协议向服务器发起连接请求。
  2. 接收请求:服务器等待并接收客户端发送的数据请求。

    • 比如,客户端可能发送一个获取网页内容的请求。
  3. 解析请求:服务器对收到的请求数据进行解析,理解客户端的需求。

    • 例如,解析请求的 URL、请求方法(GET、POST 等)、请求头和请求体中的参数等。
  4. 处理请求:根据解析出的请求内容,服务器执行相应的处理逻辑。这可能包括从数据库读取数据、进行计算、调用其他服务等。

    • 假设请求是查询用户信息,服务器会从数据库中查找相关用户的数据。
  5. 准备响应:服务器根据处理结果准备要发送回客户端的数据。

    • 如生成相应的网页内容、构建 JSON 格式的数据等。
  6. 发送响应:将准备好的响应数据通过网络发送回客户端。

    • 继续以上例子,将查询到的用户信息发送回客户端的浏览器。
  7. 关闭连接:在完成数据交互后,根据协议和配置,关闭连接或保持连接以处理后续请求。

在整个 I/O 流程中,可能会涉及到不同的 I/O 模式,如阻塞 I/O、非阻塞 I/O、异步 I/O 等,以适应不同的性能和场景需求。

例如,在一个在线游戏服务器中,当玩家进行操作时,服务器按照上述流程接收、处理请求,并及时发送响应,以实现游戏的实时交互。又比如,在文件下载服务器中,服务器接收客户端的下载请求,读取文件数据并发送给客户端,完成文件传输的 I/O 过程。

服务器的 I/O
磁盘 I/O
网络 I/O : 一切皆文件 , 本质为对 socket 文件的读写

磁盘 I/O

磁盘 I/O(输入 / 输出)是指计算机系统与磁盘设备之间的数据交换过程。

磁盘 I/O 主要包括读操作和写操作:

读操作
当系统需要从磁盘获取数据时,会发出读请求。操作系统会将请求发送到磁盘控制器,磁盘控制器控制磁盘的机械部件定位到存储所需数据的磁道和扇区,然后将数据读取到磁盘缓冲区,并最终传输到系统内存供应用程序使用。

写操作
当系统要将数据保存到磁盘时,会发起写请求。数据首先从内存传输到磁盘缓冲区,然后磁盘控制器将缓冲区中的数据写入到磁盘的指定位置。

磁盘 I/O 性能对计算机系统的整体性能有重要影响。一些影响磁盘 I/O 性能的因素包括:

  1. 磁盘转速:转速越高,数据传输速度通常越快。
  2. 寻道时间:磁头定位到数据所在磁道所需的时间,寻道时间越短,I/O 性能越好。
  3. 缓冲区大小:较大的磁盘缓冲区可以减少磁盘的实际读写次数,提高性能。
  4. 磁盘阵列(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.17ms
10000 转的机械盘平均延迟: 60*1000/10000/2 = 3ms
15000 转的机械盘平均延迟: 60*1000/15000/2 = 2ms
每秒最大 IOPS 的计算方法:
7200 转的磁盘 IOPS 计算方式: 1000 毫秒 /(9 毫秒的寻道时间 +4.17 毫秒的平均旋转延迟时
)=1000/13.13=75.9 IOPS
10000 转的磁盘的 IOPS 计算方式: 1000 毫秒 /(6 毫秒的寻道时间 +3 毫秒的平均旋转延迟时
)=1000/9=111IOPS
15000 转的磁盘的 IOPS 计算方式: 15000 毫秒 /(4 毫秒的寻道时间 +2 毫秒的平均旋转延迟时
)=1000/6=166.6 IOPS

 网络 I/O

网络 I/O(输入 / 输出)是指计算机系统通过网络进行数据的接收和发送过程。

在网络 I/O 中,主要包括以下几种常见的操作模式:

  1. 阻塞式 I/O:在进行数据读取或发送时,程序会一直等待,直到操作完成。如果数据尚未准备好,程序会被阻塞,无法进行其他操作。

    • 例如,使用传统的 socket 编程,在调用 recv 函数接收数据时,如果没有数据到达,程序会一直阻塞在那里。
  2. 非阻塞式 I/O:程序不会被阻塞,而是立即返回一个状态,表示操作是否完成。如果操作未完成,需要通过轮询不断检查状态,直到数据准备好。

    • 比如,在不断轮询检查网络套接字是否有数据可读的过程中,程序可以同时处理其他任务。
  3. I/O 多路复用:通过一个线程或进程同时监控多个网络连接,当有数据可读写时,通知相应的程序进行处理。常见的实现方式有 selectpoll 和 epoll 等。

    • 假设一个服务器同时处理多个客户端连接,使用 epoll 可以高效地管理这些连接,而无需为每个连接创建单独的线程。
  4. 异步 I/O:程序发起一个 I/O 操作后,无需等待操作完成,操作完成后会通过回调函数或其他方式通知程序。

网络 I/O 性能受到多种因素的影响,如网络带宽、延迟、数据包丢失率等。

例如,在一个高并发的 Web 服务器中,如果采用不合适的网络 I/O 模式,可能会导致大量连接请求被阻塞,服务器响应变慢。而使用高效的 I/O 多路复用或异步 I/O 模式,可以显著提高服务器的并发处理能力和性能。又如,在实时在线游戏中,低延迟的网络 I/O 对于保证游戏的流畅性和玩家体验至关重要,如果网络 I/O 出现延迟或卡顿,可能会导致游戏中的操作不及时响应

网络I/O 处理过程

网络 I/O 的处理过程通常包括以下几个主要阶段:

  1. 创建套接字(Socket):应用程序创建一个套接字来与网络进行通信。套接字是网络通信的端点,它定义了通信的协议(如 TCP 或 UDP)、本地地址和端口以及远程地址和端口等信息。

  2. 绑定(Binding):如果需要指定本地的地址和端口,应用程序将套接字与这些信息进行绑定。

  3. 连接(Connecting)(对于 TCP):在使用 TCP 协议时,如果是客户端,需要向服务器发起连接请求。服务器端则会监听并接受连接请求。

  4. 监听(Listening)(对于服务器):服务器端通过监听套接字等待客户端的连接请求。

  5. 数据发送(Sending Data):应用程序将要发送的数据写入到套接字的发送缓冲区。

  6. 数据传输

    • 操作系统将发送缓冲区中的数据通过网络协议栈进行封装和发送。
    • 网络中的路由器和交换机根据目标地址将数据包转发到目的地。
  7. 数据接收(Receiving Data)

    • 当数据包到达接收端时,操作系统将其存储在接收缓冲区中。
    • 应用程序从接收缓冲区读取数据。
  8. 错误处理:在整个网络 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 模型

  1. 阻塞型 I/O 模型

    • 特点:在进行 I/O 操作时,如果数据未准备好,进程或线程会被阻塞,直到操作完成。
    • 示例:当使用阻塞型套接字进行网络通信时,如果接收缓冲区没有数据,调用 recv 函数的线程会被阻塞,直到有数据到达。
    • 优点:编程简单,逻辑清晰。
    • 缺点:在高并发场景下,大量线程被阻塞会导致系统资源浪费,性能低下。
  2. 非阻塞型 I/O 模型

    • 特点:进程或线程在数据未准备好时不会被阻塞,而是立即返回一个错误或特定的状态。
    • 示例:使用非阻塞套接字,当调用 recv 函数而没有数据时,函数会立即返回 -1 和错误码 EWOULDBLOCK ,表示当前没有数据可接收。
    • 优点:不会因为等待 I/O 操作而阻塞线程,提高了资源利用率。
    • 缺点:需要通过轮询不断检查 I/O 状态,增加了 CPU 开销。
  3. 复用型 I/O 模型(select、poll、epoll)

    • 特点:通过一个函数同时监听多个文件描述符(套接字)的状态,当有任何一个描述符准备好进行 I/O 操作时,函数返回。
    • 示例:使用 select 函数可以同时监听多个套接字,当其中某个套接字有数据可读或可写时,select 函数返回,并告知哪些套接字处于就绪状态。
    • 优点:避免了对单个套接字的频繁轮询,减少了系统开销。
    • 缺点:select 和 poll 在处理大量文件描述符时效率较低,epoll 在大规模并发场景下表现更好。
  4. 信号驱动型 I/O 模型

    • 特点:进程通过安装一个信号处理函数,当数据准备好时,内核发送一个信号通知进程。
    • 示例:在网络编程中,设置好信号处理函数后,当网络数据到达时,内核发送信号通知进程。
    • 优点:避免了阻塞和轮询。
    • 缺点:在实际应用中较少使用,因为信号处理可能会比较复杂。
  5. 异步 I/O 模型

    • 特点:进程发起 I/O 操作后立即返回,内核在完成 I/O 操作后通知进程。
    • 示例:使用异步 I/O 接口,如 aio_read ,发起读操作后进程继续执行其他任务,当读操作完成时,通过回调函数或其他方式通知进程。
    • 优点:提供了最高的并发性能和响应性。
    • 缺点:实现复杂,依赖操作系统的支持。

 I/O 的常见具体实现方式

  1. select

    • 工作方式:通过轮询的方式检查文件描述符集合中哪些描述符就绪。
    • 缺点:能监视的文件描述符数量有限,通常为 1024 个;每次调用都需要重新设置文件描述符集合;返回时需要遍历整个集合来确定哪些描述符就绪。
  2. poll

    • 类似于 select ,但没有文件描述符数量的限制。
    • 缺点:与 select 一样,每次调用都需要重新设置描述符集合,并且返回时需要遍历。
  3. epoll

    • 工作方式:基于事件驱动,当文件描述符就绪时,内核将事件通知给应用程序。
    • 优点:没有最大文件描述符数量的限制;高效的事件通知机制,不需要每次都重新设置和遍历描述符集合。

 四、零拷贝

零拷贝(Zero-Copy)是一种在计算机系统中优化数据传输操作的技术,旨在减少数据在内存之间的不必要复制,从而提高数据传输的性能和效率。

在传统的数据传输过程中,通常需要多次的数据拷贝操作。例如,从磁盘读取文件并通过网络发送时,数据可能要从磁盘拷贝到内核缓冲区,然后再从内核缓冲区拷贝到用户空间缓冲区,最后从用户空间缓冲区拷贝到网络缓冲区进行发送。

而零拷贝技术通过避免或减少这些不必要的拷贝,直接将数据从源(如磁盘)传输到目标(如网络),或者在某些情况下,只进行一次必要的拷贝。

零拷贝技术的优点包括:

  1. 显著提高数据传输的性能,减少了 CPU 开销和内存带宽的占用。
  2. 降低了数据传输的延迟,特别是在处理大量数据时效果更为明显。

常见的实现零拷贝的方式有:

  1. mmap(内存映射):将文件映射到进程的地址空间,减少了一次数据拷贝。
  2. sendfile 系统调用:在支持的操作系统中,可以直接将数据从文件描述符传输到网络套接字,避免了用户空间和内核空间之间的数据拷贝。

例如,在一个高性能的文件服务器中,如果需要频繁地将大文件发送给客户端,使用零拷贝技术可以极大地提高文件传输的速度,提升服务器的整体性能和响应能力。

 五、Nginx 架构和安装

 Nginx 介绍

Nginx 是一款轻量级、高性能的 Web 服务器和反向代理服务器,具有以下显著特点和优势:

特点

  1. 高并发处理能力:采用异步非阻塞的方式处理请求,能够高效应对大量并发连接。
  2. 低资源消耗:相较于其他服务器,Nginx 对系统资源的需求较少,尤其是内存占用低。
  3. 反向代理和负载均衡:可以将请求分发到多个后端服务器,提高系统的可用性和扩展性。
  4. 灵活的配置:通过简单易懂的配置文件,实现各种复杂的功能和策略。

优势

  1. 快速响应:能够迅速处理请求,减少用户等待时间,提供良好的用户体验。
  2. 稳定性高:在高负载情况下仍能保持稳定运行,不易出现故障。
  3. 易于扩展:可以方便地添加模块和功能,以满足不同的需求。

应用场景

  1. Web 服务器:为静态网页和动态内容提供服务。
  2. 反向代理:隐藏后端服务器的真实 IP,增强安全性。
  3. 负载均衡:将流量均匀分配到多个服务器,提高系统整体性能。

例如,许多大型网站如淘宝、腾讯等都使用 Nginx 来处理高并发的用户请求,保证网站的快速稳定运行。对于中小企业的网站,Nginx 也能以其高效的性能和简单的配置,满足业务需求,降低服务器成本。

 Nginx 功能介绍

  1. Web 服务器功能

    • 高效处理静态文件请求,如 HTML、CSS、JavaScript、图片等,速度极快。
    • 支持动态页面的反向代理,将请求转发到后端的应用服务器(如 PHP、Python 等)。
  2. 反向代理功能

    • 隐藏后端服务器的真实 IP 地址,增加安全性。
    • 对客户端请求进行过滤和预处理,减轻后端服务器的压力。
  3. 负载均衡功能

    • 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希等,将请求均匀分配到多个后端服务器。
    • 检测后端服务器的健康状态,自动剔除故障服务器,保证服务的高可用性。
  4. 缓存功能

    • 可以对静态文件和动态页面的响应进行缓存,减少重复请求对后端服务器的压力,提高响应速度。
  5. SSL/TLS 加密支持

    • 能够配置 SSL 证书,实现 HTTPS 协议,保障数据传输的安全性。
  6. 访问控制和权限管理

    • 通过配置 IP 访问限制、用户认证等规则,控制对网站资源的访问。
  7. Gzip 压缩

    • 对响应数据进行 Gzip 压缩,减少数据传输量,提高传输效率。
  8. Rewrite 重写规则

    • 灵活地修改请求的 URL,实现 URL 重定向和优化。
  9. 监控和日志记录

    • 提供详细的访问日志和错误日志,方便监控服务器的运行状态和排查问题

Nginx 安装

Nginx 安装可以使用 yum 或源码安装,但是推荐使用源码编译安装
yum 的版本比较旧
编译安装可以更方便自定义相关路径
使用源码编译可以自定义相关功能,更方便业务的上的使用

 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的平滑升级及版本回滚

下载安装包

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

把之前的旧版的 nginx 命令备份

把新版本的 nginx 命令复制过去
[root@nginx sbin]# \cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin/nginx
启动新版本的nginx
回收旧版本
版本回滚
如果升级的版本发现问题需要回滚 , 可以重新拉起旧版本的 worker

可以选择隐藏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:提供了对不同事件模型的支持,如 epollkqueue 等,以提高网络性能。

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 -v
nginx version: nginx/1.18.0
Usage: 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/*.conf
fastcgi 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 ( 快速拷贝到 kernelsocket
buffer) >> 协议栈。
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 :指定 web 的家目录,在定义 location 的时候,文件的绝对路径等于 root+location
alias :定义路径别名,会把访问的路径重新定义到其指定的路径 , 文档映射的另一种机制 ; 仅能用于
location 上下文 , 此指令使用较少
root # 给定的路径对应于 location 中的 /uri 左侧的 /
alias # 给定的路径对应于 location 中的 /uri 的完整路径

我们新建一个子配置文件(注意要写在前面,写到后面不生效)

写解析

root

alias

十一、Nginx-location用法详解

在一个 server location 配置段可存在多个,用于实现从 uri 到文件系统的路径映射;
ngnix 会根据用户请求的 URI 来检查定义的所有 location ,按一定的优先级找出一个最佳匹配,
而后应用其配置在没有使用正则表达式的时候, nginx 会先在 server 中的多个 location 选取匹配度最
高的一个 uri
uri 是用户请求的字符串,即域名后面的 web 文件路径
然后使用该 location 模块中的正则 url 和字符串,如果匹配成功就结束搜索,并使用此 location 处理
此请求。
# 语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= # 用于标准 uri 前,需要请求字串与 uri 精确匹配,大小敏感 , 如果匹配成功就停止向下匹配并立
即处理请求
^~ # 用于标准 uri 前,表示包含正则表达式 , 并且匹配以指定的正则表达式开头
# uri 的最左边部分做匹配检查,不区分字符大小写
~ # 用于标准 uri 前,表示包含正则表达式 , 并且区分大小写
~* # 用于标准 uri 前,表示包含正则表达式 , 并且不区分大写
不带符号 # 匹配起始于此 uri 的所有的 uri
\ # 用于标准 uri 前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号

 优先级

(~* = ~)> 不带符号  >  ^~  >   =

= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立

两个比较一下(无符号的优先级大于 “=”  的优先级)

^~ # 用于标准 uri 前,表示包含正则表达式 , 并且匹配以指定的正则表达式开头
# uri 的最左边部分做匹配检查,不区分字符大小写

 

 

~ #用于标准uri前,表示包含正则表达式,并且区分大小写

 

 十二、Nginx下的用户认证

  ngx_http_auth_basic_module 模块提供此功能

 十三、Nginx自定义错误页面

自 定义错误页,同时也可以用指定的响应状态码进行响应 , 可用位置: http, server, location, if in
location

十四、Nginx自定义日志

十五、Nginx中的文件检测

try_files 会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI 的指向。最后一个参数是回退 URI 且必须存在,否则会出现内部500 错误。
语法格式
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location

 十六、Nginx中的长链接的管理

keepalive_timeout timeout [header_timeout]; # 设定保持连接超时时长, 0 表示禁止长连接,
默认为 75s
# 通常配置在 http 字段作为站点全局配置
keepalive_requests 数字 ; # 在一次长连接上所允许请求的资源的最大数量
# 默认为 100 , 建议适当调大 , 比如 :500
keepalive_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

这里是主配置文件不是子配置文件

 下载测试工具

五秒断开

十七、Nginx下载服务器的设定及优化

ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表 , 可以做为下载服务配置使用

 相关指令:

autoindex on | off; # 自动文件索引功能,默为 off
autoindex_exact_size on | off; # 计算文件确切大小(单位 bytes ), off 显示大概大小(单位 K
M) ,默认 on
autoindex_localtime on | off ; # 显示本机时间而非 GMT( 格林威治 ) 时间,默认 off
autoindex_format html | xml | json | jsonp; # 显示索引的页面文件风格,默认 html
limit_rate rate; # 限制响应客户端传输速率 ( GET HEAD 以外的所有方法 ) ,单位 B/s,bytes/second, # 默认值 0, 表示无限制 , 此指令由
ngx_http_core_module 提供
set $limit_rate 4k; # 也可以通变量限速 , 单位 B/s, 同时设置 , 此项优级高 .

 点击可直接下载

这里的时间不是本地的时间,是格林尼治时间

 文件粗略大小

限速(默认不限速)

十八、Nginx的状态页面

基于 nginx 模块 ngx_http_stub_status_module 实现,
在编译安装 nginx 的时候需要添加编译参数 --with-http_stub_status_module
否则配置完成之后监测会是提示法错误
# 配置示例:
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: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应 accepts,handled,requests 三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections: # 当前处于活动状态的客户端连接数
# 包括连接等待空闲连接数 =reading+writing+waiting
accepts # 统计总值, Nginx 自启动后已经接受的客户端请求连接的总数。
handled: # 统计总值, Nginx 自启动后已经处理完成的客户端请求连接总数
# 通常等于 accepts ,除非有因 worker_connections 限制等被拒绝的
连接
requests: # 统计总值, Nginx 自启动后客户端发来的总的请求数
Reading: # 当前状态,正在读取客户端请求报文首部的连接的连接数
# 数值越大 , 说明排队现象严重 , 性能不足
Writing: # 当前状态,正在向客户端发送响应报文过程中的连接数 , 数值越大 , 说明
访问量很大
Waiting: # 当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive 的情况下 , 这个值等于 active –
(reading+writing)

 但是状态也不能随便让人去看,需要指定

十九、Nginx的数据压缩功能

Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文
件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的 IT 支出,不过会占用相
应的 CPU 资源。
Nginx 对文件的压缩功能是依赖于模块 ngx_http_gzip_module, 默认是内置模块
配置指令如下:
# 启用或禁用 gzip 压缩,默认关闭
gzip on | off;
# 压缩比由低到高从 1 9 ,默认为 1 ,值越高压缩后文件越小,但是消耗 cpu 比较高。基本设定未 4 或者 5
gzip_comp_level 4;
# 禁用 IE6 gzip 功能,早期的 IE6 之前的版本不支持压缩
gzip_disable "MSIE [1-6]\.";
#gzip 压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# 启用压缩功能时,协议的最小版本,默认 HTTP/1.1
gzip_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中的变量

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 指令

用于条件匹配判断,并根据条件判断结果选择不同的 Nginx 配置,可以配置在 server location 块中进行配置,Nginx if 语法仅能使用 if 做单次判断,不支持使用 if else 或者 if elif 这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时 if 指令认为条件为 true ,否则认为 false ,变量与表达式之间使用以下符号链接:
= # 比较变量和字符串是否相等,相等时 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 指令

用于中断当前相同作用域 (location) 中的其他 Nginx 配置
与该指令处于同一作用域的 Nginx 配置中,位于它前面的配置生效
位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server 块和 locationif 块中使用

return 指令

return 用于完成对请求的处理,并直接向客户端返回响应状态码,比如 : 可以指定重定向 URL( 对于特殊重
定向状态码, 301/302 ) 或者是指定提示文本内容 ( 对于特殊状态码 403/500 ) ,处于此指令后的所有配
置都将不被执行, return 可以在 server if location 块进行配置

 

rewrite 指令

通过正则表达式的匹配来改变 URI ,可以同时存在一个或多个指令,按照顺序依次对 URI 进行匹配,rewrite主要是针对用户请求的 URL 或者是 URI 做具体处理
语法格式 :
rewrite regex replacement [flag];
rewrite 将用户请求的 URI 基于 regex 所描述的模式进行检查,匹配到时将其替换为表达式指定的新的 URI
注意:如果在同一级配置块中存在多个 rewrite 规则,那么会自下而下逐个检查 ; 被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制, 但不超过 10 ; 如果超过,提示 500 响应码, [flag] 所表示的标志位用于控制此循环机制
如果替换后的 URL 是以 http:// https:// 开头,则替换结果会直接以重定向返回给客户端 , 即永久重定向301
正则表达式格式
. # 匹配除换行符以外的任意字符
\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 使用介绍

利用 nginx rewrite 的指令,可以实现 url 的重新跳转, rewrite 有四种不同的 flag ,分别是 redirect( 临时重定向302) permanent( 永久重定向 301) break last 。其中前两种是跳转型的 flag ,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在 WEB 服务器内部实现跳转
rewrite 格式
Syntax: rewrite regex replacement [flag]; # 通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if

 flag 说明

redirect;
# 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求 ; 使用相对路径 , 或者 http:// https:// 开头,状态码: 302
permanent;
# 重写完成后以永久重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求,状态码: 301
break;
# 重写完成后 , 停止对当前 URL 在当前 location 中后续的其它重写操作
# 而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在 location 中使用
# 适用于一个 URL 一次重写
last;
# 重写完成后 , 停止对当前 URI 在当前 location 中后续的其它重写操作,
# 而后对新的 URL 启动新一轮重写检查,不建议在 location 中使用
# 适用于一个 URL 多次重写,要注意避免出现超过十次以及 URL 重写后返回错误的给用户

 rewrite案例: 域名永久与临时重定向

域名的临时的调整,后期可能会变,之前的域名或者 URL 可能还用、或者跳转的目的域名和 URL 还会跳转,这种情况浏览器不会缓存跳转, 临时重定向不会缓存域名解析记录 (A 记录 ) ,但是永久重定向会缓存。

rewrite 案例: break last

二十二、Nginx-rewrite的企业示例及防盗链

rewrite案例: 自动跳转 https

创建目录

制作认证文件

编写配置文件

测试访问

不用输https直接跳转

判断文件是否存在

防盗链

防盗链基于客户端携带的 referer 实现, referer 是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的 referer 信息有以下几种:
none # 请求报文首部没有 referer 首部,
# 比如用户直接在浏览器输入域名访问 web 网站,就没有 referer 信息。
blocked # 请求报文有 referer 首部,但无有效值,比如为空。
server_names #referer 首部中包含本主机名及即 nginx 监听的 server_name
arbitrary_string # 自定义指定字符串,但可使用 * 作通配符。示例 : *.timinglee.org
www.timinglee.*
regular expression # 被指定的正则表达式模式匹配到的字符串 , 要使用 ~ 开头,例如:
~.*\.timinglee\.com

二十三、Nginx的反向代理及动静分离实现

什么是反向代理

反向代理是位于客户端和后端服务器之间的服务器。与正向代理(代表客户端向服务器发起请求)不同,反向代理接收来自客户端的请求,并将这些请求转发给后端的一个或多个服务器。然后,它将后端服务器的响应返回给客户端,就好像这个响应是直接来自反向代理服务器本身一样。

Nginx 反向代理的工作原理

  1. 客户端向 Nginx 服务器发送请求,请求的目标通常是一个域名或 IP 地址及端口号。
  2. Nginx 接收到请求后,根据配置的规则确定将请求转发到哪个后端服务器。
  3. Nginx 将请求转发给后端服务器,这个过程可以是通过不同的协议(如 HTTP、HTTPS、TCP 等)进行。
  4. 后端服务器处理请求,并将响应返回给 Nginx。
  5. Nginx 再将后端服务器的响应返回给客户端。

Nginx 反向代理的优势

  1. 负载均衡

    • 通过将请求分发到多个后端服务器,可以平衡服务器的负载,避免单个服务器过载。Nginx 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希等,可以根据实际需求进行选择。
    • 例如,在一个高流量的网站中,可以使用 Nginx 反向代理将请求分发到多个 Web 服务器上,以确保每个服务器都不会承受过大的压力。
  2. 安全防护

    • 可以隐藏后端服务器的真实 IP 地址,增加系统的安全性。客户端只能看到 Nginx 的 IP 地址,而无法直接访问后端服务器。
    • Nginx 还可以配置各种安全策略,如限制访问频率、过滤恶意请求等,进一步保护后端服务器。
  3. 缓存加速

    • Nginx 可以缓存后端服务器的响应结果,当相同的请求再次到来时,直接返回缓存的结果,而无需再次向后端服务器发送请求。这可以大大提高响应速度,减少后端服务器的负载。
    • 可以根据不同的请求路径、文件类型等设置缓存策略,以优化缓存效果。
  4. 动静分离

    • 将静态资源(如图片、CSS、JavaScript 文件等)和动态资源(如 PHP、Java 等动态生成的页面)分别部署在不同的服务器上,然后通过 Nginx 反向代理进行请求分发。
    • 对于静态资源,可以设置较长的缓存时间,以提高访问速度;对于动态资源,可以根据实际情况进行负载均衡和优化
Nginx 除了可以在企业提供高性能的 web 服务之外,另外还可以将 nginx 本身不具备的请求通过某种预
定义的协议转发至其它服务器处理,不同的协议就是 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 请求后,等待的超时时间,默认 60s
proxy_send_timeout time;
# 配置 nginx 项后端服务器或服务器组发起 write 请求后,等待的超时 时间,默认 60s
proxy_http_version 1.0;
# 用于设置 nginx 提供代理服务的 HTTP 协议的版本,默认 http 1.0
proxy_ignore_client_abort off;
# 当客户端网络中断请求时, nginx 服务器中断其对后端服务器的请求。即如果此项设置为 on 开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off ,则客户端中断后 Nginx 也会中断客户端请求并立即记录499 日志,默认为 off

动静分离

二十四、Nginx反向代理的缓存功能

缓存的作用

  1. 提高响应速度

    • 当客户端请求一个资源时,如果 Nginx 缓存中已经有该资源,就可以直接从缓存中返回响应,而无需再次向后端服务器请求,大大减少了响应时间。
    • 尤其对于动态内容,缓存可以减少后端服务器的负载,提高整个系统的吞吐量。
  2. 减轻后端服务器压力

    • 大量的重复请求可以由 Nginx 缓存来处理,后端服务器只需处理那些不在缓存中的请求或者缓存过期的请求,从而降低了后端服务器的负载。

缓存的工作原理

  1. 缓存存储

    • Nginx 将反向代理获取到的资源存储在本地磁盘或内存中,具体的存储位置可以通过配置指定。
    • 缓存的资源包括静态文件(如图片、CSS、JavaScript 文件等)和动态内容(如由后端服务器生成的 HTML 页面)。
  2. 缓存命中与未命中

    • 当客户端发起请求时,Nginx 首先检查缓存中是否存在该请求的资源。
    • 如果缓存命中,Nginx 直接从缓存中读取资源并返回给客户端。
    • 如果缓存未命中,Nginx 会将请求转发到后端服务器,获取资源后再返回给客户端,并将资源缓存起来,以便下次请求时使用。
  3. 缓存过期策略

    • Nginx 可以根据不同的策略来确定缓存的过期时间。常见的策略包括:
      • 时间过期:设置一个固定的时间,例如 1 小时或 1 天,超过这个时间后缓存的资源被认为过期。
      • 条件过期:根据后端服务器返回的响应头中的信息来判断缓存是否过期。例如,如果后端服务器返回的响应头中包含 “Cache-Control” 或 “Expires” 字段,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 个左右的 key
inactive=120s # 缓存有效时间
max_size=10g; # 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
# 调用缓存功能,需要定义在相应的配置段,如 server{...}; 或者 location
proxy_cache proxycache;
proxy_cache_key $request_uri; # 对指定的数据进行 MD5 的运算做为缓存的 key
proxy_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的反向代理负载均衡

负载均衡的作用

  1. 提高系统可用性

    • 通过将请求分发到多个后端服务器上,即使其中一台服务器出现故障,其他服务器仍然可以继续处理请求,从而提高了整个系统的可用性。
    • 避免了单点故障,确保系统能够持续稳定地运行。
  2. 提升系统性能

    • 负载均衡可以将请求均匀地分配到不同的服务器上,充分利用各服务器的资源,避免某些服务器负载过高而其他服务器闲置的情况。
    • 提高了系统的吞吐量和响应速度,能够更好地满足大量用户的并发请求。

负载均衡的工作原理

  1. 客户端请求

    • 当客户端发送请求时,请求首先到达 Nginx 服务器。
  2. Nginx 分配请求

    • Nginx 根据预先配置的负载均衡算法,将请求转发到后端的一个或多个服务器上。
    • 常见的负载均衡算法有轮询(round-robin)、加权轮询(weighted round-robin)、IP 哈希(ip_hash)等。
  3. 后端服务器处理请求

    • 后端服务器接收到请求后,进行相应的处理,并将响应返回给 Nginx。
  4. 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 而不用重启
Nginx
hash KEY [consistent];
# 基于指定请求报文中首部字段或者 URI key hash 计算,使用 consistent 参数,将使用 ketama 一致性
hash 算法,适用于后端是 Cache 服务器(如 varnish )时使用, consistent 定义使用一致性 hash 运算,一致
hash 基于取模运算
hash $request_uri consistent; # 基于用户请求的 uri hash
hash $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:main
upstream backend { # 定义后端服务器
hash $remote_addr consistent; # 定义调度算法
server backend1.example.com:12345 weight=5; # 定义具体 server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { # 定义后端服务器
server 10.0.0.1:53; # 定义具体 server
server dns.example.com:53;
}
server { # 定义 server
listen 12345; # 监听 IP:PORT
proxy_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

后端服务器安装 MySQL
[root@web2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf

 [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配置指令  

Nginx 基于模块 ngx_http_fastcgi_module 实现通过 fastcgi 协议将指定的客户端请求转发至 php-fpm
理,其配置指令如下:
fastcgi_pass address:port;

# 转发请求到后端服务器, address 为后端的 fastcgi server 的地址,可用位置: location, if in
location
fastcgi_index name;
#fastcgi 默认的主页资源,示例: fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty];
# 设置传递给 FastCGI 服务器的参数值,可以是文本,变量或组合,可用于将 Nginx 的内置变量赋值给自定义
key
fastcgi_param REMOTE_ADDR $remote_addr; # 客户端源 IP
fastcgi_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 name
Nginx 默认配置示例:
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的配置方法

 

指定 pid 文件存放位置

生成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

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田驰02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值