Skip to main content

Nginx

Nginx 是经典的路由中间件,可以用来做负载均衡,做网关,做 CDN,做反向代理等等。

Nginx 目录结构

对于 docker 镜像的 Nginx,它默认的几个重要目录位置如下,

  • 存放 html 文件的站点目录:/usr/share/nginx/html
  • 存放配置文件的目录:/etc/nginx
  • 模块目录:/usr/lib/nginx/modules

默认的配置文件位于,/etc/nginx/nginx.conf

Nginx 配置文件格式

Nginx 的配置文件结构基本可以当成一个以空格分割的,带字典的键值对的文件。

使用,

key value [value ...];

value 不是字典。

如果是字典,使用,

key {
key1 value [value ...];
key2 value [value ...];
...
}

Nginx 配置文件头

Nginx 配置内容有很多。这里只讲最重要的几个配置项。

一个配置文件头如下,

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
}
  • user nginx 设置 Nginx 工作进程的运行用户。通常选择一个具有最少权限的用户来运行 Nginx 进程,通常是 nginx 或 www-data。
  • worker_processes auto 设置 Nginx 的工作进程数,可以根据服务器的 CPU 核心数来自动设置。
  • error_log /var/log/nginx/error.log warn 设置 Nginx 的错误日志路径,日志级别为 warn。
  • pid /var/run/nginx.pid 设置 Nginx 主进程的 PID 文件路径。
  • include /etc/nginx/mime.types 加载 MIME 类型文件,这样可以让 Nginx 知道如何处理不同类型的文件。
  • access_log /var/log/nginx/access.log main 设置 Nginx 的访问日志路径,日志格式为 main。
  • sendfile on 启用高效的文件传输方式,允许 Nginx 在内核空间直接将文件发送给客户端,从而提高性能。
  • keepalive_timeout 65 设置服务器与客户端保持连接的最大时间(以秒为单位),通过复用连接来减少延迟。

Nginx 基本路由

默认情况下,nginx 会把 URL 的 / 映射到站点目录的文件夹结构。目录的默认文件是 index.html。即如果 URL 指向一个文件夹,将返回该文件夹下的 index.html

要修改路由的行为,修改 httpserver 部分,如下所示,

server {
listen 80;
server_name example.com;

location / {
root /usr/share/nginx/html;
index index.html;
}

location /images/ {
root /images;
}

location /api/ {
proxy_pass http://backend_server;
}
}
  • listen 80; 设置 Nginx 监听的端口,通常是 80(HTTP 默认端口)
  • server_name example.com; 指定当前 server 块处理的域名或 IP 地址。如果不设置,Nginx 会监听所有的域名和 IP 地址。如果有多个 server 块,nginx 会寻找最匹配的 server 块来处理请求。
  • location path { ... } 定义对于 path 路径,配置的处理逻辑。
  • root path 用于设置站点的根目录。Nginx 会根据请求的路径查找相应的文件。
  • index index.html 指定默认文件,当用户访问目录时,会返回该目录下的 index 文件。
  • proxy_pass http://backend_server; 用于反向代理,将请求转发到其他服务(如 backend_server)。proxy_pass 可以指定多个服务,如 proxy_pass http://backend_server1 http://backend_server2;,这样可以实现负载均衡。proxy_pass 会将原始的请求完全转发给后端服务,后端服务可以处理请求,然后将响应返回给客户端。

Nginx 高级配置

Nginx 提供了许多高级配置选项,用于优化性能、安全性以及特定应用的需求。接下来,我们将介绍一些常见的高级配置和使用场景。

负载均衡配置

Nginx 可用作反向代理,提供负载均衡功能。默认情况下,Nginx 支持基于轮询、IP 哈希、最少连接等算法进行负载均衡。以下是一个简单的负载均衡配置示例:

http {
upstream backend_servers {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_servers;
}
}
}
  • upstream backend_servers { ... }:定义一个名为 backend_servers 的上游服务器组。可以包含多个后端服务器,Nginx 会根据负载均衡算法将请求分发给这些服务器。
  • proxy_pass http://backend_servers;:将客户端的请求转发到 backend_servers 上游组,Nginx 会根据配置的负载均衡算法选择一个服务器处理请求。

