编辑
2020-08-27
编程
00

目录

nginx base
1.搭建
1.1 安装 nginx
1.1.1 环境-操作系统
1.1.2 环境-软件
1.1.3 环境-磁盘
1.1.4 环境-Linux内核参数的优化
1.1.5 下载源码
1.2 编译安装 Nginx
1.2.1 命令说明
1.3 ./configure 详解
1.4 nginx 命令行控制
2. nginx 的配置
2.1 nginx 进程关系
2.2 nginx 配置的通用语法
2.2.1 块配置
2.2.2 配置项的语法格式
2.2.3 配置项的注释
2.2.4 配置项的单位
2.2.5 配置项中使用变量
2.3 nginx 服务的基本配置
2.3.1 用于调试、定位问题的配置项
1. 是否以守护进程方式进行 nginx
2.是否以master/worker方式工作
3.error日志的设置
4.是否处理几个特殊的调试点
5.仅对指定的客户端输出debug级别的日志
6.限制coredump核心转储文件的大小
7.指定coredump文件生成目录
2.3.2 正常运行的配置项
1.定义环境变量
2.嵌入其他配置文件
3.pid文件的路径
4.Nginx worker进程运行的用户及用户组
5.指定Nginx worker进程可以打开的最大句柄描述符个数
6.限制信号队列语法
2.3.3 优化性能的配置项
1.Nginx worker进程个数
2.绑定Nginx worker进程到指定的CPU内核
3.SSL硬件加速
4.系统调用 gettimeofday 的执行频率
5.Nginx worker进程优先级设置
2.3.4 事件类配置项
1.是否打开accept锁
2.lock文件的路径
3.使用accept锁后到真正建立连接之间的延迟时间
4.批量建立新连接
5。选择事件模型
6.每个worker的最大连接数

nginx base

1.搭建

1.1 安装 nginx

1.1.1 环境-操作系统

  • Linux 2.6 及以上版本的操作系统
    • 为Linux 2.6及以上内核才支持epoll,而在Linux上使用select或poll来解决事件的多路复用,是无法解决高并发压力问题的
    • 使用 uname -a 命令来查询 Linux 内核版本

1.1.2 环境-软件

  • GCC编译器
    • GCC(GNU Compiler Collection)可用来编译C语言程序
    • yum install -y gcc
    • yum install -y gcc-c++
  • PCRE库:
    • PCRE(Perl Compatible Regular Expressions,Perl兼容正则表达式)如果我们在配置文件nginx.conf里使用了正则表达式,那么在编译Nginx时就必须把PCRE库编译进Nginx,因为Nginx的HTTP模块要靠它来解析正则表达式。当然,如果你确认不会使用正则表达式,就不必安装它。
    • yum install -y pcre pcre-devel
  • zlib库
    • zlib库用于对HTTP包的内容做gzip格式的压缩,如果我们在nginx.conf里配置了gzip on,并指定对于某些类型(content-type)的HTTP响应使用gzip来进行压缩以减少网络传输量,那么,在编译时就必须把zlib编译进Nginx。
    • yum install -y zlib zlib-devel
  • OpenSSL开发库
    • 如果我们的服务器不只是要支持HTTP,还需要在更安全的SSL协议上传输HTTP,那么就需要拥有OpenSSL了。另外,如果我们想使用MD5、SHA1等散列函数,那么也需要安装它。
    • yum install -y openssl openssl-devel

1.1.3 环境-磁盘

  • Nginx源代码存放目录

该目录用于放置从官网上下载的Nginx源码文件,以及第三方或我们自己所写的模块源代码文件。

  • Nginx编译阶段产生的中间文件存放目录

该目录用于放置在configure命令执行后所生成的源文件及目录,以及make命令执行后生成的目标文件和最终连接成功的二进制文件。默认情况下,configure命令会将该目录命名为objs,并放在Nginx源代码目录下。

  • 部署目录

该目录存放实际Nginx服务运行期间所需要的二进制文件、配置文件等。默认情况下,该目录为/usr/local/nginx。

  • 日志文件存放目录

日志文件通常会比较大,当研究Nginx的底层架构时,需要打开debug级别的日志,这个级别的日志非常详细,会导致日志文件的大小增长得极快,需要预先分配一个拥有更大磁盘空间的目录。

