所在位置:

Nginx 的常用配置

Nginx凭借其高性能、稳定性、丰富的模块生态而成为首选Web服务器之一。但是要发挥Nginx的最大效用,合理的配置同样至关重要。本文将详细讲解Nginx中反向代理、Nginx 限流、静态资源、Nginx的缓存、负载均衡的策略、Gzip 压缩等常见功能的配置方法:

反向代理

Nginx的反向代理是指将客户端发起的请求转发给后端服务器,并将后端服务器返回的响应结果返回给客户端,这个过程对于客户端来说是透明的。

在反向代理中,客户端并不知道自己实际访问的是哪一台服务器,因为客户端只与Nginx进行通信,Nginx再将请求转发给后端服务器。反向代理可以隐藏后端服务器的真实IP地址,在保护后端服务器安全的同时,还可以实现负载均衡、缓存、SSL加速等功能。

反向代理的具体实现可以通过Nginx的配置文件进行设置,例如可以使用 proxy_pass 指令将请求转发到后端服务器,也可以使用 proxy_cache 指令实现缓存功能。总之,通过使用Nginx的反向代理功能,可以提高系统的性能和安全性,同时也可以更好地管理后端服务器。

下面是一个Nginx反向代理的例子,当访问首页,会被代理到 http://172.20.10.2:8080 的后端服务,显示 "Hello World"

server {
    listen       80;
    server_name  127.0.0.1;

    location / {
        proxy_pass  http://172.20.10.2:8080;
        proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;   
    }
}

Nginx 限流

在 Nginx 中,有几种不同的限流方式可供选择,下面分别进行详细说明:

  • 基于连接数的限流

基于连接数的限流是 Nginx 中最常用的限流方式之一。通过限制客户端连接数,可以避免过多的并发请求对服务器的影响。

在 Nginx 中,可以使用 limit_conn_zonelimit_conn 指令实现基于连接数的限流。其中,limit_conn_zone 指令用于定义一个限流区域,limit_conn 指令则用于对该限流区域进行限流。

例如:

http {
    ...
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
    ...
    server {
        ...
        location / {
            limit_conn conn_limit_per_ip 10;
            ...
        }
    }
}

在上面的示例中,limit_conn_zone 指令定义了一个名为 conn_limit_per_ip 的限流区域,用于限制每个 IP 地址的最大连接数。$binary_remote_addr 表示使用客户端的 IP 地址作为限流区域的标识符,10m 表示限流区域的内存大小为 10MB。

limit_conn 指令则表示对 conn_limit_per_ip 限流区域进行连接数限制,这里设置为最大 10 个连接。当某个 IP 地址的连接数超过 10 个时,该 IP 地址的新连接将被拒绝。

  • 基于请求速率的限流

基于请求速率的限流是一种更加细粒度的限流方式,可以根据时间单位内的请求数量来限制请求速率。在 Nginx 中,可以使用 limit_req_zonelimit_req 指令实现基于请求速率的限流。

例如:

http {
    ...
    limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
    ...
    server {
        ...
        location / {
            limit_req zone=req_limit_per_ip burst=5;
            ...
        }
    }
}

在上面的示例中,limit_req_zone 指令定义了一个名为 req_limit_per_ip 的限流区域,用于限制每个 IP 地址的请求速率。$binary_remote_addr 表示使用客户端的 IP 地址作为限流区域的标识符,10m 表示限流区域的内存大小为 10MB,rate=1r/s 表示每秒钟只允许处理 1 个请求。

limit_req 指令则表示对 req_limit_per_ip 限流区域进行请求速率限制,这里设置为最大 5 个请求。当某个 IP 地址在一个时间单位内发送的请求数超过 5 个时,该 IP 地址的新请求将被拒绝。

需要注意的是,limit_req 指令可以指定 burst 参数来控制突发请求的处理。当请求速率超过限制时,如果突发请求的数量没有超过 burst 参数指定的阈值,这些请求将被允许通过。只有在突发请求数量超过 burst 参数指定的阈值时,才会触发请求被拒绝。

  • 基于带宽的限流

