Nginx应用与运维——Nginx核心配置指令(一)

Nginx核心配置指令

作为一款高性能的HTTP服务器软件,Nginx的核心功能就是应对HTTP请求的处理。由于具体硬件、操作系统及应用场景的不同,需要Nginx在对HTTP请求的处理方法上进行不同的调整,为了应对这些差异,Nginx提供了多种配置指令,让用户可以根据实际的软硬件及使用场景进行灵活配置。

Nginx的配置指令很多,为了方便理解和使用,可以按照其在代码中的分布,将其分为核心配置指令和模块配置指令两大类。核心配置指令分为事件核心配置指令和HTTP核心配置指令,事件核心配置指令主要是与Nginx自身软件运行管理及Nginx事件驱动架构有关的配置指令;HTTP核心配置指令是对客户端从发起HTTP请求、完成HTTP请求处理、返回处理结果,到关闭HTTP连接的完整过程中的各个处理方法进行配置的配置指令。模块配置指令是在每个Nginx模块中对所在模块的操作方法进行配置的配置指令。

1、Nginx配置文件解析

Nginx默认编译安装后,配置文件都会保存在/usr/local/nginx/conf目录下,在配置文件目录下,Nginx默认的主配置文件是nginx.conf,这也是Nginx唯一的默认配置入口。

1.1、配置文件目录

Nginx配置文件在conf目录下,其默认目录结构如下。

bash 复制代码
conf/ 
    ├── fastcgi.conf
    ├── fastcgi.conf.default
    ├── fastcgi_params
    ├── fastcgi_params.default
    ├── koi-utf
    ├── koi-win
    ├── mime.types
    ├── mime.types.default
    ├── nginx.conf
    ├── nginx.conf.default
    ├── scgi_params
    ├── scgi_params.default
    ├── uwsgi_params
    ├── uwsgi_params.default
    └── win-utf

其中,以".default"为扩展名的文件是Nginx配置文件的配置样例文件。各配置文件的说明如下。

  • fastcgi_params: Nginx在配置FastCGI代理服务时会根据fastcgi_params文件的配置向FastCGI服务器传递变量,该配置文件现已由fastcgi.conf代替。
  • fastcgi.conf:为了规范配置指令SCRIPT_FILENAME的用法,引入FastCGI变量传递配置。
  • mime.types: MIME类型映射表,Nginx会根据服务端文件后缀名在映射关系中获取所属文件类型,将文件类型添加到HTTP消息头字段"Content-Type"中。
  • nginx.conf: Nginx默认的配置入口文件。
  • scgi_params: Nginx在配置SCGI代理服务时会根据scgi_params文件的配置向SCGI服务器传递变量。
  • uwsgi_params: Nginx在配置uWSGI代理服务时会根据uwsgi_params文件的配置向uWSGI服务器传递变量。
  • koi-utf、koi-win、win-utf:这3个文件是KOI8-R编码转换的映射文件,因为Nginx的作者是俄罗斯人,在Unicode流行之前,KOI8-R是使用最为广泛的俄语编码。

1.2、配置文件结构

为了便于了解Nginx配置文件的内部结构,这里约定几个名词的定义。

  • 配置指令:在配置文件中,由Nginx约定的内部固定字符串,Nginx官方文档中的英文单词为directive,本书中则统一称为配置指令,简称指令。指令是Nginx中功能配置的最基本元素,Nginx的每个功能配置都是通过多个不同的指令组合来实现的。
  • 配置指令值:每个配置指令都有对应的内容来表示该指令的控制参数,本书中约定其对应的内容为配置指令值,简称指令值。指令值可以是字符串、数字或变量等多种类型。
  • 配置指令语句:指令与指令值组合构成指令语句。一条指令语句可以包含多个配置指令值,在Nginx配置文件中,每条指令语句都要用";"作为语句结束的标识符。
  • 配置指令域:配置指令值有时会是由"{}"括起来的指令语句集合,本书中约定"{}"括起来的部分为配置指令域,简称指令域。指令域既可以包含多个指令语句,也可以包含多个指令域。
  • 配置全局域:配置文件nginx.conf中上层没有其他指令域的区域被称为配置全局域,简称全局域。

Nginx的常见配置指令域如表所示。

打开系统默认的nginx.conf文件,可以看到整个文件的结构如下。

