Nginx 介绍、安装与参数调优 2021-12-31

Nginx 介绍、安装与参数调优 2021-12-31,第1张

Nginx 介绍、安装与参数调优 2021-12-31 Java组件总目录

Nginx 核心功能与配置
  • Java组件总目录
  • 一 Nginx 概述
    • 1 代理服务器
      • 1.1 正向代理
      • 1.2 反向代理
    • 2 Nginx服务器特点
      • 2.1 高并发
      • 2.2 低消耗
      • 2.3 热部署
      • 2.4 高可用
      • 2.5 高扩展
    • 3 Nginx 的下载与安装
      • 3.1 安装
    • 4 Nginx 命令说明
      • 4.1 测试配置文件命令
      • 4.2 停止命令
    • 4.3 平滑重启命令 nginx –s reload
  • 二 Niginx 性能调优
    • 1 零拷贝(Zero Copy)
      • 1.1 传统拷贝方式
      • 1.2 零拷贝方式
      • 1.3 Gather Copy DMA 零拷贝方式
      • 1.4 mmap 零拷贝
    • 2 Nginx 的并发处理机制
      • 2.1 IO连接处理模型
        • 1 多进程/多线程连接处理模型
        • 2 多路复用连接处理模型
      • 2.2 多路复用器工作原理
        • 1 select
        • 2 poll
        • 3 epoll
          • LT 模式
          • ET 模式
    • 3 Nginx 配置文件调优
      • 1 全局模块下的参数调优
        • 1.1 worker_processes
        • 1.2 worker_cpu_affinity
        • 1.3 worker_rlimit_nofile
      • 2 events 模块下的参数调优
        • 2.1 worker_connections 1024
        • 2.2 accept_mutex on
        • 2.3 accept_mutex_delay 500ms
        • 2.4 multi_accept on
        • 2.5 use epoll
      • 3 http 模块下的参数
        • 1 非调优属性简介
        • 2 sendfile on
        • 3 tcp_nopush
        • 4 tcp_nodelay on
        • 5 keepalive_timeout 60
        • 6 keepalive_requests 10000
        • 7 client_body_timeout 10

一 Nginx 概述 1 代理服务器

正向代理时 客户端知道真正要访问的服务器地址的。
反向代理时 客户端以为自己访问的地址的是服务器的真正地址。

1.1 正向代理

正向代理代理的是客户端。服务器无法感知客户端的存在。客户端通过代理访问服务器。

功能:

  • 隐藏客户端
  • 访问本身不能访问的网络: 客户端无法直接访问服务器S, 通过访问带来实现访问
  • 提速: 与代理服务器访问为高速链路。
  • 缓存:客户端从服务器下载内容,代理服务器可缓存,其他客户端访问时可不用下载。
  • 授权:代理存在防火墙,控制哪些客户端能够访问外网。

1.2 反向代理

反向代理是Nginx 代理的服务器端。客户端不知道服务器。通过Nginx 来转发。

功能:

  • 保护隐藏: 隐藏具体的服务端。
  • 分布式路由: 客户端发起请求后,代理会转给不同的服务器。
  • 负载均衡: 对应集群来说,代理会将请求分配给不同机器。实现负载均衡
  • 动静分离: 静态资源请求与动态的内容分离,Nginx 提供静态资源文件。
  • 数据缓存:
2 Nginx服务器特点 2.1 高并发

一个 Nginx 服务器在不做任何配置的情况下并发量可达 1000 左右。在硬件条件允许的前提下,Nginx 可以支持高达 5-10 万的并发量(除了 Nginx 的设置外,Linux 主机需要做大量的设置来配合 Nginx)。

对比一下 Tomcat。Tomcat 服务器默认的并发量为 150(不做任何配置)。即,当有超过150 个用户同时访问某 Servlet 时,Tomcat 的响应就会变得非常慢。

2.2 低消耗

官方给出的测试结果,10000 个非活跃连接,在 Nginx 中仅消耗 2.5M 内存。对于一般性的 DoS 攻击来说就不是事儿,但承受不了 DDoS 攻击。

2.3 热部署

可以在 7*24 小时不间断服务的前提下,进行 Nginx 版本的平滑升级,Nginx 配置文件的平滑修改。即在不停机的情况下升级 Nginx,修改替换 Nginx 配置文件。

命令如下:

nginx –s reload
2.4 高可用

