目录

Nginx配置

Nginx 的配置文件是一个以块(block)的形式组织一组指令的文本文件。

配置文件路径:

  • Ubuntu apt 安装:/etc/nginx/
  • MacOS brew 安装:/usr/local/etc/nginx/

include

在配置文件中,使用 include 指令来执行对一个特定文件的包含,即将特定文件内容插入到配置文件 include 指令的位置。例如

1
 include mime.types;

以上配置包含了 Nginx 自带的文件扩展列表。

这种组织配置的方式,使我们可以将不同域的配置分开成独立的配置文件。

block

概述

每个块以一个花括号({})来表示。主要块有:

含义
main全局设置,包含一些 Nginx 的基本控制功能。它在配置的顶层,不需要显式写出
events事件设置,控制 Nginx 处理连接的方式
httpHTTP 设置
server主机设置
upstream负载均衡设置
location针对特定 URL 的设置。

块的嵌套关系如下: 

1
2
3
4
5
6
main
├── events
└── http
    ├── server
    │   └── location
    └── upstream

被嵌套的块将继承其父块的设置,也可以重新进行设置。

原理

在 http 块中可以声明多个 server 块,一个 server 块允许配置一个虚拟主机和监听的端口,在 server 块内允许插入多个 location 块,当需要对特定的路径进行URL匹配时,location块允许对这些路径单独设置。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
http {
    include       mime.types;

  # 虚拟主机配置
    server {
        listen       80;
        server_name  bbs.example.com;

        location / {
            proxy_pass        http://localhost:5000;
            # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header  Host  $host;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

        #静态文件,nginx自己处理,不去backend请求tomcat
        location  ~* /download/ {
            root /apps/oa/fs;
}

main 块

nginx在运行时与具体业务功能(比如http服务或者email服务代理)无关的一些参数,比如工作进程数,运行的身份等。

  • woker_processes 2 worker 工作进程的个数。这个数值简单一点可以设置为 cpu 的核数grep ^processor /proc/cpuinfo | wc -l,也是设置为 auto 时的值;如果开启了 ssl 和 gzip 应该设置成与逻辑 CPU 数量一样甚至为2倍,可以减少 I/O 操作;如果 nginx 服务器还有其它服务,可以考虑适当减少。
  • worker_cpu_affinity 在高并发情况下,通过设置 cpu 粘性来降低由于多 CPU 核切换造成的寄存器等现场重建带来的性能损耗。如 worker_cpu_affinity 0001 0010 0100 1000; (四核)。
  • worker_rlimit_nofile 10240 默认是没有设置,可以限制为操作系统最大的限制 65535。

events 块

  • worker_connections 2048 每一个 worker 进程能并发处理(发起)的最大连接数(包括与客户端和后端服务器的连接)。nginx 作为反向代理服务器时,计算公式 最大连接数 = worker_processes * worker_connections/4;当 nginx 作为 http 服务器时,计算公式里面是除以2。
  • use epoll 在 Linux 操作系统下,nginx 默认使用 epoll 事件模型,得益于此,nginx 在 Linux 操作系统下效率相当高。同时 Nginx 在 OpenBSD 或 FreeBSD 操作系统上采用类似于 epoll 的高效事件模型kqueue。在操作系统不支持这些高效模型时才使用 select。

http 块

HTTP 服务相关的一些配置参数。

  • sendfile on 开启高效文件传输模式,sendfile 指令指定 nginx 是否调用 sendfile 函数来输出文件,减少用户空间到内核空间的上下文切换。对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。
  • keepalive_timeout 60 长连接超时时间,单位是秒。如果是大量小文件的场景,设置较长的超时时间可以减少重建连接的开销;如果是大文件的场景,设置时间较短会导致失败。但如果设置时间过长,长时间保持连接会占用大量资源。
  • send_timeout 用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接。
  • client_max_body_size 10m 允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值。
  • client_body_buffer_size 128k 缓冲区代理缓冲用户端请求的最大字节数。

gzip 压缩相关设置

  • gzip on 开启 gzip 压缩输出,减少网络传输。
  • gzip_min_length 1k 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。
  • gzip_buffers 4 16k 设置系统获取几个单位的缓存用于存储 gzip 的压缩结果数据流。“4 16k”代表按原始数据大小以 16k 为单位的 4 倍申请内存。
  • gzip_http_version 1.1 启用 GZip 所需的 HTTP 最低版本,默认 1.1,也可以设置成 1.0。
  • gzip_comp_level 6 GZip 压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理速度最慢。
  • gzip_types 匹配 mime 类型进行压缩,无论是否指定,“text/html” 类型总是会被压缩的。
  • gzip_proxied any Nginx 作为反向代理的时候,决定后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含 ”Via” 的 header 头。
  • gzip_vary on : 和 http 头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过 gzip 压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。

http_proxy 相关设置

  • proxy_connect_timeout 60 nginx 跟后端服务器连接超时时间(代理连接超时)。
  • proxy_read_timeout 60 连接成功后,与后端服务器两个成功的响应操作之间超时时间(代理接收超时)。
  • proxy_buffer_size 4k 设置作为代理服务器从后端 realserver 读取并保存用户信息的缓冲区大小,默认与 proxy_buffers 大小相同。
  • proxy_buffers 4 32k proxy_buffers 缓冲区,nginx 针对单个连接缓存来自后端 realserver 的响应
  • proxy_busy_buffers_size 64k 高负荷下缓冲大小,一般为 proxy_buffers*2
  • proxy_max_temp_file_size 当 proxy_buffers 放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M,设置为0禁用。
  • proxy_temp_file_write_size 64k 当缓存被代理的服务器响应到临时文件时,这个选项限制每次写临时文件的大小。

server块

  • listen 监听端口,默认80,小于1024的要以root启动。可以为listen *:80listen 127.0.0.1:80等形式。
  • server_name 服务器名,如localhostwww.example.com,可以通过正则匹配。

可以根据 server_name 不同,对来自同一端口的访问请求转发到不同的后端服务器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
server {
	listen 80;
	server_name www.a.net;
	location / {
		proxy_pass http://127.0.0.1:5000;
		index index.html index.htm;
	}
}

server {
	listen 80;
    server_name www.a.cn;
    location / {
        proxy_pass http://127.0.0.1:8000;
        index index.html index.htm;
    }
}

upstream 块

在 upstream 块中定义多个后端服务器地址,格式为server ip:port options,通过算法进行负载均衡设置。

例如:

1
2
3
4
5
6
7
upstream backend {
    least_conn;
    server 127.0.0.1:8000 down;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}

least_conn 为负载均衡算法名称,down 表示当前服务器不参与负载均衡。

负载均衡算法

  • round-robin Nginx 默认的轮询算法(不需要在 upstream 块中显式指定),每个请求按时间顺序逐一分配到不同的后端服务器。宕机服务器会被自动剔除。可以通过 weight 指定轮询权值,weight 值越大,该服务器被访问的概率越高,主要用于后端服务器性能不均的情况。
  • least_conn 请求会被发送到活跃连接数最少的服务器上。
  • ip_hash 按访问 IP 的哈希结果分配请求,来自同一 IP 的用户会固定访问一个后端服务器;
  • hash 按某个键的哈希结果分配(键可以是文本、变量等)请求。例如 hash $request_uri 即是按请求地址生成哈希结果。

状态参数

状态参数含义
down当前服务器暂时不参与负载均衡,对该服务器的请求会自动发送到下一个服务器
max_fails允许请求失败的次数,默认为1。当超过最大次数时,返回对应的 XX_next_upstream 模块定义的错误。
fail_timeout在经历了 max_fails 次失败后,暂停服务的时间,默认是 10s。
backup预留的备份服务器。当其他所有非 backup 服务器出现故障或者忙时,才会请求 backup 服务器。

location 块

  • root /var/www/html 定义服务器的默认网站根目录位置。如果 location URL匹配的是子目录或文件,root 没什么作用,一般放在 server 指令里面或 / 下。
  • index index.jsp index.html index.htm 定义路径下默认访问的文件名,一般跟着 root 放。
  • proxy_pass http://backend 请求转向 backend 定义的服务器列表,即反向代理,对应 upstream 负载均衡器。如果只有一个服务器地址,也可以不用负载均衡直接写 proxy_pass http://ip:port
  • proxy_set_header Host $host; 让 backend 服务器知道真实请求host。
  • proxy_set_header X-Real-IP $remote_addr; 让 backend 服务器知道真实请求IP。
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 让 backend 服务器知道真实请求 URL;

proxy_pass 是 Nginx 作为反向代理服务器时的重要配置。

URI 匹配规则

按照匹配顺序,如下:

  • = 开头表示精确匹配;
  • 完整路径匹配;
  • ^~ 开头表示以某个常规字符串开头,不是正则匹配;
  • ~ 开头表示区分大小写的正则匹配;
  • ~* 开头表示不区分大小写的正则匹配;
  • /images/abc 表示最长字符匹配,匹配包含 /images/abc 的URI;
  • / 通用匹配,如果没有其它匹配,任何请求都会匹配到;

举个例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ]
}

location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ]
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址
}