bash 复制代码
#user  nobody;
worker_processes  1;                        # 只启动一个工作进程
events {
    worker_connections  1024;               # 每个工作进程的最大连接为1024
}
http {
    include       mime.types;               # 引入MIME类型映射表文件
    default_type  application/octet-stream;   # 全局默认映射类型为application/octet-stream

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    sendfile        on;                     # 启用零复制机制
    keepalive_timeout  65;                  # 保持连接超时时间为65s
    server {
        listen       80;                    # 监听80端口的网络连接请求
        server_name  localhost;             # 虚拟主机名为localhost
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html; 
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

由上述配置文件可以看出,配置文件中的指令和指令值是以类似于key-value的形式书写的。写在配置文件全局域的指令是Nginx配置文件的核心指令,主要是对Nginx自身软件运行进行配置的指令。其中,events和http所包含的部分分别为事件指令域和HTTP指令域,指令域内的指令则明确约定了该区域内的指令的应用范围。server指令域被包含于http指令域中,同时又包含了location指令域,各指令域中的共用范围逐层被上层指令域限定,可见各指令域匹配的顺序是由外到内的。Nginx的配置指令按照内部设定可以同时编写在不同指令域中,包含在最内层的指令将对外层同名指令进行指令值覆盖,并以最内层指令配置为最终生效配置。

编写Nginx配置文件时,为了便于维护,也会把一些指令或指令域写在外部文件中,再通过include指令引入nginx.conf主配置文件中。例如,配置文件中把写有types指令域的mime.types文件引用到http指令域中。此处使用的是nginx.conf文件的相对路径。

1.3、配置文件中的计量单位

在Nginx配置文件中有很多与容量、时间相关的指令值,Nginx配置文件有如下规范。

  • 1)容量单位可以使用字节、千字节、兆字节或千兆字节,示例如下。

    bash 复制代码
    512
    1k或1K
    10m或10M
    1g或10G
  • 2)时间的最小单位是毫秒,示例如下。

    bash 复制代码
    10ms  # 10毫秒
    30s     # 30秒
    2m      # 2分钟
    5h      # 5小时
    1h 30m  # 1小时30分
    6d      # 6天
    3w      # 3周
    5M      # 5个月
    2y      # 2年

1.4、配置文件中的哈希表

Nginx使用哈希表加速对Nginx配置中常量的处理,如server中的主机名、types中的MIME类型映射表、请求头属性字段等数据集合。哈希表是通过关键码来快速访问常量对应值的数据存储结构,在通过哈希表获取数据的过程中,其内部实现通过相关函数将常量名转换为一个关键码来实现对应值的快速定位和读取。由于数据的复杂性,会出现不同常量名转换的关键码是一样的情况,这就会导致读取对应值时发生冲突。为了解决这个问题,Nginx同时引入了哈希桶机制,就是把相同关键码的哈希键存在一个哈希桶定义的存储空间中,然后再进行二次计算来获取对应的值。

单个哈希桶的大小等于CPU缓存行大小的倍数。这样就可以通过减少内存访问的数量来加速在CPU中搜索哈希关键码的速度。如果哈希桶的大小等于CPU的缓存行的大小,在Nginx进行哈希关键码搜索期间,内存的访问次数最多是两次,一次是计算哈希桶的地址,另一次是在哈希桶内进行哈希关键码的搜索。

Linux系统下查看CPU缓存行的指令如下。

bash 复制代码
cat /proc/cpuinfo |grep cache_alignment

Nginx在每次启动或重新加载配置时会选择合适大小的最小初始化哈希表。哈希表的大小会随哈希桶数量的增加而不断调整,直到哈希桶总的大小达到哈希表设置的最大值。因此,在Nginx提示需要增加哈希表或哈希桶的大小时,要先调整哈希表的大小。

2、Nginx的进程核心配置指令

Nginx的进程核心配置指令包含在Nginx核心代码及事件模块代码中,按配置指令设定的功能可分为进程管理、进程调优、进程调试、事件处理4个部分。

2.1、进程管理

Nginx本身是一款应用软件,在其运行时,用户可对其运行方式、动态加载模块、日志输出等使用其内建的基础配置指令进行配置,指令说明如表所示。

  • pcre_jit需要Nginx在配置编译时加上--with-pcre-jit参数。
  • error_log的日志级别可以为如下值:debug、info、notice、warn、error、crit、alert、emerg。

在Linux系统中,可用如下命令查看当前系统支持的OpenSSL加速引擎信息。

bash 复制代码
openssl engine -t

2.2、进程调优

Nginx是按照事件驱动架构设计的。每个外部请求都以事件的形式被工作进程(Worker Process)响应,并发完成各种功能的操作处理。Nginx工作进程的性能依赖于硬件和操作系统的配置,在实际应用场景中,用户需要按照硬件、操作系统或应用场景需求的侧重点进行相应的配置调整。Nginx的进程调优配置指令如表所示。