Nginx 只所以可以实现高并发,是因为其具有很多工作进程 worker。当这些工作进程中的某些出现问题停止工作时,并不会影响整个系统的整体运行。因为其它 worker 会接替那些出问题的线程。

2.5 高扩展

Nginx 只所以现在的用户很多,是因为很多功能都已经开发好并模块化。若需要哪些功能,只需要安装相应功能的扩展模块即可。根据编写扩展模块所使用的语言的不同,可以划分为两类:C 语言扩展模块与 LUA 脚本扩展模块。 http://openresty.org/cn/

3 Nginx 的下载与安装 3.1 安装

由于 Nginx 服务器默认的端口号为 80,所以在浏览器中直接输入 Nginx 的主机名或 IP, 就可以看到 Nginx 欢迎页面。只要可以看到以下页面信息,则说明 Nginx 安装运行成功。

# 安装C 语言相关库
yum -y install gcc gcc-c++
# 安装Nignx 的依赖库
yum -y install pcre-devel openssl-devel
# 解压文件
mkdir /usr/apps
tar -zxvf nginx-1.20.2.tar.gz -C /usr/apps/

# 生成 makefile
# 编译命令 make 需要根据编译文件 makefile 进行编译,
# 所以在编译之前需要先生成编译文件 makefile。使用 configure 命令可以生成该文件。
./configure 
--prefix=/usr/local/nginx 
--with-http_ssl_module

# 编译 和 安装
make & make install

# 将nginx 命令添加到path 中,方便使用 查看系统路径
echo $PATH
# 创建软链接, 放在/usr/local/sbin
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin

# 启动nginx, 查看相关进程
nginx
ps aux | grep nginx

# 访问虚拟机ip, 看到Nginx 欢迎界面

4 Nginx 命令说明
  • 1 查看命令选项 nginx -h
  • 2 查看 Nginx 版本信息 nginx –v 或-V
  • 3 指定配置文件 –c file 指定配置文件.
  • 4 指定配置文件路径 nginx –p 指定 Nginx 配置文件的存放路径
4.1 测试配置文件命令

nginx –t:测试配置文件是否正确,默认只测试默认的配置文件 conf/nginx.conf。
nginx –T:测试配置文件是否正确,并显示配置文件内容。
nginx –tq:在配置文件测试过程中,禁止显示非错误信息,即只显示错误信息。
可以结合-c 选项指定要测试的配置文件。注意,其不会启动 nginx。

nginx -c /usr/local/nginx/conf.conf -t

4.2 停止命令

nginx 命令后通过-s 选项,可以指定不同的信号完成不同的功能。

  • nginx –s stop:强制停止 Nginx,无论当前工作进程是否正在处理工作。
  • nginx –s quit:优雅停止 Nginx,使当前的工作进程完成当前工作后停止。
4.3 平滑重启命令 nginx –s reload

在不重启 Nginx 的前提下重新加载 Nginx 配置文件,称为平滑重启。

二 Niginx 性能调优

在 Nginx 性能调优中,有两个非常重要的理论点(面试点)需要掌握。所以,下面首先
讲解这两个知识点,再进行性能调优的配置。

1 零拷贝(Zero Copy)

**零拷贝指的是,从一个存储区域到另一个存储区域的 copy 任务没有 CPU 参与。**零拷贝
通常用于网络文件传输,以减少 CPU 消耗和内存带宽占用,减少用户空间与 CPU 内核空间的拷贝过程,减少用户上下文与 CPU 内核上下文间的切换,提高系统效率。
用户空间指的是用户可 *** 作的内存缓存区域,CPU 内核空间是指仅 CPU 可以 *** 作的寄
存器缓存及内存缓存区域。

用户上下文指的是用户状态环境,CPU 内核上下文指的是 CPU 内核状态环境。
零拷贝需要 DMA 控制器的协助。DMA,Direct Memory Access,直接内存存取,是 CPU
的组成部分,其可以在 CPU 内核(算术逻辑运算器 ALU 等)不参与运算的情况下将数据从一个地址空间拷贝到另一个地址空间。

下面均以“将一个硬盘中的文件通过网络发送出去”的过程为例,来详细详细分析不同
拷贝方式的实现细节。

1.1 传统拷贝方式

首先通过应用程序的 read()方法将文件从硬盘读取出来,然后再调用 send()方法将文件
发送出去。

该拷贝方式共进行了 4 次用户空间与内核空间的上下文切换,以及 4 次数据拷贝,其中
两次拷贝存在 CPU 参与。