基于带宽的限流是一种较为粗粒度的限流方式,可以根据带宽限制请求的传输速率。在 Nginx 中,可以使用 limit_rate 指令实现基于带宽的限流。

例如:

http {
    ...
    server {
        ...
        location / {
            limit_rate 100k;
            ...
        }
    }
}

在上面的示例中,limit_rate 指令用于限制请求的传输速率,这里设置为最大 100k/s。当请求传输速率超过 100k/s 时,请求的传输速率将被限制在 100k/s 以内。

需要注意的是,基于带宽的限流方式对请求的传输速率进行限制,但不会限制请求的数量和连接数。因此,在使用基于带宽的限流方式时,需要同时考虑连接数和请求速率的限制,以确保服务器的稳定性和性能。

静态资源

在 Nginx 中,静态资源是指不需要经过动态处理的文件,例如 HTML、CSS、JS 等文本文件,以及图片、视频、音频等二进制文件。常见的静态资源包括:

  • HTML 文件:网页的基础文件格式,通常包含页面的结构和内容;
  • CSS 文件:用于设置页面样式和布局的文件,可以控制字体、颜色、元素位置等;
  • JavaScript 文件:用于添加交互性和动态效果的脚本文件,可以实现表单验证、下拉菜单等功能;
  • 图片文件:包括 PNG、JPEG、GIF 等格式的图片,用于显示网页中的图像;
  • 音频文件:包括 MP3、WAV、OGG 等格式的音频文件,用于播放网页中的声音;
  • 视频文件:包括 MP4、AVI、FLV 等格式的视频文件,用于播放网页中的视频。

在配置静态资源之前,要先了一下location块中的两个指令 root 和 alias,它们都可以用来指定静态文件所在的目录,但这两个指令还是有很大的区别的,下面来说一下 root 和 alias 的区别:

  • root指令会将url路径加上指定的目录路径作为完整的物理路径,在服务器上查找对应的文件。例如:
location /static/ {
    root /var/www/;
}

这里的 root 指令将请求 /static/images/login.png 映射到本地物理路径 /var/www/static/images/logo.png

  • alias指令会使用指定的目录路径替代请求中的部分路径,然后在服务器上查找文件。例如:
location /static/ {
    alias /var/www/static/;
}

这里的 alias 指令将请求 /static/images/logo.png 映射到本地物理路径/var/www/static/images/logo.png,要注意的是如果 location /static,那 alias 就要变成 /var/www/static;

因此,root 适用于请求的 URL 路径与服务器上的文件系统路径之间的简单映射,而 alias 则更适合需要精细控制URL路径和文件系统路径之间映射的情况。

在配置 location 块的时候还会用到正则,这里还是需要对 location 块的正则做一下补充,在 Nginx 中,location 指令是用于匹配请求 URL 路径的关键指令。在使用 location 指令时,可以通过正则表达式来匹配请求路径,以下是 location 指令中使用的正则表达式规则:

  • ~:使用普通字符区分大小写进行匹配(case-sensitive)。例如:
location ~ /images/ {
    ...
}

此示例将匹配任何以 /images/ 开头的 URL

  • ~*:使用普通字符进行不区分大小写的匹配(case-insensitive)。例如:
location ~* \.(gif|jpg|jpeg)$ {
    ...
}

此示例将匹配以 .gif、.jpg 或 .jpeg 结尾的所有 URL

  • ^~:确定一个非常精确的匹配项,并停止搜索其他定位块。在匹配到该规则后,nginx 将会立即处理对应的请求。例如:
location ^~ /api/ {
    proxy_pass http://localhost:8000/api/;
}

此示例中,如果请求的 URL 以 /api/ 开头,则 nginx 将使用代理服务器将请求转发到 http://localhost:8000/api/

  • =:精确匹配,只有完全匹配的 URL 才会被匹配。例如:
location = /login {
    ...
}

此示例将仅匹配请求路径为 /login 的 URL

  • @:定义一个命名的 location。例如:
location @backend {
    ...
}

此示例将定义一个名为 backend 的 location,用于在其他配置块中引用。

下面就说一下如何配置静态资源:

使用 static 的统一前缀,所有的静态文件都放在 static 目录下

location /static/ {
    root /var/www/;
}