2.2.1、线程池指令------thread_pool

配置样例如下:

bash 复制代码
thread_pool pool_1 threads=16;

具体参数说明如下。

  • thread_pool也可以编写在http指令域中。
  • threads参数定义了线程池的线程数。
  • max_queue参数指定了等待队列中的最大任务数,在线程池中所有线程都处于繁忙状态时,新任务将进入等待队列。等待队列中的最大任务数为65536。
  • 线程池指令需要在编译配置时增加--with-threads参数。
2.2.2、定时器方案指令------timer_resolution

配置样例如下:

bash 复制代码
timer_resolution 100ms;

在因频繁调用时间函数引发的资源消耗不大的场景中可不设定该指令。

2.2.3、工作进程优先级指令------worker_priority

配置样例如下:

bash 复制代码
worker_priority -5;

worker_priority指令值的取值范围是-20~19,数值越小,优先级越高,获得的CPU时间就越多。配置生效后可以通过如下命令查看,输出结果如图所示。

bash 复制代码
ps axo command,pid,ni | grep nginx | grep -v grep
2.2.4、工作进程数指令------worker_processes

配置样例如下:

bash 复制代码
worker_processes auto;

工作进程数指令的指令值有两种类型,分别为数字和auto。指令值为auto时,Nginx会根据CPU的内核数生成等数量的工作进程。

2.2.5、工作进程CPU绑定指令------worker_processes

配置样例如下:

bash 复制代码
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

指令值是用CPU掩码来表示的,使用与CPU数量相等位数的二进制值来表示。单个CPU用单个二进制值表示,多个CPU组合可用二进制值相加来表示。如配置样例所示,CPU有8个核,分别表示绑定了从第0核到第7核的CPU。CPU核数是从0开始计数的。

指令值除了可以是CPU掩码外,还可以是auto。当指令值为auto时,Nginx会自动进行CPU绑定。

配置样例如下:

bash 复制代码
worker_processes auto;  
worker_cpu_affinity auto;

工作进程与CPU核数也可以是多种对应组合,指令语句如下:

bash 复制代码
worker_processes 4;  
worker_cpu_affinity 01 10 01 10; # 表示把第1、3工作进程绑定在2核CPU的第0核,第2、4工作
                                 # 进程绑定在2核CPU的第1核

worker_processes 2;  
worker_cpu_affinity 0101 1010;   # 表示把第1工作进程绑定在CPU的第0核和第2核,第2工作进程
                                 # 绑定在CPU的第1核和第3核

工作进程CPU绑定指令仅适合于FreeBSD和Linux操作系统。

2.2.6、工作进程开文件数指令------worker_rlimit_nofile

配置样例如下:

bash 复制代码
worker_rlimit_nofile 65535;
2.2.7、工作进程关闭等待时间指令------worker_shutdown_timeout

配置样例如下:

bash 复制代码
worker_shutdown_timeout 10s;
2.2.8、设置互斥锁文件指令------lock_file

配置样例如下:

bash 复制代码
lock_file logs/nginx.lock;

2.3、进程调试

Nginx调整配置或运行发生异常时,为了及时获知工作进程在事件处理过程中发生的问题,可通过获取内存中各状态机、变量等数据的内容进行调试。Nginx为用户提供了一些调试用的配置指令,方便用户进行进程调试。配置指令如表所示。

2.3.1、主进程指令------debug_points

配置样例如下:

bash 复制代码
debug_points stop;
2.3.2、工作目录指令------working_directory

配置样例如下:

bash 复制代码
working_directory logs

可以使用工具objdump、GDB进行文件分析。

2.3.3、调试文件大小指令------worker_rlimit_core

配置样例如下:

bash 复制代码
worker_rlimit_core 800m;

2.4、事件处理

Nginx是采用事件驱动式架构处理外部请求的,这一架构使得Nginx在现有硬件架构下可以处理数以万计的并发请求。通过事件处理指令的配置可以让Nginx与实际运行的硬件及系统进行有效的适配,从而发挥更加高效的并发处理能力。Nginx的事件处理指令编辑在events指令域中,如表所示。

2.4.1、工作进程并发数指令------worker_connections

配置样例如下:

bash 复制代码
events {
    worker_connections 65535;
}

Linux系统下,因为每个网络连接都将打开一个文件描述符,Nginx可处理的并发连接数受限于操作系统的最大打开文件数,同时所有工作进程的并发数也受worker_rlimit_nofile指令值的限制。