1.1.4 环境-Linux内核参数的优化

在优化内核时,可以做的事情很多,不过,我们通常会根据业务特点来进行调整,当Nginx作为静态Web内容服务器、反向代理服务器或是提供图片缩略图功能(实时压缩图片)的服务器时,其内核参数的调整都是不同的。这里只针对最通用的、使Nginx支持更多并发请求的TCP网络参数做简单说明。

/etc/sysctl.conf

/etc/sysctl.conf
fs.file-max=999999 net.ipv4.tcp_tw_reuse=1 net.ipv4.tcp_keepalive_time=600 net.ipv4.tcp_fin_timeout=30 net.ipv4.tcp_max_tw_buckets =5000 net.ipv4.ip_local_port_range=1024 61000 net.ipv4.tcp_rmem=4096 32768 262142 net.ipv4.tcp_wmem=4096 32768 262142 net.core.netdev_max_backlog=8096 net.core.rmem_default=262144 net.core.wmem_default=262144 net.core.rmem_max=2097152 net.core.wmem_max=2097152 net.ipv4.tcp_syncookies=1 net.ipv4.tcp_max_syn.backlog=1024
  • file-max:这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直接限制最大并发连接数,需根据实际情况配置。

  • tcp_tw_reuse:这个参数设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接,这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接。

  • tcp_keepalive_time:这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置得小一些,可以更快地清理无效的连接。

  • tcp_fin_timeout:这个参数表示当服务器主动关闭连接时,socket保持在FIN-WAIT-2状态的最大时间。

  • tcp_max_tw_buckets:这个参数表示操作系统允许TIME_WAIT套接字数量的最大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。

  • tcp_max_syn_backlog:这个参数表示TCP三次握手建立阶段接收SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求。

  • ip_local_port_range:这个参数定义了在UDP和TCP连接中本地(不包括连接的远端)端口的取值范围。

  • net.ipv4.tcp_rmem:这个参数定义了TCP接收缓存(用于TCP接收滑动窗口)的最小值、默认值、最大值。

  • net.ipv4.tcp_wmem:这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小值、默认值、最大值。

  • netdev_max_backlog:当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。这个参数表示该队列的最大值。

  • rmem_default:这个参数表示内核套接字接收缓存区默认的大小。

  • wmem_default:这个参数表示内核套接字发送缓存区默认的大小。

  • rmem_max:这个参数表示内核套接字接收缓存区的最大大小。

  • wmem_max:这个参数表示内核套接字发送缓存区的最大大小。

注意:滑动窗口的大小与套接字缓存区会在一定程度上影响并发连接的数目。每个TCP连接都会为维护TCP滑动窗口而消耗内存,这个窗口会根据服务器的处理速度收缩或扩张。 参数wmem_max的设置,需要平衡物理内存的总大小、Nginx并发处理的最大连接数量(由nginx.conf中的worker_processes和worker_connections参数决定)而确定。当然,如果仅仅为了提高并发量使服务器不出现Out OfMemory问题而去降低滑动窗口大小,那么并不合适,因为滑动窗口过小会影响大数据量的传输速度。rmem_default、wmem_default、rmem_max、wmem_max这4个参数的设置需要根据我们的业务特性以及实际的硬件成本来综合考虑。
  • tcp_syncookies:该参数与性能无关,用于解决TCP的SYN攻击

1.1.5 下载源码

官网: http://nginx.org/en/download.html

1.2 编译安装 Nginx

shell
cd 到解压目录下 ./configure make make install

1.2.1 命令说明

./configure

configure命令做了大量的“幕后”工作,包括检测操作系统内核和已经安装的软件,参数的解析,中间目录的生成以及根据各种参数生成一些C源码文件、Makefile文件等。

make

make命令根据configure命令生成的Makefile文件编译Nginx工程,并生成目标文件、最终的二进制文件。

make install

make install命令根据configure执行时的参数将Nginx部署到指定的安装目录,包括相关目录的建立和二进制文件、配置文件的复制。

1.3 ./configure 详解

官方文档:http://nginx.org/en/docs/configure.html

1.4 nginx 命令行控制

默认情况下,Nginx被安装在目录 /usr/local/nginx/ 中,其二进制文件路径为 /usr/local/nginc/sbin/nginx,配置文件路径为 /usr/local/nginx/conf/nginx.conf。当然,在configure执行时是可以指定把它们安装在不同目录的。