如果访问 /static/images/logo.png,就会映射到本地物理路径 /var/www/static/images/logo.png,同理,其它静态资源一样的访问

Nginx的缓存

Nginx 的缓存分为静态缓存和动态缓存,这里简单说一下静态缓存和动态缓存

nginx 静态缓存可以按以下方式进行分类:
  • 基于 URI 的缓存:这种缓存是根据请求的 URI 进行缓存的,可以缓存整个页面或者其中的某些组件,如图片、CSS 或 JavaScript 文件等。

例如,将以下配置添加到 nginx 的配置文件中可以缓存所有以“/static/”开头的 URI 请求:

location /static/ {
    expires 7d;
}
  • 基于 HTTP 头的缓存:基于 HTTP 头的缓存是指按照请求头中的信息进行缓存,如果两个请求的头信息完全相同,则它们可以使用相同的缓存结果。这种缓存方式适用于那些根据用户的请求头信息返回不同内容的资源,比如根据 Accept-Encoding 头返回不同的压缩格式文件等。

例如,将以下配置添加到 nginx 的配置文件中可以根据 Accept-Encoding 头信息缓存压缩格式的文件:

gzip on;
gzip_types text/plain text/css application/json;
gzip_vary on;

location /static/ {
    expires 7d;
    gzip_static on;
}
  • 基于时间的缓存:基于时间的缓存是指在一定时间内缓存请求的结果。如果在这段时间内有相同的请求,则可以直接使用缓存的结果,而不必再次进行计算或请求。这种缓存方式适用于那些内容相对不频繁更新的资源。

例如,将以下配置添加到 nginx 的配置文件中可以将 /static 目录下的文件缓存 10 分钟:

location /static/ {
    expires 10m;
}
  • 基于文件系统的缓存:基于文件系统的缓存是指将静态文件缓存到文件系统中,以避免每次请求都要读取磁盘。当请求静态文件时,Nginx 可以直接从缓存中获取文件,而不必再次读取磁盘。这种缓存方式适用于那些大型文件或者不经常更新的资源。

例如,将以下配置添加到 nginx 的配置文件中可以将 /var/www/html 目录下的文件缓存到内存中:

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 304 10m;
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;

location / {
    proxy_cache my_cache;
    proxy_pass http://backend;
}
nginx 动态缓存可以按以下方式进行分类:
  • FastCGI缓存:FastCGI是一种协议,用于将Web服务器与后端应用程序连接起来。在Nginx中,可以通过FastCGI缓存来缓存FastCGI协议返回的内容。例如,可以将PHP-FPM的响应缓存起来,避免每次请求都需要重新执行PHP脚本。

  • Proxy缓存:Nginx可以作为反向代理服务器,将请求转发到后端的Web服务器。在这种情况下,可以通过Proxy缓存来缓存后端Web服务器返回的内容。例如,可以将Apache服务器的响应缓存起来,避免每次请求都需要重新执行Apache的处理逻辑。

  • Memcached缓存:Memcached是一种高速缓存系统,可以将数据存储在内存中,以提高访问速度。在Nginx中,可以通过Memcached缓存来缓存一些动态生成的内容,例如动态生成的HTML页面或JSON数据。

  • Redis缓存:Redis是一种高速缓存系统,与Memcached类似,可以将数据存储在内存中。在Nginx中,可以通过Redis缓存来缓存一些动态生成的内容,例如动态生成的HTML页面或JSON数据。

下面是这些分类的例子:

http {
    # 配置 FastCGI 缓存
    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=fastcgi_cache:100m inactive=60m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";

    server {
        listen 80;
        server_name example.com;

        # 配置 FastCGI 缓存
        location ~ \.php$ {
            fastcgi_pass unix:/run/php-fpm.sock;
            fastcgi_cache_bypass $http_pragma;
            fastcgi_cache_revalidate on;
            fastcgi_cache_valid 200 10m;
            fastcgi_cache_use_stale error timeout invalid_header updating http_500;
        }

        # 配置 Proxy 缓存
        location / {
            proxy_pass http://backend_server;
            proxy_cache_bypass $http_pragma;
            proxy_cache_revalidate on;
            proxy_cache_valid 200 10m;
            proxy_cache_key "$scheme$request_method$host$request_uri";
        }

        # 配置 Memcached 缓存
        location /api {
            set $memcached_key "api:$request_uri";
            memcached_pass memcached_server:11211;
            memcached_cache_key $memcached_key;
            memcached_cache_bypass $http_pragma;
            memcached_cache_revalidate on;
            memcached_cache_valid 200 10m;
        }

        # 配置 Redis 缓存
        location /data {
            set $redis_key "data:$request_uri";
            redis_pass redis_server:6379;
            redis_cache_key $redis_key;
            redis_cache_bypass $http_pragma;
            redis_cache_revalidate on;
            redis_cache_valid 200 10m;
        }
    }
}