我们发现一个很明显的问题:应用程序的作用仅仅就是一个数据传输的中介,最后将
kernel buffer 中的数据传递到了 socket buffer。显然这是没有必要的。所以就引入了零拷贝。

1.2 零拷贝方式

Linux 系统(CentOS6 及其以上版本)对于零拷贝是通过 sendfile 系统调用实现的。

该拷贝方式共进行了 2 次用户空间与内核空间的上下文切换,以及 3 次数据拷贝,但整
个拷贝过程均没有 CPU 的参与,这就是零拷贝。

我们发现这里还存在一个问题:kernel buffer 到 socket buffer 的拷贝需要吗?kernel
buffer 与 socket buffer 有什么区别呢?DMA 控制器所控制的拷贝过程有一个要求,数据在源头的存放地址空间必须是连续的。kernel buffer 中的数据无法保证其连续性,所以需要将数据再拷贝到 socket buffer,socket buffer 可以保证了数据的连续性。

这个拷贝过程能否避免呢?可以,只要主机的 DMA 支持 Gather Copy 功能,就可以避
免由 kernel buffer 到 socket buffer 的拷贝。

1.3 Gather Copy DMA 零拷贝方式

由于该拷贝方式是由 DMA 完成,与系统无关,所以只要保证系统支持 sendfile 系统调
用功能即可。

该方式中没有数据拷贝到 socket buffer。取而代之的是只是将 kernel buffer 中的数据描
述信息写到了 socket buffer 中。数据描述信息包含了两方面的信息:kernel buffer 中数据的
地址及偏移量。


该拷贝方式共进行了 2 次用户空间与内核空间的上下文切换,以及 2 次数据拷贝,并且
整个拷贝过程均没有 CPU 的参与。
该拷贝方式的系统效率是高了,但与传统相比,也存在有不足。传统拷贝中 user buffer
中存有数据,因此应用程序能够对数据进行修改等 *** 作;零拷贝中的 user buffer 中没有了数据,所以应用程序无法对数据进行 *** 作了。Linux 的 mmap 零拷贝解决了这个问题。

1.4 mmap 零拷贝

mmap 零拷贝是对零拷贝的改进。当然,若当前主机的 DMA 支持 Gather Copy,mmap
同样可以实现 Gather Copy DMA 的零拷贝。

该方式与零拷贝的唯一区别是,应用程序与内核共享了 Kernel buffer。由于是共享,所
以应用程序也就可以 *** 作该 buffer 了。当然,应用程序对于 Kernel buffer 的 *** 作,就会引发用户空间与内核空间的相互切换。

该拷贝方式共进行了 4 次用户空间与内核空间的上下文切换,以及 2 次数据拷贝,并且
整个拷贝过程均没有 CPU 的参与。虽然较之前面的零拷贝增加了两次上下文切换,但应用
程序可以对数据进行修改了。

2 Nginx 的并发处理机制

一般情况下并发处理机制有三种:多进程、多线程,与异步机制。Nginx 对于并发的处
理同时采用了三种机制。当然,其异步机制使用的是异步非阻塞方式。

我们知道 Nginx 的进程分为两类:master 进程与 worker 进程。每个 master 进程可以生
成多个 worker 进程,所以其是多进程的。每个 worker 进程可以同时处理多个用户请求,每
个用户请求会由一个线程来处理,所以其是多线程的。

那么,如何解释其“异步非阻塞”并发处理机制呢?
worker 进程采用的就是 epoll 多路复用机制来对后端服务器进行处理的。当后端服务器返回结果后,后端服务器就会回调 epoll 多路复用器,由多路复用器对相应的 worker 进程进行通知。此时,worker 进程就会挂起当前正在处理的事务,用 IO 返回结果去响应客户端请求。响应完毕后,会再继续执行挂起的事务。这个过程就是“异步非阻塞”的。

2.1 IO连接处理模型

若要理解 select、poll 与 epoll 多路复用器的工作原理,就需要首先了解什么是多路复用
器。而要了解什么是多路复用器,就需要先了解什么是“多进程/多线程连接处理模型”。

1 多进程/多线程连接处理模型


在该模型下,一个用户连接请求会由一个内核进程处理,而一个内核进程会创建一个应
用程序进程,即 app 进程来处理该连接请求。应用程序进程在调用 IO 时,采用的是 BIO 通
讯方式,即应用程序进程在未获取到 IO 响应之前是处于阻塞态的。