/usr/local/nginx/sbin/nginx

直接二进制启动:

  • 会读取默认路径下的配置文件:/usr/local/nginx/conf/nginx.conf
  • 实际上,在没有显式指定nginx.conf配置文件路径时,将打开在configure命令执行时使用--conf-path=PATH指定的nginx.conf文件

/usr/local/nginx/sbin/nginx -c /tmp/nginx.conf

指定配置文件启动:

  • 读取-c参数后指定的nginx.conf配置文件来启动Nginx

/usr/local/nginx/sbin/nginx -p /usr/local/nginx/

指定安装目录启动:

  • 使用 -p 次数指定 nginx 的安装目录

/usr/local/nginx/sbin/nginx -g "pid /var/nginx/test.pid"

上面这行命令意味着会把pid文件写到/var/nginx/test.pid中

  • 可以通过-g参数临时指定一些全局配置项,以使新的配置项生效
  • -g 参数的约束条件
    • 指定的配置项不能与默认路径下的nginx.conf中的配置项相冲突,否则无法启动。
    • 以-g方式启动的Nginx服务执行其他命令行时,需要把-g参数也带上,否则可能出现配置项不匹配的情形。如上次关闭 nginx 的命令应该为: /usr/local/nginx/sbin/nginx -g "pid /var/nginx/test.pid" -s stop

/usr/local/nginx/sbin/nginx -t

  • 在不启动 nginx 的情况下,测试配置是否有错误

/usr/local/nginx/sbin/nginx -t -q

  • 测试配置选项时,使用-q参数可以不把error级别以下的信息输出到屏幕

/usr/local/nginx/sbin/nginx -v

  • 使用-v参数显示Nginx的版本信息

/usr/local/nginx/sbin/nginx -V

  • 使用-V参数除了可以显示Nginx的版本信息外,还可以显示配置编译阶段的信息,如GCC编译器的版本、操作系统的版本、执行configure时的参数等

/usr/local/nginx/sbin/nginx -s stop

---等价

kill -s SIGTERM

---等价

kill -s SIGINT

  • 快速地停止服务
  • -s 参数其实是告诉Nginx程序向正在运行的Nginx服务发送信号量
    • Nginx程序通过nginx.pid文件中得到master进程的进程ID,再向运行中的master进程发送TERM信号来快速地关闭Nginx服务
  • 当快速停止服务时,worker进程与master进程在收到信号后会立刻跳出循环,退出进程

/usr/local/nginx/sbin/nginx -s quit

---等价

kill -s SIGWINCH

---等价

kill -s SIGQUIT

  • “优雅”地停止服务
  • 首先会关闭监听端口,停止接收新的连接,然后把当前正在处理的连接全部处理完,最后再退出进程。

/usr/local/nginx/sbin/nginx -s reload

---等价

kill -s SIGHUP

  • 使运行中的Nginx重读配置项并生效
  • Nginx会先检查新的配置项是否有误,如果全部正确就以“优雅”的方式关闭,再重新启动Nginx来实现这个目的

/usr/local/nginx/sbin/nginx -s reopen

---等价

kill -s SIGUSR1

  • 日志文件回滚

  • 使用-s reopen参数可以重新打开日志文件,这样可以先把当前日志文件改名或转移到其他目录中进行备份,再重新打开时就会生成新的日志文件。这个功能使得日志文件不至于过大。

  • 平滑升级Nginx

    • 通知正在运行的旧版本Nginx准备升级

    kill -s SIGUSR2

    • 启动新版本的Nginx
    • 通过kill命令向旧版本的master进程发送SIGQUIT信号,以“优雅”的方式关闭旧版本的Nginx。

2. nginx 的配置

2.1 nginx 进程关系