负载均衡的策略

Nginx的负载均衡是指将来自客户端的请求分发到多个后端服务器上,以达到均衡负载的目的。当网站访问量较大时,单台服务器可能无法承受所有的请求,此时可以使用负载均衡技术将流量分摊到多台服务器上,增加系统的稳定性和可靠性,下面是几种负载均衡的策略:

  • 轮询(round-robin):Nginx按照服务器列表中定义的顺序依次将请求分配给每台服务器

假设我们有3台服务器A、B和C。当客户端向Nginx发送请求时,Nginx会将请求依次转发到A、B和C三台服务器上,然后再从A开始循环

upstream round_robin {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    location / {
        proxy_pass http://round_robin;
    }
}
  • IP哈希(ip-hash):基于客户端IP地址进行哈希计算,并将相同哈希结果的请求转发到同一台服务器上

如果我们有3台服务器A、B和C,客户端1与服务器A建立连接,客户端2与服务器B建立连接,客户端3与服务器C建立连接,则每个客户端发送的请求都会被转发到他们最初连接的那台服务器上

upstream ip_hash {
    ip_hash;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    location / {
        proxy_pass http://ip_hash;
    }
}
  • 最少连接(least-connected):将请求分配给当前连接数最少的服务器

如果我们有3台服务器A、B和C,服务器A已经处理了100个连接,服务器B已经处理了80个连接,服务器C已经处理了50个连接,则新的请求将被转发到服务器C上

upstream least_connected {
    least_conn;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    location / {
        proxy_pass http://least_connected;
    }
}
  • URL哈希(url-hash):将请求的URL地址进行哈希计算,并将相同哈希结果的请求转发到同一台服务上

如果我们有3台服务器A、B和C,针对同一个URL的请求将始终被转发到相同的服务器上,确保用户在执行特定操作时始终访问相同的服务器

upstream url_hash {
    hash $request_uri;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    location / {
        proxy_pass http://url_hash;
    }
}
  • 最快响应时间(least-time):将请求分配给响应时间最短的服务器

如果我们有3台服务器A、B和C,Nginx会先向这三台服务器发送ping请求,然后选择响应时间最短的服务器来处理新的请求

upstream least_time {
    least_time;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    location / {
        proxy_pass http://least_time;
    }
}

Gzip 压缩

要在 Nginx 中启用 gzip 压缩,您需要编辑 nginx.conf 文件 的 http 块中添加以下指令:

gzip on; # 开启 gzip 压缩(默认 off)
# 设置压缩文件的类型
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

这将启用 gzip 压缩,并定义了哪些 MIME 类型应该被压缩。您可以根据需要更改 MIME 类型列表。

如果您想进一步优化 gzip 压缩设置,您可以使用以下指令:

gzip_http_version 1.1; # 设置 gzip 所需的 HTTP 协议最低版本(HTTP/1.1, HTTP/1.0)
gzip_comp_level 6; # 设置压缩级别,压缩级别越高压缩时间越长(1-9)
gzip_min_length 1k; # 设置压缩的最小字节数, 页面 Content-Length 获取
gzip_vary on; # 用于在响应消息头中添加 Vary:Accept-Encoding

这些指令定义了压缩级别、最小压缩文件大小、代理服务器的压缩设置和 Vary 头信息,查看配置是否生效,查看响应头中的 Content-Encoding 字段,值为 gzip

参考链接

【上一篇】在 centos 中安装 nginx

【下一篇】安装和使用webpack