该模型的优点是,内核进程不存在对app进程的竞争,一个内核进程对应一个app进程。
但,也正因为如此,所以其弊端也就显而易见了。需要创建过多的 app 进程,而该创建过程
十分的消耗系统资源。且一个系统的进程数量是有上限的,所以该模型不能处理高并发的情
况。

2 多路复用连接处理模型


在该模型下,只有一个 app 进程来处理内核进程事务,且 app 进程一次只能处理一个内
核进程事务。故这种模型对于内核进程来说,存在对 app 进程的竞争。

在前面的“多进程/多线程连接处理模型”中我们说过,app 进程只要被创建了就会执行内核进程事务。那么在该模型下,应用程序进程应该执行哪个内核进程事务呢?谁的准备就绪了,app 进程就执行哪个。但 app 进程怎么知道哪个内核进程就绪了呢?需要通过“多路复用器”来获取各个内核进程的状态信息。
那么多路复用器又是怎么获取到内核进程的状不同的多路复用器,其算法不同。常见的有三种:select、poll 与 epoll。

app 进程在进行 IO 时,其采用的是 NIO 通讯方式,即该 app 进程不会阻塞。当一个 IO
结果返回时,app 进程会暂停当前事务,将 IO 结果返回给对应的内核进程。然后再继续执
行暂停的线程。该模型的优点很明显,无需再创建很多的应用程序进程去处理内核进程事务了,仅需一个即可。

2.2 多路复用器工作原理 1 select

select 多路复用器是采用轮询的方式,一直在轮询所有的相关内核进程,查看它们的进程状态。若已经就绪,则马上将该内核进程放入到就绪队列。否则,继续查看下一个内核进程状态。在处理内核进程事务之前,app 进程首先会从内核空间中将用户连接请求相关数据
复制到用户空间。

该多路复用器的缺陷有以下几点:

  • 对所有内核进程采用轮询方式效率会很低。因为对于大多数情况下,内核进程都不属于
    就绪状态,只有少部分才会是就绪态。所以这种轮询结果大多数都是无意义的。
  • 由于就绪队列底层由数组实现,所以其所能处理的内核进程数量是有限制的,即其能够
    处理的最大并发连接数量是有限制的。
  • 从内核空间到用户空间的复制,系统开销大。
2 poll

poll 多路复用器的工作原理与 select 几乎相同,不同的是,由于其就绪队列由链表实现,所以,其对于要处理的内核进程数量理论上是没有限制的,即其能够处理的最大并发连接数量是没有限制的(当然,要受限于当前系统中进程可以打开的最大文件描述符数 ulimit,后面会讲到)。

3 epoll

epoll 多路复用是对 select 与 poll 的增强与改进。其不再采用轮询方式了,而是采用回
调方式实现对内核进程状态的获取:一旦内核进程就绪,其就会回调 epoll 多路复用器,进
入到多路复用器的就绪队列(由链表实现)。所以 epoll 多路复用模型也称为 epoll 事件驱动模型。

另外,应用程序所使用的数据,也不再从内核空间复制到用户空间了,而是使用 mmap
零拷贝机制,大大降低了系统开销。

当内核进程就绪信息通知了 epoll 多路复用器后,多路复用器就会马上对其进行处理,
将其马上存放到就绪队列吗?不是的。根据处理方式的不同,可以分为两种处理模式:LT
模式与 ET 模式。

LT 模式

LT,Level Triggered,水平触发模式。即只要内核进程的就绪通知由于某种原因暂时没有
被 epoll 处理,则该内核进程就会定时将其就绪信息通知 epoll。直到 epoll 将其写入到就绪
队列,或由于某种原因该内核进程又不再就绪而不再通知。其支持两种通讯方式:BIO 与
NIO。

ET 模式

ET,Edge Triggered,边缘触发模式。其仅支持 NIO 的通讯方式。

当内核进程的就绪信息仅会通知一次 epoll,无论 epoll 是否处理该通知。明显该方式的
效率要高于 LT 模式,但其有可能会出现就绪通知被忽视的情况,即连接请求丢失的情况。

3 Nginx 配置文件调优 1 全局模块下的参数调优 1.1 worker_processes

打开 nginx.conf 配置文件,可以看到 worker_processes 的默认值为 1。