基于 IP 哈希的负载均衡

在一些场景下,需要将同一客户端的请求始终路由到同一台服务器。通过 ip_hash 可以实现这种基于客户端 IP 的负载均衡:

http {
upstream backend_servers {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_servers;
}
}
}
  • ip_hash;:启用 IP 哈希负载均衡方式。Nginx 会根据客户端 IP 地址来选择后端服务器,确保相同的 IP 始终请求到同一台服务器。

启用 HTTPS 配置

为了加密通信和提高安全性,Nginx 可以通过 SSL/TLS 配置来支持 HTTPS。下面是一个简单的 HTTPS 配置示例:

server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

location / {
root /usr/share/nginx/html;
index index.html;
}
}
  • listen 443 ssl;:Nginx 监听 443 端口,并启用 SSL。
  • ssl_certificatessl_certificate_key:指定 SSL 证书和私钥文件路径,确保 HTTPS 连接能够建立。

配置请求限流

Nginx 可以通过限制请求的速率来防止滥用或保护后台服务。以下是使用 limit_req 限制请求速率的示例:

http {
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;

server {
listen 80;
server_name example.com;

location / {
limit_req zone=req_limit_per_ip burst=5;
root /usr/share/nginx/html;
index index.html;
}
}
}
  • limit_req_zone:定义了一个限流区域,使用 $binary_remote_addr(客户端 IP 地址的二进制表示)来限制请求的速率。rate=1r/s 表示每个客户端每秒最多允许 1 个请求。
  • limit_req:应用限流配置,burst=5 允许客户端最多在短时间内请求 5 次,超过后会受到限制。

Nginx 缓存配置

为了提高性能,Nginx 可以缓存静态文件或后端服务的响应。以下是一个简单的缓存配置示例:

http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:10m max_size=1g inactive=60m use_temp_path=off;

server {
listen 80;
server_name example.com;

location / {
proxy_cache cache_zone;
proxy_cache_valid 200 1h;
proxy_pass http://backend_servers;
}
}
}
  • proxy_cache_path:指定缓存目录和缓存策略。levels=1:2 指定缓存目录的层级结构,keys_zone=cache_zone:10m 设置缓存区域的大小,max_size=1g 设置缓存的最大大小。
  • proxy_cacheproxy_cache_valid:启用缓存并配置缓存有效期。proxy_cache_valid 200 1h 表示成功响应的缓存时间为 1 小时。

配置 Nginx 访问控制

Nginx 还支持基于 IP 地址、子网或其他请求属性来控制访问。以下是一个 IP 白名单的示例:

server {
listen 80;
server_name example.com;

location / {
allow 192.168.1.0/24;
deny all;
root /usr/share/nginx/html;
index index.html;
}
}
  • allowdeny:通过 allow 指令设置允许访问的 IP 地址或子网,deny 指令则拒绝其他请求。上述配置只允许 192.168.1.0/24 网段的客户端访问,其他请求将被拒绝。

配置错误页面

为了优化用户体验和网站的可用性,可以配置自定义错误页面:

server {
listen 80;
server_name example.com;

location / {
root /usr/share/nginx/html;
index index.html;
}

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
}
  • error_page 404 /404.html;:当返回 404 错误时,Nginx 会将请求重定向到 /404.html 页面。
  • location = /404.html:处理 /404.html 文件的请求,并通过 internal 限制该文件只能被 Nginx 内部访问。

带复写的反向代理

Nginx 可以在代理的时候编辑请求头和响应头。以下是一个带复写的反向代理示例:

server {
listen 80;
server_name example.com;

location /api {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
rewrite ^/api(.*)$ $1 break;
}
}
  • proxy_set_header:设置请求和响应头的值。
  • rewrite:复写请求路径,将 /api 替换为原始路径,以便后端服务正确处理请求。