nginx 支持单进程和 master-worker 两种方式进行进程管理

  • 单进程:有 master 进程提供服务
  • master-worker
    • master 进程只负责监控管理worker进程。worker进程之间通过共享内存、原子操作等一些进程间通信机制来实现负载均衡等功能
    • worker:真正地提供互联网服
    • 一般情况下,worker进程的数量与服务器上的CPU核心数相等
    • 优点:
      • master 进程只做管理工作(启动服务、停止服务、重载配置文件、平滑升级程序等),不受请求的影响
      • 多个worker进程处理互联网请求不但可以提高服务的健壮性(一个worker进程出错后,其他worker进程仍然可以正常提供服务),最重要的是,这样可以充分利用现在常见的SMP多核架构,从而实现微观上真正的多核并发处理
      • worker进程数量设置得与CPU核心数量一致,进程间切换的代价是最小的

nginx 目录结构

|-- client_body_temp |-- conf               #这是Nginx所有配置文件的目录,极其重要 | |-- fastcgi.conf            #fastcgi相关参数的配置文件 | |-- fastcgi.conf.default            #fastcgi.conf的原始备份 | |-- fastcgi_params          #fastcgi的参数文件 | |-- fastcgi_params.default | |-- koi-utf | |-- koi-win | |-- mime.types             #媒体类型, | |-- mime.types.default | |-- nginx.conf              #这是Nginx默认的主配置文件 | |-- nginx.conf.default | |-- scgi_params             #scgi相关参数文件,一般用不到 | |-- scgi_params.default | |-- uwsgi_params        #uwsgi相关参数文件,一般用不到 | |-- uwsgi_params.default | `-- win-utf |-- fastcgi_temp         #fastcgi临时数据目录 |-- html                   #这是编译安装时Nginx的默认站点目录,类似Apache的默认站点htdocs目录 | |--50x.html # 错误页面优雅替代显示文件,例如:出现502错误时会调用此页面 # error_page 500502503504 /50x.html; | `-- index.html # 默认的首页文件,首页文件名字是在nginx.conf中事先定义好的。 |-- logs #这是Nginx默认的日志路径,包括错误日志及访问日志 | |-- access.log # 这是Nginx的默认访问日志文件,使用tail -f access.log,可以实时观看网站用户访问情况信息 | |-- error.log # 这是Nginx的错误日志文件,如果Nginx出现启动故障等问题,一定要看看这个错误日志 | `-- nginx.pid # Nginx的pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件 |-- proxy_temp #临时目录 |-- sbin #这是Nginx命令的目录,如Nginx的启动命令nginx | `-- nginx #Nginx的启动命令nginx |-- scgi_temp #临时目录 `-- uwsgi_temp #临时目录

2.2 nginx 配置的通用语法

nginx
user nobody nobody; worker_processes 8; error_log /var/log/nginx/error.log error; pid logs/nginx.pid; worker_rlimit_nofile 65535; events{ use epoll; worker_connections 65536; }

2.2.1 块配置

块配置项一个块配置项名称一对大括号组成,示例如下:

nginx
events { .... } http { upstream backend { server 127.0.0.1:8080 } gzip on; server { ... location /webstatic { gizp off; } } }

代码段钟的 events,upstream,server,location 等都是块配置项,块配置项后面是否带参数(如 location 的 /webstatic)则由该模块决定

  • 块配置项可以嵌套
  • 内层块直接集成外层块
  • 内外层配置冲突时,以哪一方为准,取决于解析这个配置项的模块。如配置中 webstatic 最后以 gizp off 来处理

2.2.2 配置项的语法格式

配置项名 配置项值1 配置项值2 ...;

  • 行首配置项名

    • 配置项名必须是Nginx的某一个模块想要处理的,否则Nginx会认为配置文件出现了非法的配置项名
    • 配置项名输入结束后,将以空格作为分隔符
  • 配置项值

    • 可以是数字或字符串(当然也包括正则表达式)
    • 针对一个配置项,既可以只有一个值,也可以包含多个值,配置项值之间仍然由空格符来分隔
    • 一个配置项对应的值究竟有多少个,取决于解析这个配置项的模块
    • 我们必须根据某个Nginx模块对一个配置项的约定来更改配置项
  • 结尾分号

  • 注意:如果配置项值钟包含语法符号空格符,那么需要使用单引号或双引号括住配置项值,否则 nginx 回报语法错误

    • log_format main 'remoteaddrremote_addr - remote_user [timelocal]"time_local] "request"';

2.2.3 配置项的注释

#pid logs/nginx.pid;

  • 使用 # 注释

2.2.4 配置项的单位