2.4.2、事件处理机制选择指令------use

配置样例如下:

bash 复制代码
events {
    use epoll;
}

Nginx支持的事件模型有select、poll、kqueue、epoll、/dev/poll、eventport。

2.4.3、互斥锁指令------accept_mutex

配置样例如下:

bash 复制代码
events {
    accept_mutex on;
}

在Nginx 1.11.3版本之前,互斥锁指令是默认开启的。

2.4.4、互斥锁等待时间指令------accept_mutex_delay

配置样例如下:

bash 复制代码
events {
    accept_mutex_delay 300ms;
}
2.4.5、多请求支持指令------multi_accept

配置样例如下:

bash 复制代码
events {
    multi_accept on;
}
2.4.6、未完成异步操作最大数指令------worker_aio_requests

配置样例如下:

bash 复制代码
events {
    worker_aio_requests 128;
}
2.4.7、调试指定连接指令------debug_connection

配置样例如下:

bash 复制代码
events {
    debug_connection 127.0.0.1;
    debug_connection localhost;
    debug_connection 192.0.2.0/24;
    debug_connection ::1;
    debug_connection 2001:0db8::/32;
    debug_connection unix:;
    ...
}

该指令需要Nginx在编译时通过--with-debug参数开启。

2.5、核心指令配置样例

本节核心指令的配置样例如下。

bash 复制代码
daemon on;                                              # 以守护进程的方式运行Nginx
pid  logs/nginx.pid;                                    # 主进程ID记录在logs/nginx.pid中
user nobody nobody;                                     # 工作进程运行用户为nobody
load_module "modules/ngx_http_xslt_filter_module.so";   # 加载动态模块ngx_http_xslt_
                                                        # filter_module.so
error_log  logs/error.log debug;                        # 错误日志输出级别为debug
pcre_jit on;                                            # 启用pcre_jit技术
thread_pool default threads=32 max_queue=65536;         # 线程池的线程数为32,等待队列中的最大
                                                          # 任务数为65536
timer_resolution 100ms;                                 # 定时器周期为100毫秒
worker_priority -5;                                     # 工作进程系统优先级为-5
worker_processes auto;                                  # 工作进程数由Nginx自动调整
worker_cpu_affinity auto;                               # 工作进程的CPU绑定由Nginx自动调整
worker_rlimit_nofile 65535;                             # 所有工作进程的最大连接数是65535
worker_shutdown_timeout 10s;                            # 工作进程关闭等待时间是10秒
lock_file logs/nginx.lock;                              # 互斥锁文件的位置是logs/nginx.lock

working_directory logs                                  # 工作进程工作目录是logs
debug_points stop;                                      # 调试点模式为stop
worker_rlimit_core 800m;                                # 崩溃文件大小为800MB

events {
    worker_connections 65535;                           # 每个工作进程的最大连接数是65535
    use epoll;                                          # 指定事件模型为epoll
    accept_mutex on;                                    # 启用互斥锁模式的进程调度
    accept_mutex_delay 300ms;                           # 互斥锁模式下进程等待时间为300毫秒
    multi_accept on;                                    # 启用支持多连接
    worker_aio_requests 128;                            # 完成异步操作最大数为128
    debug_connection 192.0.2.0/24;                       # 调试指定连接的IP地址和端口是192.0.2.0/24
}
相关推荐
android阿杜1 小时前
Ubuntu 26.04 LTS 系统每次重启后屏幕亮度都会增加一点
linux·运维·ubuntu
路溪非溪2 小时前
Linux下Shell脚本基础知识(二)
linux·运维·服务器
fruge2 小时前
飞牛OS部署Flare导航页:Docker Compose、YAML书签配置与cpolar公网访问
运维·docker·容器
NailiConveyor2 小时前
输送机皮带材质选型指南:PVC、PU、橡胶、模块化塑料各适用什么场景?
大数据·运维·自动化·制造·业界资讯·材质
不会就选b3 小时前
Linux之再次理解udp
linux·运维·udp
我命由我123453 小时前
自动化 / 智能装配的对象、内容、层级
运维·学习·职场和发展·自动化·求职招聘·职场发展·学习方法
guo_wen_qiang3 小时前
云服务器kibana环境搭建
linux·运维·服务器
海宇大数据3 小时前
零信任架构实战:基于海宇车辆出险记录核验构建自动化二手车收车评估网关
运维·人工智能·架构·自动化
Lsetea3 小时前
OpenSSL报path length constraint exceeded:CA层级与pathlen排查
运维·https·ssl证书·openssl·证书链