高性能的 HTTP 和反向代理服务器详解
在学习本章内容前,请先思考以上问题。带着问题学习,能够帮助您更好地理解和掌握知识点。
Nginx(发音为"engine x")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。本章将介绍Nginx的基本概念、特点和应用场景。
Nginx 是一个开源的 Web 服务器,以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。它可以用作 Web 服务器、反向代理服务器、负载均衡器、邮件代理和 HTTP 缓存。
Nginx 的发展历程:
Nginx 相比其他 Web 服务器有以下优势:
小知识:Nginx 的名称来源于"引擎 X"(Engine X),象征其强大的引擎特性。而 Apache HTTP Server 更侧重于功能的全面性,Nginx 则专注于核心功能的高性能实现。
特性 | Nginx | Apache HTTP Server | IIS |
---|---|---|---|
处理模型 | 异步非阻塞事件驱动 | 多进程/多线程 | 多线程 |
资源消耗 | 低 | 中到高 | 中到高 |
高并发处理 | 优秀 | 一般 | 一般 |
配置复杂度 | 简单 | 中等 | 图形界面,较简单 |
操作系统 | 跨平台 | 跨平台 | 仅 Windows |
动态内容 | 需要通过代理 | 内置支持 (mod_php 等) | 内置支持 (ASP.NET) |
在学习本章内容前,请先思考以上问题。带着问题学习,能够帮助您更好地理解和掌握知识点。
本章将介绍如何在不同操作系统上安装 Nginx,并了解其基本配置文件结构和常用命令。
大多数 Linux 发行版都在其官方软件仓库中提供 Nginx 包。
Ubuntu/Debian:
sudo apt update
sudo apt install nginx
CentOS/RHEL:
sudo yum install epel-release
sudo yum install nginx
使用官方仓库安装最新版本(推荐):
# Ubuntu/Debian
sudo apt install curl gnupg2 ca-certificates lsb-release
echo "deb https://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install yum-utils
sudo tee /etc/yum.repos.d/nginx.repo << EOF
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF
sudo yum install nginx
Nginx 提供 Windows 版本的二进制文件:
C:\nginx
start nginx
启动服务器使用 Homebrew 安装 Nginx:
brew install nginx
如果需要自定义编译选项或使用特定模块,可以从源码编译:
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module
make
sudo make install
提示:使用包管理器安装 Nginx 通常会自动配置系统服务,而手动安装则需要额外步骤来配置自启动服务。
Nginx 的配置文件通常位于 /etc/nginx/
目录(Linux)或安装目录下的 conf
文件夹(Windows)。主配置文件是 nginx.conf
,它包含其他配置文件的引用。
nginx.conf
- 主配置文件conf.d/*.conf
- 包含的配置文件目录sites-available/
- 可用站点配置sites-enabled/
- 已启用站点的符号链接modules-enabled/
- 已启用模块的配置user nginx; # 运行 Nginx 的用户
worker_processes auto; # 工作进程数,通常设置为 CPU 核心数
error_log /var/log/nginx/error.log warn; # 错误日志
pid /var/run/nginx.pid; # 存储主进程 PID 的文件
events {
worker_connections 1024; # 每个工作进程的最大连接数
}
http {
include /etc/nginx/mime.types; # 包含 MIME 类型定义
default_type application/octet-stream; # 默认 MIME 类型
# 日志格式定义
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 /var/log/nginx/access.log main; # 访问日志
sendfile on; # 启用 sendfile 系统调用
tcp_nopush on; # 优化网络包传输
tcp_nodelay on; # 禁用 Nagle 算法
keepalive_timeout 65; # 保持连接超时时间
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
}
在 /etc/nginx/conf.d/default.conf
中:
server {
listen 80; # 监听端口
server_name example.com www.example.com; # 服务器名称
location / {
root /usr/share/nginx/html; # 根目录
index index.html index.htm; # 默认文件
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Nginx 提供了多种命令来控制服务器操作:
命令 | 描述 |
---|---|
nginx 或 systemctl start nginx |
启动 Nginx |
nginx -s stop 或 systemctl stop nginx |
快速停止 Nginx |
nginx -s quit 或 systemctl quit nginx |
优雅停止 Nginx(等待工作进程处理完现有请求) |
nginx -s reload 或 systemctl reload nginx |
重新加载配置文件 |
nginx -s reopen |
重新打开日志文件 |
nginx -t |
测试配置文件是否有语法错误 |
nginx -v |
显示 Nginx 版本 |
nginx -V |
显示 Nginx 版本、编译参数和配置参数 |
sudo systemctl start nginx # 启动 Nginx
sudo systemctl stop nginx # 停止 Nginx
sudo systemctl restart nginx # 重启 Nginx
sudo systemctl reload nginx # 重新加载配置
sudo systemctl status nginx # 查看 Nginx 状态
sudo systemctl enable nginx # 设置开机自启动
sudo systemctl disable nginx # 禁用开机自启动
在 Windows 命令提示符中:
cd C:\nginx
start nginx # 启动 Nginx
nginx -s stop # 停止 Nginx
nginx -s quit # 优雅停止
nginx -s reload # 重新加载配置
nginx -s reopen # 重新打开日志
实例:配置验证最佳实践
在更改配置后,始终进行验证并使用 reload 命令:
sudo nginx -t && sudo systemctl reload nginx
这样可以确保只有在配置正确的情况下才会重新加载 Nginx。
在学习本章内容前,请先思考以上问题。带着问题学习,能够帮助您更好地理解和掌握知识点。
要熟练使用 Nginx,需要了解其核心概念和架构设计。本章将深入探讨 Nginx 的工作原理以及关键配置元素。
Nginx 采用主从架构,由一个 master 进程和多个 worker 进程组成:
Nginx 使用异步非阻塞 I/O 模型处理请求:
小知识:一个 Nginx worker 进程可以处理 10,000+ 并发连接,而传统的多线程服务器每个线程通常只能处理一个连接。
Nginx 配置文件使用简单直观的语法,基于块和指令组织:
main
:全局配置,影响整个服务器events
:事件处理配置http
:HTTP 服务器配置server
:虚拟主机配置location
:请求 URI 匹配规则mail
:邮件服务器配置(如果启用)stream
:TCP/UDP 代理配置(1.9.0+ 版本)大多数指令都遵循自上而下的继承规则:
add_header
)不继承而是完全替换# 全局配置 (main 上下文)
user nginx;
worker_processes 4;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# 事件配置 (events 上下文)
events {
worker_connections 1024;
}
# HTTP 配置 (http 上下文)
http {
include /etc/nginx/mime.types;
default_type 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 /var/log/nginx/access.log main;
# 全局 HTTP 选项
sendfile on;
keepalive_timeout 65;
# 虚拟主机配置 (server 上下文)
server {
listen 80;
server_name example.com;
# URI 匹配配置 (location 上下文)
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ {
proxy_pass http://backend_servers;
}
}
# 另一个虚拟主机
server {
listen 80;
server_name sub.example.com;
location / {
root /var/www/sub;
index index.html;
}
}
}
Server 块定义了虚拟服务器,允许 Nginx 在单个 IP 地址上处理多个域名。每个 server 块需要包含 listen
指令(指定端口)和 server_name
指令(指定域名)。
server {
listen 80; # 监听端口
server_name example.com; # 服务器名称
# 其他配置...
}
server_name
指令用于区分请求应该由哪个 server 块处理,支持多种匹配模式:
server_name example.com;
server_name *.example.com;
或 server_name example.*;
server_name ~^www\d+\.example\.com$;
server_name example.com www.example.com;
当一个请求匹配多个 server 块时,Nginx 按以下优先级选择:
listen 80 default_server;
指定)当请求的 Host 头不匹配任何 server_name 时,Nginx 使用默认 server 块:
server {
listen 80 default_server;
server_name _;
return 404 "No server is configured for this host.";
}
实例:多域名配置
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8080;
}
}
server {
listen 80 default_server;
server_name _;
return 444; # 关闭连接,不返回任何内容
}
Location 块用于根据请求的 URI 处理不同的内容或逻辑,是 Nginx 配置中最灵活的部分。
location = /uri
- 精确匹配location /uri
- 前缀匹配location ^~ /uri
- 优先前缀匹配location ~ pattern
- 区分大小写的正则匹配location ~* pattern
- 不区分大小写的正则匹配location @name
- 命名 location,用于内部重定向Nginx 按以下顺序选择匹配的 location 块:
=
)^~
)~
或 ~*
),按照它们在配置文件中的出现顺序# 精确匹配首页
location = / {
root /var/www/html;
index index.html;
}
# 处理静态文件
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
root /var/www/static;
expires 30d; # 设置缓存时间
}
# API 请求代理到后端
location /api/ {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
return 404;
}
# 命名 location 用于错误处理
error_page 404 @notfound;
location @notfound {
return 301 /404.html;
}
root
- 设置请求的根目录alias
- 替换 location 匹配的部分index
- 定义默认文件try_files
- 按顺序尝试文件return
- 返回指定的状态码和消息rewrite
- 重写 URIproxy_pass
- 将请求代理到后端服务器提示:了解 root
和 alias
的区别非常重要。使用 root
时,完整路径是 root + URI;使用 alias
时,location 匹配的部分会被 alias 替换。
Nginx 提供了许多内置变量,可以在配置中使用:
$uri
- 当前请求的规范化 URI$request_uri
- 完整的原始请求 URI(包含查询参数)$args
- 请求的参数字符串$arg_name
- 特定查询参数的值$request_method
- 请求方法(GET, POST 等)$remote_addr
- 客户端 IP 地址$remote_port
- 客户端端口$server_addr
- 服务器 IP 地址$server_port
- 服务器端口$server_name
- 匹配上的 server_name$http_user_agent
- User-Agent 头$http_referer
- Referer 头$http_host
- Host 头$http_cookie
- Cookie 头$http_x_forwarded_for
- X-Forwarded-For 头$status
- 响应状态码$body_bytes_sent
- 发送给客户端的字节数$bytes_sent
- 发送给客户端的总字节数$request_time
- 请求处理时间(秒)$upstream_response_time
- 上游服务器响应时间# 日志格式中使用变量
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
# 重写规则中使用变量
if ($http_user_agent ~* "Googlebot") {
rewrite ^/(.*)$ /google-bot/$1 last;
}
# proxy_pass 中使用变量
set $backend_server "backend.example.com";
location /api/ {
proxy_pass http://$backend_server;
}
# 根据语言变量提供不同内容
location / {
if ($http_accept_language ~* ^zh) {
root /var/www/html/zh;
}
if ($http_accept_language ~* ^en) {
root /var/www/html/en;
}
index index.html;
}
Nginx 允许在单个 IP 地址上配置多个虚拟主机,每个虚拟主机可以处理不同的域名和端口。本章将介绍如何配置虚拟主机。
每个 server 块需要包含 listen
指令(指定端口)和 server_name
指令(指定域名)。
server {
listen 80; # 监听端口
server_name example.com; # 服务器名称
# 其他配置...
}
server_name
指令用于区分请求应该由哪个 server 块处理,支持多种匹配模式:
server_name example.com;
server_name *.example.com;
或 server_name example.*;
server_name ~^www\d+\.example\.com$;
server_name example.com www.example.com;
当一个请求匹配多个 server 块时,Nginx 按以下优先级选择:
listen 80 default_server;
指定)当请求的 Host 头不匹配任何 server_name 时,Nginx 使用默认 server 块:
server {
listen 80 default_server;
server_name _;
return 404 "No server is configured for this host.";
}
实例:多域名配置
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8080;
}
}
server {
listen 80 default_server;
server_name _;
return 444; # 关闭连接,不返回任何内容
}
Nginx 使用 location 块来匹配请求的 URI,并根据匹配结果处理不同的内容或逻辑。本章将介绍 location 块的语法和使用方法。
location 块的语法如下:
location [ = | ~ | ~* | ^~ ] uri {
# 配置指令
}
=
- 精确匹配~
- 区分大小写的正则匹配~*
- 不区分大小写的正则匹配^~
- 优先前缀匹配Nginx 按以下顺序选择匹配的 location 块:
=
)^~
)~
或 ~*
),按照它们在配置文件中的出现顺序Nginx 按以下顺序选择匹配的 location 块:
=
)^~
)~
或 ~*
),按照它们在配置文件中的出现顺序try_files 指令用于按顺序尝试文件,并根据尝试结果处理请求。
try_files file1 file2 ... fileN = code;
try_files $uri $uri/index.html $uri/index.htm =404;
try_files $uri $uri/index.html $uri/index.htm =404;
alias /path/to/files;
try_files $uri $uri/index.html $uri/index.htm =404;
return 404;
Nginx 可以高效地提供静态文件服务,包括 HTML、CSS、JavaScript、图片等。本章将介绍如何配置静态文件服务。
要配置静态文件服务器,需要使用 root
指令指定文件的根目录,并使用 index
指令指定默认文件。
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
}
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html index.htm;
}
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
}
Nginx 可以使用 expires
指令来配置缓存策略,以减少对后端服务器的负载。
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
}
}
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
}
location ~* \.(html|htm)$ {
expires 1h;
}
}
Nginx 可以用作反向代理服务器,接收客户端请求并转发到后端服务器。本章将介绍如何配置反向代理。
要配置反向代理,需要使用 proxy_pass
指令将请求代理到后端服务器。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 upstream
指令来配置负载均衡,将请求分发到多个后端服务器。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用多种方式进行负载均衡,包括轮询、加权轮询、最少连接和 IP 哈希等。本章将介绍如何配置负载均衡。
Nginx 可以使用 upstream
指令来配置轮询负载均衡。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 least_conn
指令来配置最少连接负载均衡。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以配置 HTTPS 服务器,处理 HTTPS 请求。本章将介绍如何配置 HTTPS 服务器。
要配置 SSL,需要使用 ssl
指令和相关配置。
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert1.pem;
ssl_certificate_key /path/to/key1.pem;
ssl_certificate /path/to/cert2.pem;
ssl_certificate_key /path/to/key2.pem;
}
Nginx 可以使用 ssl_session_cache
指令来配置 SSL 会话缓存。
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_session_cache shared:SSL:10m;
}
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_session_cache shared:SSL:10m;
}
Nginx 提供了多种配置选项来优化性能,包括调整工作进程数、缓存配置和连接超时等。本章将介绍如何优化 Nginx 性能。
Nginx 可以使用 worker_processes
指令来调整工作进程数。
worker_processes auto; # 工作进程数,通常设置为 CPU 核心数
worker_processes 4; # 配置多个工作进程
Nginx 可以使用 proxy_cache
指令来配置缓存。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 keepalive_timeout
指令来配置连接超时。
keepalive_timeout 65; # 保持连接超时时间
keepalive_timeout 65; # 保持连接超时时间
Nginx 提供了多种安全配置选项,包括限制访问、配置访问控制和启用安全功能等。本章将介绍如何配置 Nginx 以提高安全性。
Nginx 可以使用 allow
和 deny
指令来限制访问。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 allow
和 deny
指令来限制访问。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 ssl
指令和相关配置来启用安全功能。
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
server {
listen 80;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
Nginx 可以用于多种应用场景,包括 Web 服务器、反向代理、负载均衡和 API 网关等。本章将介绍如何配置这些应用场景。
要配置 Web 服务器,需要使用 root
指令指定文件的根目录,并使用 index
指令指定默认文件。
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
}
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html index.htm;
}
要配置反向代理,需要使用 proxy_pass
指令将请求代理到后端服务器。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以使用 upstream
指令来配置负载均衡,将请求分发到多个后端服务器。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
Nginx 可以用作 API 网关,将请求路由到相应的服务。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
掌握了 Nginx 的核心概念后,接下来我们将学习如何配置和使用 Nginx 来完成常见任务。
Nginx 作为静态文件服务器非常高效,可以轻松处理 HTML、CSS、JavaScript、图片等文件:
server {
listen 80;
server_name example.com;
# 网站根目录
root /var/www/example;
# 默认索引文件
index index.html index.htm;
# 静态文件缓存设置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
try_files
指令按顺序检查文件是否存在,并使用第一个找到的文件进行请求处理:
location / {
try_files $uri $uri/ /index.html;
}
这个配置会:
可以启用目录列表功能,当访问一个没有索引文件的目录时显示文件列表:
location /downloads/ {
root /var/www/example;
autoindex on;
autoindex_exact_size off; # 以可读格式显示文件大小
autoindex_localtime on; # 显示本地时间
}
可以限制对某些文件或目录的访问:
# 禁止访问隐藏文件
location ~ /\. {
deny all;
return 404;
}
# 保护敏感文件
location ~* \.(htaccess|htpasswd|ini|conf|txt)$ {
deny all;
return 404;
}
# 基于 IP 限制访问
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
}
Nginx 作为反向代理可以将请求转发到后端服务器,是其最常见的应用场景之一。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
注意:在 proxy_pass
中,如果 URL 包含路径(如 http://localhost:8080/app/
),则 location 匹配的部分会被替换成该路径。如果不含路径,则完整的原始 URI 会被追加。
Host
- 确保后端服务器知道原始请求的域名X-Real-IP
- 传递客户端的真实 IPX-Forwarded-For
- 包含请求经过的所有代理 IPX-Forwarded-Proto
- 原始请求的协议(HTTP 或 HTTPS)location /api/ {
proxy_pass http://backend_api;
# 超时设置
proxy_connect_timeout 5s; # 连接超时
proxy_send_timeout 60s; # 发送超时
proxy_read_timeout 60s; # 读取超时
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
}
Nginx 可以代理 WebSocket 连接,需要设置特殊的头部和超时:
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# WebSocket 连接可能长时间保持,增加超时
proxy_read_timeout 3600s;
}
Nginx 可以在多个后端服务器之间分配请求,提供高可用和扩展性。
http {
# 定义上游服务器组
upstream backend_servers {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Nginx 支持多种负载均衡算法:
# 轮询(默认)
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 加权轮询
upstream backend {
server 192.168.1.10:8080 weight=3; # 该服务器接收 3/4 的请求
server 192.168.1.11:8080 weight=1; # 该服务器接收 1/4 的请求
}
# IP 哈希(会话持久性)
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 最少连接
upstream backend {
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 通用哈希
upstream backend {
hash $request_uri consistent; # 基于 URI 的一致性哈希
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup; # 备用服务器
server 192.168.1.13:8080 down; # 标记为不可用
}
参数说明:
max_fails
- 允许的最大失败次数fail_timeout
- 在指定时间内达到最大失败次数后,服务器将被标记为不可用的时间backup
- 备用服务器,仅在所有主服务器不可用时使用down
- 标记服务器为永久不可用weight
- 服务器权重,默认为 1max_conns
- 服务器的最大并发连接数小知识:Nginx 开源版只支持被动健康检查(通过 max_fails 和 fail_timeout)。主动健康检查(定期探测后端服务器状态)需要 Nginx Plus 商业版。
Nginx 提供了强大的 URL 重写功能,可以修改请求 URI 或将客户端重定向到不同的 URL。
server {
listen 80;
server_name example.com;
# 基本重写:将请求从旧路径重写到新路径
rewrite ^/old-page\.html$ /new-page.html permanent;
# 使用捕获组保留 URI 的一部分
rewrite ^/products/(\d+)$ /items/$1 last;
# 处理尾部斜杠
rewrite ^/(.+)/$ /$1 permanent;
# 多个重写规则
location /old-site/ {
rewrite ^/old-site/(.*)$ /new-site/$1 permanent;
}
}
last
- 停止处理当前指令集并从头开始匹配新的 locationbreak
- 停止处理当前指令集但继续在当前 location 内处理redirect
- 返回 302 临时重定向permanent
- 返回 301 永久重定向对于简单重定向,return
指令比 rewrite
更高效:
# 永久重定向
location /old-url {
return 301 https://example.com/new-url;
}
# 临时重定向
location /temp-url {
return 302 https://example.com/temporary;
}
# 返回自定义状态和消息
location /forbidden {
return 403 "Access Forbidden";
}
# 对整个站点强制使用 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
Nginx 支持在 server 和 location 块中使用 if 条件:
server {
listen 80;
server_name example.com;
# 基于查询参数重定向
if ($args ~* utm_source=newsletter) {
return 302 /landing-page;
}
# 检查文件是否存在
if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
# 基于 User-Agent 重写
if ($http_user_agent ~* "Googlebot") {
rewrite ^/(.*)$ /for-bots/$1 last;
}
}
注意:Nginx 开发者不建议过度使用 if 指令,因为它在某些情况下可能导致不可预期的行为。尽可能使用 location 块或 try_files 指令代替。
# 单页应用配置
location / {
try_files $uri $uri/ /index.html;
}
# WordPress 漂亮链接
location / {
try_files $uri $uri/ /index.php?$args;
}
# Laravel 应用
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 域名规范化 (非 www 到 www)
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
# 强制 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}