大部分模块遵循通用的规定

  • 空间大小:
    • K 或者 K千字节(KiloByte, KB)
    • M或者m兆字节(MegaByte,MB)

如:

shell
gzip_buffers 4 8k; client_max_body_size 64M;
  • 指定时间:
    • ms(毫秒),s(秒),m(分钟),h(小时),d(天),w(周,包含7天),M(月,包含30天),y(年,包含365天)

如:

nginx
expires 10y; proxy_read_timeout 600; client_body_timeout 2m;

配置项后的值究竟是否可以使用这些单位,取决于解析该配置项的模块。如果这个模块使用了Nginx框架提供的相应解析配置项方法,那么配置项值才可以携带单位。

2.2.5 配置项中使用变量

有些模块允许在配置项中使用变量,如

nginx
log_format main '$remote_addr - $remote_user [$time_local] "$request"' '$status $bytes_sent "$http_referer"' '"$http_user_agent" "$http_x_forwarded_for"';

remote_addr是一个变量,使用它的时候前面要加上$符号。

需要注意的是,这种变量只有少数模块支持,并不是通用的

提示:在执行configure命令时,我们已经把许多模块编译进Nginx中,但是否启用这些模块,一般取决于配置文件中相应的配置项。换句话说,每个Nginx模块都有自己感兴趣的配置项,大部分模块都必须在nginx.conf中读取某个配置项后才会在运行时启用。例如,只有当配置http{...}这个配置项时,ngx_http_module模块才会在Nginx中启用,其他依赖ngx_http_module的模块也才能正常使用。

2.3 nginx 服务的基本配置

Nginx 在运行时,至少必须加载几个核心模块和一个事件类模块。这些模块运行时所支持的配置项称为基本配置——所有其他模块执行时都依赖的配置项

配置项较多,把它们按照用户使用时的预期功能分成了以下4类:

  • 用于调试、定位问题的配置项
  • 正常运行的必备配置项
  • 优化性能的配置项
  • 事件类配置项(有些事件类配置项归纳到优化性能类,这是因为它们虽然也属于events{}块,但作用是优化性能)

有些配置项,即使没有显式配置,也会有默认值,如 daemon,即使在nginx.conf中没有对它进行配置,也相当于打开了这个功能

2.3.1 用于调试、定位问题的配置项

1. 是否以守护进程方式进行 nginx

语法: daemon on|off;

默认:daemon on;

脱离终端是为了避免进程执行过程中的信息在任何终端上显示,这样一来,进程也不会被任何终端所产生的信息所打断


2.是否以master/worker方式工作

语法:master_process on|off;

默认:master_process on;


3.error日志的设置

语法:error_log /path/file level;

默认:error_log logs/error.log error;

  • 可以根据自己的需求设置error日志的路径和级别。

  • 使用 /dev/null 作为文件路径,不会输出任何日志,这也是关闭 error 日志的唯一手段

  • 取值范围是debug、info、notice、warn、error、crit、alert、emerg,从左至右级别依次增大

    • 大于或等于该级别的日志都会被输出到/path/file文件中,小于该级别的日志则不会输出
  • 如果日志级别设定到debug,必须在configure时加入--with-debug配置项。


4.是否处理几个特殊的调试点

语法:debug_points[stop|abort]

  • Nginx在一些关键的错误逻辑中设置了调试点。
  • 如果设置了debug_points为 stop,那么Nginx的代码执行到这些调试点时就会发出 SIGSTOP 信号以用于调试
  • 如果 debug_points 设置为 abort,则会产生一个 coredump 文件,可以使用 gdb 来查看 Nginx 当时的各种信息。

5.仅对指定的客户端输出debug级别的日志

语法:debug_connection[IP|CIDR]

  • 这个配置项实际上属于事件类配置,因此,它必须放在events{...}中才有效。它的值可以是IP地址或CIDR地址

  • 例如:

    • nginx
      events { debug_connection 10.224.66.14; debug_connection 10.224.57.0/24; }
  • 仅仅来自以上IP地址的请求才会输出debug级别的日志,其他请求仍然沿用error_log中配置的日志级别

  • 使用debug_connection前,需确保在执行configure时已经加入了--with-debug参数,否则不会生效


6.限制coredump核心转储文件的大小