worker_processes,工作进程,用于指定 Nginx 的工作进程数量。其数值一般设置为 CPU
内核数量,或内核数量的整数倍。
不过需要注意,该值不仅仅取决于 CPU 内核数量,还与硬盘数量及负载均衡模式相关。
在不确定时可以指定其值为 auto。

1.2 worker_cpu_affinity

worker 进程与具体的内核进行绑定。不过,若指定 worker_processes 的值为 auto,
则无法设置 worker_cpu_affinity。

该设置是通过二进制进行的。每个内核使用一个二进制位表示,0 代表内核关闭,1 代
表内核开启。也就是说,有几个内核,就需要使用几个二进制位。

1.3 worker_rlimit_nofile

用于设置一个 worker 进程所能打开的最多文件数量。其默认值与当前 Linux 系统可以打
开的最大文件描述符数量相同。 65535

2 events 模块下的参数调优 2.1 worker_connections 1024

设置每一个 worker 进程可以并发处理的最大连接数。该值不能超过 worker_rlimit_nofile
的值。

2.2 accept_mutex on
  • on:默认值,表示当一个新连接到达时,那些没有处于工作状态的 worker 将以串行方
    式来处理; 新连接会唤醒队首worker, 其他worker 保持阻塞。

  • off:表示当一个新连接到达时,所有的 worker 都会被唤醒,不过只有一个 worker 能获
    取新连接,其它的 worker 会重新进入阻塞状态,这就是“惊群”现象。(当消息一次来很多时,该方式效率较高,资源花费较大。)

2.3 accept_mutex_delay 500ms

设置队首 worker 会获取互斥锁的时间间隔。默认值为 500 毫秒。
队首 worker 500 毫秒获取 互斥锁 ,获取到锁后,执行。

2.4 multi_accept on

当所有worker 都处于工作状态,有新的连接到来时,如何将连接分配给worker。

  • off:系统会逐个拿出新连接按照负载均衡策略,将其分配给当前处理连接个数最少的
    worker。
  • on:系统会实时的统计出各个 worker 当前正在处理的连接个数,根据每个worker 正在处理的个数,一次性将这么多的新连接分配给该连接数最少的 work。(默认)
2.5 use epoll

一般不修改。设置worker与客户端连接的处理方式。Nginx会自动选择适合当前系统的最高效的方式。
当然,也可以使用 use 指令明确指定所要使用的连接处理方式。user 的取值有以下几种:
select | poll | epoll | rtsig | kqueue | /dev/poll 。

  • kqueue :应用在 BSD 系统上的 epoll。
  • /dev/poll: UNIX 系统上使用的 poll。
3 http 模块下的参数 1 非调优属性简介

  • include mime.types;
    将当前目录(conf 目录)中的 mime.types 文件包含进来。

  • default_type application/octet-stream;
    对于无扩展名的文件,默认其为 application/octet-stream 类型,即 Nginx 会将其作为一个八进制流文件来处理。

  • charset utf-8; 设置请求与响应的字符编码。

2 sendfile on

设置为 on 则开启 Linux 系统的零拷贝机制,否则不启用零拷贝。当然,开启后是否起
作用,要看所使用的系统版本。CentOS6 及其以上版本支持 sendfile 零拷贝。

3 tcp_nopush
  • on:以单独的数据包形式发送 Nginx 的响应头信息,而真正的响应体数据会再以数据包
    的形式发送,这个数据包中就不再包含响应头信息了。(当响应数据量较大时,可以减低数据冗余度,减少数据发送量)

  • off:默认值,响应头信息包含在每一个响应体数据包中。

4 tcp_nodelay on
  • on:不设置数据发送缓存,即不推迟发送,适合于传输小数据,无需缓存。
  • off:开启发送缓存。若传输的数据是图片等大数据量文件,则建议设置为 off。
5 keepalive_timeout 60

设置客户端与Nginx间所建立的长连接的生命超时时间,时间到达,则连接将自动关闭。
单位秒。(长连接是双方的,客户端的浏览器一般也是60)

6 keepalive_requests 10000

设置一个长连接最多可以发送的请求数。该值需要在真实环境下测试。

7 client_body_timeout 10

设置客户端获取 Nginx 响应的超时时限,即一个请求从客户端发出到接收到 Nginx 的响
应的最长时间间隔。若超时,则认为本次请求失败。
从 客户端发送 到 客户端接收,设置在Nginx 端, Nginx 传递给客户端,客户端可以判断是否超时。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5695151.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存