location ^~ /images/ {
  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
}

location /images/ {
  # 字符匹配到 /images/
}

location /images/abc {
  # 最长字符匹配到 /images/abc,优先级高于上一条
  [ configuration G ]
}

HTTPS 设置

使用 Let’s Encrypt 的 HTTPS 证书设置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
http {
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    include     /etc/letsencrypt/options-ssl-nginx.conf;
    add_header  Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    server {
        listen 443 ssl;
        server_name xxxxx;

        ssl_certificate     /etc/letsencrypt/live/jupyter.mrchi.cc/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/jupyter.mrchi.cc/privkey.pem;
    }

    # HTTP 请求301重定向到 HTTPS
    server {
        listen 80;
        server_name xxxxx;
        return 301 https://$server_name$request_uri;
    }
}

WebSocket 设置

1
2
3
4
5
6
7
8
location ~ /api/kernels/ {
    proxy_pass          http://localhost:8888;
    proxy_set_header    Host       $host;
    proxy_http_version  1.1;
    proxy_set_header    Upgrade    "websocket";
    proxy_set_header    Connection "Upgrade";
    proxy_read_timeout  86400;
}

Default server 配置

444 状态码是 Nginx 专用状态码,会直接关闭连接,不会返回任何内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    server_name _;

    ssl_certificate     /etc/letsencrypt/live/jupyter.mrchi.cc/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/jupyter.mrchi.cc/privkey.pem;

    return 444;
}

其他

测试配置:

1
sudo nginx -t

加载配置:

1
sudo nginx -s reload