语法:worker_rlimit_core size;

  • 核心转储(core dumps):在Linux系统中,当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内容(核心映像)写入一个文件(core文件),以作为调试之用
  • 当Nginx进程出现一些非法操作(如内存越界)导致进程直接被操作系统强制结束时,会生成核心转储core文件,可以从core文件获取当时的堆栈、寄存器等信息,从而帮助我们定位问题
  • 通过worker_rlimit_core配置可以限制core文件的大小,可以现在core文件大小,从而有效帮助用户定位问题

7.指定coredump文件生成目录

语法:working_directory path;

  • worker进程的工作目录。这个配置项的唯一用途就是设置coredump文件所放置的目录,协助定位问题。因此,需确保worker进程有权限向working_directory指定的目录中写入文件。

2.3.2 正常运行的配置项

1.定义环境变量

语法:env VAR|VAR=VALUE;

  • 这个配置项可以让用户直接设置操作系统上的环境变量
  • 例如: evn TESTPATH=/tmp/;

2.嵌入其他配置文件

语法:include/path/file;

  • include配置项可以将其他配置文件嵌入到当前的nginx.conf文件中
  • 它的参数既可以是绝对路径,也可以是相对路径(相对于Nginx的配置目录,即nginx.conf所在的目录)
  • 参数的值可以是一个明确的文件名,也可以是含有通配符*的文件名,同时可以一次嵌入多个配置文件
