Nginx基础入门

        Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在 BSD-like 协议下发行。Nginx是为性能而生,从发布以来一直侧重于高性能、高并发、低 CPU 内存消耗;在功能方面:负载均衡、反向代理、访问控制、热部署、高扩展性等特性又十分适合现代的网络架构。更可贵的是配置简单文档丰富,大大降低了学习的门槛。

Web 调度员 Nginx(Nginx应用之一)

        当 web 应用发展到一定程度时,单台服务器不足以支撑业务的正常运行,为增大吞吐量往往会使用多台服务器一起提供服务,如何充分利用多台服务器的资源,就需要一个‘调度员’,这个调度员要求能高效的接收并分发请求,知道后端的服务器健康状态,要能方便的扩展和移除,这就是 Nginx 又一常见应用架构,此架构充分利用了 Nginx 的反向代理和负载均衡的优势,Nginx 本身不提供 web 服务,而是在前端接受 Web 请求并分发到后端服务器处理,后端服务器可以是 Apache、Tomcat、IIS 等。

Nginx 的代码是由一个 核心 和一系列的 模块 组成。

 核心的功能如下:

  • 主要用于提供 WebServer 的基本功能;
  • 实现 Web 和 Mail 反向代理的功能;
  • 还用于启用网络协议;
  • 创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。

        大多跟协议相关的功能和应用特有的功能都是由 Nginx 的模块实现的。这些功能模块大致可以分为:事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream 和负载均衡几个类别,这些功能模块共同组成了 Nginx 的 http 功能。

其中:

  • 事件模块主要用于提供 OS 独立的(不同操作系统的事件机制有所不同)事件通知机制,如 kqueue 或 epoll 等。
  • 协议模块则负责实现 Nginx 通过 HTTP、TLS/SSL、SMTP、POP3 以及 IMAP 与对应的客户端建立会话。

在 Nginx 内部,进程间的通信是通过模块的 pipeline 或 chain 实现的。

        每一个功能或操作都由一个模块来实现。例如:压缩、通过 FastCGI 或 uwsgi 协议与 upstream 服务器通信、以及与 memcached 建立会话等。Nginx 启动后,在 Unix 系统中会以 daemon (守护进程)的方式在后台运行,后台进程包含一个 master 进程和多个 worker 进程(你可以理解为工人和管理员)。这里就主要讲解 Nginx 的多进程模式。

Nginx 处理连接的过程

        Nginx 不会为每个连接派生进程或线程,而是由 worker 进程通过监听共享套接字接收新请求,并且使用高效的循环来处理数千个连接。Nginx 不使用仲裁器或分发器来分发连接,这个工作由操作系统内核机制完成。监听套接字在启动时就完成初始化,worker 进程通过这些套接字接收、读取请求和输出响应。

master 进程

        当 Nginx 在启动后,会有一个 master 进程和多个 worker 进程。master 进程主要用来管理 worker 进程,master 要做的就是:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动重新启动新的 worker 进程。

worker 进程

        对于基本的网络事件,Nginx 则是放在 worker 进程中来处理。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求(一对一)。然而 Nginx 没有专门地仲裁或连接分布的 worker,这项工作是由操作系统内核机制完成的。在启动时,创建一组初始的监听套接字,HTTP 请求和响应之时,worker 连续接收、读取和写入套接字。

我们来看一看一个完整的请求是怎样通过互相的协作来实现的:

(1)首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socketlistenfd)之后,然后再 fork 出多个 worker 进程。

(2)所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,然后在读事件里调用 accept 接受该连接。

(3)当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

我们可以看到:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。

        Nginx 采用的是多 Worker 进程加异步非阻塞的处理模型。这种模型的高明之处在于,即使每个 Worker 进程只有一个主线程,它也能高效地处理大量并发请求。关键在于“异步非阻塞”这四个字。

异步非阻塞的工作原理
  1. 事件驱动:Nginx 的每个 Worker 进程使用事件驱动的方式来处理请求。它通过操作系统提供的高效 I/O 复用机制(如 epollkqueue 等)来监控多个文件描述符(即客户端连接)的状态变化。

  2. 非阻塞 I/O:在非阻塞 I/O 模型中,当一个 I/O 操作(如读取数据)不能立即完成时,操作系统不会让该操作阻塞(等待)当前线程,而是立即返回一个标记(如 EAGAIN),表示操作未完成。然后,Nginx 可以继续处理其他请求。

  3. 事件循环:Nginx 的 Worker 进程会进入一个事件循环,不断地检查哪些请求有事件发生(如有数据可读或可写)。当检测到事件发生时,才去处理相应的请求。这种方式避免了等待某个 I/O 操作完成的时间浪费。

        Nginx 真正的魅力在于它的模块,整个应用程序建立在一个模块化系统之上,在编译时,可以对每一个模块进行启用或者禁用,需要什么就定制什么。

        对 Nginx 模块的基本原理总结一下,基本就是:在特定地方调用函数。(Nginx 本身支持多种模块,如 HTTP 模块、EVENTS 模块和 MAIL 模块,这里只简单讲述 HTTP 的模块及其中的命令)

下面是配置文件结构图:

        Nginx 本身做的工作实际很少,当它接到一个 HTTP 请求时,它仅仅是通过查找配置文件将此次请求映射到一个 location block,而此 location 中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做 Nginx 真正的劳动工作者。

  • 通常一个 location 中的指令会涉及一个 handler 模块和多个 filter 模块(当然,多个 location 可以复用同一个模块)。
    • handler 模块负责处理请求,完成响应内容的生成;
    • filter 模块对响应内容进行处理。

因此 Nginx 模块开发分为 handler 开发和 filter 开发(本文不考虑 load-balancer 模块)。

下图展示了一次常规请求和响应的过程。

参考链接

https://xxetb.xetslk.com/s/2fs2Vb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值