nginx
include mime.types; include vhost/*.conf;

3.pid文件的路径

语法:pid path/file;

默认:pid logs/nginx.pid;

  • 保存master进程ID的pid文件存放路径。
  • 默认与configure执行时的参数 “--pid-path” 所指定的路径是相同的,也可以随时修改,但应确保Nginx有权在相应的目标中创建pid文件
  • 该文件直接影响Nginx是否可以运行

4.Nginx worker进程运行的用户及用户组

语法:user username[groupname];

默认:user nobody nobody;

  • user用于设置master进程启动后,fork出的worker进程运行在哪个用户和用户组下。
  • 当按照“user username;”设置时,用户组名与用户名相同。
  • 若用户在configure命令执行时使用了参数--user=username和--group=groupname,此时nginx.conf将使用参数中指定的用户和用户组。

5.指定Nginx worker进程可以打开的最大句柄描述符个数

语法:worker_rlimit_nofile limit;

  • 设置一个worker进程可以打开的最大文件句柄数。

6.限制信号队列语法

语法:worker_rlimit_sigpending limit;

  • 设置每个用户发往Nginx的信号队列的大小。也就是说,当某个用户的信号队列满了,这个用户再发送的信号量会被丢掉。

2.3.3 优化性能的配置项

1.Nginx worker进程个数

语法:worker_processes number;

默认:worker_processes 1;

  • 在master/worker运行方式下,定义worker进程的个数。
  • worker进程的数量会直接影响性能。
  • 配置多少个worker进程才好呢?
    • 如果确认使用的模块不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程;
    • 如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程。
    • 多worker进程可以充分利用多核系统架构,但是worker进程的数量多于CPU内核数,那么会增大进程间切换带来的消耗(Linux是抢占式内核)
    • 例如,如果业务方面会致使用户请求大量读取本地磁盘上的静态资源文件,而且服务器上的内存较小,以至于大部分的请求访问静态资源文件时都必须读取磁盘(磁头的寻址是缓慢的),而不是内存中的磁盘缓存,那么磁盘I/O调用可能会阻塞住worker进程少量时间,进而导致服务整体性能下降。
    • 一般情况下,用户要配置与CPU内核数相等的worker进程,并且使用下面的worker_cpu_affinity配置来绑定CPU内核。

2.绑定Nginx worker进程到指定的CPU内核

语法:worker_cpu_affinity cpumask[cpumask...];

  • 如果多个worker进程都在抢同一个CPU,那么这就会出现同步问题
  • 如果每一个worker进程都独享一个CPU,就在内核的调度策略上实现了完全的并发。

4个 cpu 配置

nginx
worker_processes 4; worker_cpu_affinity 1000 0100 0010 0001;

注意:worker_cpu_affinity配置仅对Linux操作系统有效。Linux操作系统使用sched_setaffinity()系统调用实现这个功能


3.SSL硬件加速

语法:ssl_engine device;

  • 通过命令 openssl engine -t 查看是否有 SSL 硬件加速设备

4.系统调用 gettimeofday 的执行频率

语法:timer_resolution t;

  • 默认情况下,每次内核的事件调用(如epoll、select、poll、kqueue等)返回时,都会执行一次gettimeofday,实现用内核的时钟来更新Nginx中的缓存时钟

  • 当需要降低gettimeofday的调用频率时,可以使用timer_resolution配置。例如,“timer_resolution 100ms;”表示至少每100ms才调用一次gettimeofday。

  • 早期的Linux内核中,gettimeofday的执行代价不小,而目前的大多数内核钟,gettimeofday只是一次vsyscall,仅仅对共享内存页中的数据做访问,并不是通常的系统调用,代价并不大,一般不必使用这个配置


5.Nginx worker进程优先级设置

语法:worker_priority nice;

默认:worker_priority 0;

  • 该配置项用于设置Nginx worker进程的nice优先级。
  • 当许多进程都处于可执行状态时,将按照所有进程的优先级来决定本次内核选择哪一个进程执行
  • 进程所分配的CPU时间片大小也与进程优先级相关,优先级越高,进程分配到的时间片也就越大(例如,在默认配置下,最小的时间片只有5ms,最大的时间片则有800ms)
  • 优先级高的进程会占有更多的系统资源。
  • nice值是进程的静态优先级,它的取值范围是–20~+19,–20是最高优先级,+19是最低优先级。
  • 不建议比内核进程的nice值(通常为–5)还要小。

2.3.4 事件类配置项

1.是否打开accept锁

语法:accept_mutex[on|off]

默认:accept_mutext on;

  • accept_mutex是Nginx的负载均衡锁
  • accept_mutex这把锁可以让多个worker进程轮流地、序列化地与新的客户端建立TCP连接。
  • 当某一个worker进程建立的连接数量达到worker_connections配置的最大连接数的7/8时,会大大地减小该worker进程试图建立新TCP连接的机会,以此实现所有worker进程之上处理的客户端请求数尽量接近。
  • accept锁默认是打开的,如果关闭它,那么建立TCP连接的耗时会更短,但worker进程之间的负载会非常不均衡,因此不建议关闭它

2.lock文件的路径

语法:lock_file path/file;

默认:lock_file logs/nginx.lock;

  • accept锁可能需要这个lock文件
  • 如果accept锁关闭,lock_file配置完全不生效
  • 如果打开了accept锁,并且由于编译程序、操作系统架构等因素导致Nginx不支持原子锁,这时才会用文件锁实现accept锁(14.8.1节将会介绍文件锁的用法),这样lock_file指定的lock文件才会生效。

注意:在基于i386、AMD64、Sparc64、PPC64体系架构的操作系统上,若使用GCC、Intel C++、SunPro C++编译器来编译Nginx,则可以肯定这时的Nginx是支持原子锁的,因为Nginx会利用CPU的特性并用汇编语言来实现它(可以参考14.3节x86架构下原子操作的实现)。这时的lock_file配置是没有意义的。


3.使用accept锁后到真正建立连接之间的延迟时间

语法:accept_mutex_delay Nms;

默认:accept_mutex_delay 500ms;

  • 使用accept锁后,同一时间只有一个worker进程能够取到accept锁
  • 这个accept锁不是阻塞锁,如果取不到会立刻返回。
  • 如果有一个worker进程试图取accept锁而没有取到,它至少要等accept_mutex_delay定义的时间间隔后才能再次试图取锁。

4.批量建立新连接

语法:multi_accept[on|off];

默认:multi_accept off;

当事件模型通知有新连接时,尽可能地对本次调度中客户端发起的所有TCP请求都建立连接。


5。选择事件模型

语法:use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];

默认:Nginx会自动使用最适合的事件模型。

对于Linux操作系统来说,可供选择的事件驱动模型有poll、select、epoll三种。epoll当然是性能最高的一种


6.每个worker的最大连接数

语法:worker_connections number;

定义每个worker进程可以同时处理的最大连接 数。


Cn0+Cn1+Cn2+...Cnn=2n>1000得到n10C{_n^0} + C{_n^1} + C{_n^2} + ...C{_n^n} = 2^n > 1000 \\ 得到 n \geq 10

本文作者:Yui_HTT

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!