Nginx Web 服务器入门教程:从零开始掌握高性能之道
在当今互联网高速发展的时代,Web 服务器作为连接用户与网站应用的核心组件,其性能和稳定性至关重要。在众多Web服务器软件中,Nginx(发音为 “engine-x”)凭借其高性能、高并发处理能力和低内存消耗脱颖而出,成为了许多高流量网站和应用的首选。无论是静态文件服务、反向代理、负载均衡还是API网关,Nginx都能胜任,并展现出卓越的表现。
如果你是Web开发新手,或是希望了解如何搭建和配置一个高性能的Web服务器,那么学习Nginx将是非常有价值的。本教程旨在帮助你从零开始,逐步掌握Nginx的基础知识、安装、配置和常用功能。
第一章:初识 Nginx – 为什么选择它?
1.1 什么是 Nginx?
Nginx 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器。最初由俄罗斯的 Igor Sysoev 开发,并于2004年发布。它的设计初衷是为了解决 C10k 问题,即单台服务器如何同时处理数万个并发连接。
传统的Web服务器(如 Apache 的 prefork 模型)通常采用多进程或多线程模型,每个连接对应一个进程或线程。当并发连接数量巨大时,创建和管理大量进程/线程会消耗大量系统资源,导致性能下降。
而 Nginx 采用了事件驱动(Event-driven)的异步非阻塞架构。它使用少量的进程来处理大量的并发连接。当一个连接建立后,Nginx 不会为其分配独立的进程或线程,而是将其注册到事件循环中。当该连接有数据可读写时,事件循环会通知 Nginx 工作进程进行处理。这种模型使得 Nginx 在处理高并发连接时表现出色,资源占用极低。
1.2 Nginx 的主要特点与优势
- 高性能和高并发处理能力: 这是 Nginx 最突出的优势。其事件驱动架构使其能轻松处理数万甚至数十万的并发连接,非常适合高流量网站。
- 低内存消耗: 相较于其他一些Web服务器,Nginx 在处理相同负载时通常占用更少的内存。
- 高度模块化: Nginx 的功能由模块提供,可以根据需要编译和加载不同的模块,保持核心的精简和高效。
- 强大的反向代理功能: Nginx 可以作为反向代理服务器,将客户端请求转发到后端的多台应用服务器上,有效隐藏后端服务,增加安全性。
- 灵活的负载均衡: Nginx 支持多种负载均衡算法(如轮询、IP Hash、最少连接等),可以根据后端服务器的负载情况智能分配请求。
- 静态文件服务优化: Nginx 在处理静态文件方面非常高效,可以直接快速响应静态资源请求。
- 支持 HTTP/2 和 WebSocket: 适应现代Web协议和技术。
- 易于配置: Nginx 的配置文件结构清晰,易于理解和编写(尽管初学者可能需要适应其语法)。
1.3 Nginx 的常见应用场景
- 静态资源服务器: 直接托管 HTML、CSS、JavaScript、图片等静态文件。
- 反向代理服务器: 将客户端请求转发给后端的应用服务器(如运行 Node.js, Python Django/Flask, Java Spring Boot 等的服务器),Nginx 负责接收外部请求,处理静态文件、SSL加密、压缩等,然后将动态请求转发给后端。
- 负载均衡器: 将流量分发到多台后端服务器,提高可用性和扩展性。
- API 网关: 作为API请求的入口点,进行认证、限流、监控、路由等。
- 缓存服务器: 缓存后端应用的响应,减少后端压力,加快响应速度。
- SSL 终止: 在 Nginx 层面处理 SSL/TLS 加密和解密,减轻后端服务器的负担。
第二章:安装 Nginx
在开始配置之前,你需要先在你的服务器或本地机器上安装 Nginx。这里我们以 Linux 系统(基于 Debian/Ubuntu 的发行版)为例进行说明,这是 Nginx 最常见的部署环境。对于其他系统,安装方法略有不同,但核心概念类似。
2.1 在 Ubuntu/Debian 上安装
打开终端,运行以下命令:
- 更新包列表:
bash
sudo apt update - 安装 Nginx:
bash
sudo apt install nginx
安装过程会提示你确认,输入 Y
并回车即可。
安装完成后,Nginx 服务通常会自动启动。你可以通过以下命令检查其状态:
bash
sudo systemctl status nginx
如果看到 active (running)
字样,说明 Nginx 已经成功运行。
2.2 防火墙设置 (ufw)
如果你的服务器开启了防火墙(例如 Ubuntu 默认的 ufw),你需要允许 HTTP (80) 和 HTTPS (443) 流量通过。
Nginx 在安装时会注册其配置文件到 ufw。你可以查看可用的应用配置文件:
bash
sudo ufw app list
通常会看到 Nginx Full
, Nginx HTTP
, Nginx HTTPS
选项。
Nginx HTTP
: 只允许端口 80 (HTTP)。Nginx HTTPS
: 只允许端口 443 (HTTPS)。Nginx Full
: 允许端口 80 和 443。
选择 Nginx Full
以便后续配置 HTTPS:
bash
sudo ufw allow 'Nginx Full'
然后重新加载或启用防火墙(如果之前是禁用的):
bash
sudo ufw enable
最后检查防火墙状态:
bash
sudo ufw status
确认 80 和 443 端口已被允许。
2.3 测试安装
安装成功并确保防火墙允许流量后,你可以在浏览器中访问服务器的 IP 地址或域名。如果看到 Nginx 默认的欢迎页面(通常显示 “Welcome to nginx!”),恭喜你,Nginx 已经成功安装并运行了!
第三章:Nginx 配置基础
Nginx 的核心在于其配置文件。理解配置文件的结构和语法是掌握 Nginx 的关键。
3.1 配置文件位置
在大多数 Linux 系统上,Nginx 的主配置文件位于 /etc/nginx/nginx.conf
。
为了更好地组织配置,Nginx 采用了模块化的配置方式。nginx.conf
文件通常会包含一些其他目录中的配置文件。常见的结构如下:
/etc/nginx/nginx.conf
: 主配置文件,包含全局设置和引入其他配置文件。/etc/nginx/conf.d/*.conf
: 这个目录通常用于存放独立的配置片段,例如为不同的虚拟主机或应用配置的独立文件。Nginx 主配置文件中通常有include /etc/nginx/conf.d/*.conf;
这样的指令来加载这些文件。/etc/nginx/sites-available/
: 这个目录存放所有可用的虚拟主机配置文件(每个文件通常对应一个网站或应用)。/etc/nginx/sites-enabled/
: 这个目录存放当前已启用的虚拟主机配置文件的软链接。Nginx 主配置文件通过include /etc/nginx/sites-enabled/*;
来加载这些配置文件。启用或禁用一个虚拟主机通常是通过在sites-enabled
目录中创建或删除到sites-available
中文件的软链接来完成。
重要提示: 在修改任何 Nginx 配置文件之前,强烈建议备份原始文件。
3.2 配置文件的基本语法
- 配置文件由指令(Directives)和块(Blocks)组成。
- 每个指令以指令名称开头,后面跟着一个或多个参数,最后以分号
;
结束。
nginx
directive_name parameter1 parameter2; - 块是一组相关的指令,用大括号
{}
包围。块可以嵌套。
nginx
block_name {
directive1 parameter;
directive2 parameter parameter;
# ... more directives
} - 注释以
#
开头,直到行尾。
nginx
# This is a comment
3.3 配置文件的主要上下文(Contexts)
Nginx 配置文件有几个主要的上下文,指令只能在特定的上下文中有效:
-
main
(或 Global) 上下文: 这是配置文件的最顶层,影响所有其他上下文。例如,设置 Nginx 工作进程数、用户和组等。
“`nginx
user www-data; # 工作进程的用户和组
worker_processes auto; # 工作进程数量,auto 表示自动检测
error_log /var/log/nginx/error.log warn; # 错误日志路径和级别
pid /var/run/nginx.pid; # PID 文件路径events {
# … events block directives
}http {
# … http block directives
}
* **`events` 上下文:** 配置影响网络连接处理的全局属性,如每个工作进程的最大连接数、连接处理方法等。
nginx
events {
worker_connections 1024; # 每个工作进程的最大连接数
# multi_accept on; # 是否一次接受多个连接
# use epoll; # 使用哪个事件模型 (Linux 上 epoll 是默认且推荐的)
}
* **`http` 上下文:** 这是配置 HTTP 服务器的主要上下文,包含所有 HTTP 相关的配置,如 MIME 类型、日志格式、TCP优化设置以及定义一个或多个 `server` 块。
nginx
http {
include 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_nopush #tcp_nodelay on; # 启用 tcp_nodelay keepalive_timeout 65; # keep-alive 超时时间 gzip on; # 启用 gzip 压缩 # Include configuration files for virtual hosts include /etc/nginx/conf.d/*.conf; # or typically include from sites-enabled include /etc/nginx/sites-enabled/*; # Define one or more server blocks here or in included files server { # ... server block directives } server { # ... another server block }
}
* **`server` 上下文:** 定义一个虚拟主机。基于监听的端口 (`listen`) 和服务器名称 (`server_name`) 来区分不同的虚拟主机。每个 `server` 块可以看作是一个独立的网站配置。
nginx
server {
listen 80; # 监听 80 端口
server_name example.com www.example.com; # 绑定的域名# ... location blocks and other directives specific to this server
}
* **`location` 上下文:** 定义如何处理特定 URL 路径的请求。嵌套在 `server` 块中。这是 Nginx 进行请求路由和处理的核心。
nginx
server {
listen 80;
server_name example.com;location / { # ... directives for requests to / } location /images/ { # ... directives for requests to /images/ } location ~ \.php$ { # ... directives for requests ending in .php }
}
``
upstream` 上下文用于配置后端服务器组(负载均衡时使用),以及其他模块特定的上下文。
* 还有
第四章:配置 Nginx 服务静态文件
为网站提供静态文件是 Nginx 最基本也是最常用的功能之一。
假设你的网站文件(HTML, CSS, JS, 图片等)存放在 /var/www/mywebsite/
目录下。你可以创建一个新的配置文件,例如 /etc/nginx/sites-available/mywebsite.conf
,内容如下:
“`nginx
/etc/nginx/sites-available/mywebsite.conf
server {
listen 80; # 监听 HTTP 默认端口 80
# 定义服务器名称,根据你的域名修改
# 可以使用多个域名,用空格分隔
server_name mywebsite.com www.mywebsite.com;
# 定义网站根目录
# 当请求到达且没有匹配到更具体的 location 时,Nginx 会在这个目录下查找文件
root /var/www/mywebsite;
# 定义默认首页文件
# 当请求的是一个目录(如 / 或 /docs/)时,Nginx 会按顺序查找这些文件
index index.html index.htm;
# location 块定义如何处理特定的 URL 路径
location / {
# try_files 会按顺序尝试查找文件
# $uri 表示当前请求的 URI,例如 /index.html
# $uri/ 表示当前请求的 URI 作为一个目录,尝试查找 index 文件
# =404 表示如果前两者都没找到,则返回 404 错误
try_files $uri $uri/ =404;
}
# 可以根据需要添加其他 location 块,例如处理特定类型的资源
# location /images/ {
# # 这里可以添加图片相关的配置,例如过期时间等
# }
# 定义访问日志文件
access_log /var/log/nginx/mywebsite_access.log;
# 定义错误日志文件
error_log /var/log/nginx/mywebsite_error.log warn;
}
“`
创建这个文件后,你需要将其链接到 sites-enabled
目录来启用它:
bash
sudo ln -s /etc/nginx/sites-available/mywebsite.conf /etc/nginx/sites-enabled/
为了避免冲突,通常需要删除或禁用 Nginx 默认的配置文件:
bash
sudo rm /etc/nginx/sites-enabled/default
在应用新的配置之前,务必测试配置文件的语法是否正确:
bash
sudo nginx -t
如果输出显示 syntax is ok
和 test is successful
,说明配置文件没有语法错误。
最后,重新加载 Nginx 服务以应用新的配置:
bash
sudo systemctl reload nginx
现在,当你访问 mywebsite.com
(如果已配置 DNS 指向你的服务器) 或服务器 IP 地址时,Nginx 就会从 /var/www/mywebsite/
目录提供文件。
第五章:理解 server
块与虚拟主机
server
块是 Nginx 中定义虚拟主机的单元。通过监听不同的 IP 地址、端口或根据 server_name
来区分不同的 server
块,从而实现在同一台服务器上托管多个网站或应用。
listen
指令: 指定server
块监听的 IP 地址和端口。listen 80;
监听所有可用 IP 的 80 端口。listen 192.168.1.10:80;
监听特定 IP 的 80 端口。listen 443 ssl;
监听 443 端口,并启用 SSL。
server_name
指令: 指定这个server
块要响应的域名。server_name example.com www.example.com;
响应example.com
和www.example.com
的请求。server_name *.example.com;
使用通配符,响应所有以.example.com
结尾的子域名请求。server_name .example.com;
同时响应example.com
和所有子域名请求(注意前面的点)。server_name _;
通常用作默认的server
块(当没有其他server_name
匹配时)。在一个listen
端口下,如果没有指定哪个server
是默认的,则第一个定义的server
块将成为默认块。
选择 server
块的顺序: 当一个请求到达时,Nginx 会按照以下顺序查找最匹配的 server
块:
1. 根据 IP 和端口找到匹配的 server
块集合。
2. 在集合中,优先匹配使用精确 server_name
的块。
3. 然后匹配使用前缀通配符 (*.example.com
) 的块,选择最长的匹配。
4. 接着匹配使用后缀通配符 (mail.*
) 的块,选择最长的匹配。
5. 最后匹配使用正则表达式的 server_name
的块,按照在配置文件中出现的顺序选择第一个匹配的。
6. 如果都没有匹配,则使用该 IP 和端口对应的默认 server
块。
通过合理配置 listen
和 server_name
,你可以灵活地管理多个网站。
第六章:理解 location
块
location
块是 Nginx 中最强大和最复杂的配置单元之一,它定义了如何根据请求的 URI (Uniform Resource Identifier) 来处理请求。location
块嵌套在 server
块内部。
location
指令的基本语法:
nginx
location [modifier] uri {
...
}
uri
: 要匹配的 URI。modifier
: 控制 Nginx 如何解释uri
并进行匹配。常见的修饰符有:- (无修饰符): 前缀匹配。查找以指定
uri
开头的请求路径。这是最常见的匹配方式。
nginx
location /images/ {
# 匹配所有以 /images/ 开头的请求
} =
: 精确匹配。只有当请求的 URI 完全等于指定的uri
时才匹配。如果找到精确匹配,则立即停止搜索,使用这个location
块。
nginx
location = /login {
# 只匹配 /login 这个 URI
}~
: 正则表达式匹配(区分大小写)。
nginx
location ~ \.php$ {
# 匹配所有以 .php 结尾的请求
}~*
: 正则表达式匹配(不区分大小写)。
nginx
location ~* \.(jpg|jpeg|png|gif)$ {
# 匹配所有以 .jpg, .jpeg, .png, .gif 结尾的请求,不区分大小写
}^~
: 前缀匹配,但如果匹配成功,则停止搜索其他更长的或正则表达式的location
。这比普通的前缀匹配优先级高。
nginx
location ^~ /static/ {
# 如果请求路径以 /static/ 开头,就使用这个块,不再继续匹配正则表达式 location
}
- (无修饰符): 前缀匹配。查找以指定
location
块的匹配顺序(复杂但重要):
- 精确匹配 (
=
): 首先尝试所有精确匹配。如果找到一个匹配项,立即使用它并停止处理。 - 前缀匹配 (
^~
): 扫描所有以^~
开头的前缀匹配。选择匹配度最高(最长路径)的一个。如果找到,使用它并停止处理。 - 普通前缀匹配 (无修饰符): 扫描所有普通前缀匹配。选择匹配度最高(最长路径)的一个,但暂时不使用它,而是记住它。
- 正则表达式匹配 (
~
和~*
): 按照它们在配置文件中出现的顺序扫描所有正则表达式匹配。一旦找到第一个匹配项,就使用它并停止处理。 - 使用最长的前缀匹配: 如果步骤 4 没有找到任何匹配项,则使用步骤 3 中记住的最长的前缀匹配。
理解这个顺序对于正确配置 Nginx 的路由至关重要。通常,你会有一个处理根路径 /
的前缀匹配,以及一些用于处理特定类型文件或路径的更具体的 location
块。
try_files
指令:
try_files
是 location
块中非常有用的指令,用于在指定路径下按顺序查找文件或目录,如果找到则发送给客户端;如果都没找到,则执行最后一个参数指定的动作(通常是返回错误码或内部重定向到另一个 location)。
“`nginx
location / {
# 尝试查找请求的 URI 对应的文件,例如请求 /about.html 则查找 /var/www/html/about.html
# 如果没找到,尝试查找 URI 对应的目录下的 index 文件,例如请求 /blog/ 尝试查找 /var/www/html/blog/index.html
# 如果都没找到,内部重定向到 /index.php?uri=$uri&$args (这个 /index.php 需要由另一个 location 块处理,通常是 FastCGI)
try_files $uri $uri/ /index.php?$uri&$args;
}
location /static/ {
# 尝试查找文件,如果没找到,返回 404 错误
try_files $uri =404;
}
“`
第七章:常用指令详解
除了前面提到的 listen
, server_name
, root
, index
, location
, try_files
之外,还有一些非常常用的指令:
alias path;
: 在location
块中使用。它不是在root
基础上查找文件,而是将匹配到的 URI 部分替换为path
,然后查找文件。
nginx
location /static/ {
alias /path/to/your/static/files/;
# 当请求 /static/style.css 时,Nginx 会去 /path/to/your/static/files/style.css 查找
}
注意:alias
通常用于location
块以斜杠/
结尾的情况,且alias
的路径也应该以斜杠/
结尾,以避免一些潜在的问题。普通的前缀匹配 (location /some/
) 通常更推荐使用root
。error_page code ... [=response]
: 定义当出现指定错误码时显示的页面。
“`nginx
server {
# …
error_page 404 /404.html; # 404 错误时显示 /404.html 页面
error_page 500 502 503 504 /50x.html; # 5xx 错误时显示 /50x.html 页面location = /404.html { root /usr/share/nginx/html; # 指定错误页面的根目录 internal; # internal 指令很重要,它表示这个 location 只能由 Nginx 内部重定向访问,防止外部直接访问错误页面文件 } location = /50x.html { root /usr/share/nginx/html; internal; }
}
* **`rewrite regex replacement [flag];`**: 使用正则表达式重写 URL。功能强大但可能比较复杂,且在某些简单场景下可以用 `try_files` 或 `return` 替代,后者性能通常更好。
nginx
server {
# …
location /old-path/ {
rewrite ^/old-path/(.*)$ /new-path/$1 permanent; # 将 /old-path/… 重写为 /new-path/… 并返回 301 永久重定向
}
}
`flag` 常用的有 `last` (在当前 server 或 location 中继续查找匹配的 location 进行处理) 和 `permanent` (返回 301 永久重定向)。
nginx
* **`return code [text];`**: 直接返回指定的 HTTP 状态码和可选的响应体。比 `rewrite` 更简单高效,常用于重定向或返回错误。
server {
# …
location /deprecated-path {
return 301 /new-path; # 将 /deprecated-path 永久重定向到 /new-path
}location /forbidden { return 403 "Access Denied!"; # 返回 403 Forbidden 错误 }
}
* **`proxy_pass url;`**: 在反向代理时使用,将请求转发到指定的后端服务器或 upstream 组。
nginx
location /api/ {
proxy_pass http://localhost:8080; # 将 /api/ 开头的请求转发到本地 8080 端口
}
* **`add_header name value [always];`**: 添加自定义 HTTP 响应头。
nginx
location / {
add_header X-Frame-Options “DENY”; # 防止点击劫持
add_header Content-Security-Policy “default-src ‘self'”; # 基本 CSP 设置
}
“`
第八章:管理 Nginx 服务器
学会如何启动、停止、重新加载和测试 Nginx 是日常维护的基础。
- 启动 Nginx:
bash
sudo systemctl start nginx - 停止 Nginx:
bash
sudo systemctl stop nginx - 重启 Nginx: (停止然后启动,连接会中断)
bash
sudo systemctl restart nginx - 重新加载配置: (平滑重启,加载新配置但不中断现有连接,推荐在修改配置后使用)
bash
sudo systemctl reload nginx - 检查 Nginx 服务状态:
bash
sudo systemctl status nginx - 测试配置文件语法: (强烈推荐在 reload 前执行)
bash
sudo nginx -t - 查看 Nginx 版本信息:
bash
nginx -v
# 或更详细的信息
nginx -V
第九章:Nginx 作为反向代理
反向代理是 Nginx 最强大的功能之一。作为反向代理,Nginx 接收来自客户端的请求,然后将请求转发给后端的应用服务器(例如 Node.js、Python、Java 应用),并将后端服务器的响应返回给客户端。
为什么使用反向代理?
- 安全性: 隐藏后端真实服务器的 IP 地址和端口。
- 负载均衡: 将流量分发到多个后端服务器(下一章会讲)。
- SSL 终止: 在 Nginx 层面处理 SSL 加密,减轻后端服务器负担。
- 静态文件服务优化: Nginx 高效地处理静态文件,后端应用只处理动态请求。
- 缓存: 缓存后端响应,提高速度。
- 压缩: 对响应进行 gzip 压缩。
- 集中日志和监控: 在 Nginx 层面统一处理日志。
配置示例:
假设你的 Node.js 应用运行在本地的 3000 端口。你想让 Nginx 在 80 端口监听请求,并将所有请求转发到 3000 端口。
创建一个新的配置文件,例如 /etc/nginx/sites-available/mywebapp.conf
:
“`nginx
/etc/nginx/sites-available/mywebapp.conf
server {
listen 80;
server_name mywebapp.com www.mywebapp.com; # 你的域名
location / {
# 将所有请求转发到本地 3000 端口
proxy_pass http://localhost:3000;
# 转发一些重要的请求头,确保后端应用能获取客户端真实信息
# X-Forwarded-For 记录客户端 IP 链
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Real-IP 记录客户端真实 IP
proxy_set_header X-Real-IP $remote_addr;
# Host 转发原始请求的 Host 头
proxy_set_header Host $host;
# X-Forwarded-Proto 转发客户端使用的协议 (http 或 https)
proxy_set_header X-Forwarded-Proto $scheme;
# 开启 WebSocket 支持 (如果你的应用需要)
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
}
# 可以为静态文件单独配置 location,让 Nginx 直接提供
# location /static/ {
# root /path/to/your/webapp/static; # 假设静态文件在应用目录下的 static 子目录
# expires 30d; # 设置静态文件缓存过期时间
# }
}
“`
启用配置,测试并重新加载 Nginx:
“`bash
sudo ln -s /etc/nginx/sites-available/mywebapp.conf /etc/nginx/sites-enabled/
如果之前有 default 配置,记得删除
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
“`
现在,当用户访问 mywebapp.com
时,Nginx 会接收请求并将其转发给运行在 3000 端口的 Node.js 应用。
第十章:Nginx 作为负载均衡器
当你的应用流量增大或需要高可用性时,通常会部署多个后端服务器实例。Nginx 可以作为负载均衡器,将传入的请求分发到这些后端服务器组。
配置示例:
假设你有两个后端应用服务器,分别运行在 192.168.1.100:8000 和 192.168.1.101:8000。
“`nginx
在 http 块中定义一个 upstream 块
http {
# … 其他 http 配置
# 定义一个名为 backend_servers 的 upstream 组
upstream backend_servers {
# 负载均衡算法,默认是轮询 (round-robin)
# weight=N: 设置权重,权重越高分到的请求越多
server 192.168.1.100:8000 weight=3;
server 192.168.1.101:8000 weight=1;
# 其他算法:
# ip_hash; # 根据客户端 IP 的 hash 值分配,确保同一客户端总是请求同一服务器
# least_conn; # 将请求发送给当前连接数最少的服务器
# random; # 随机选择服务器
# ... 还有一些更高级的算法和模块
}
server {
listen 80;
server_name myapp.com; # 你的应用域名
location / {
# 将请求转发给 upstream 组
proxy_pass http://backend_servers;
# 转发必要的请求头
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# ... 其他 proxy 配置
}
}
}
“`
将上述 server
块配置到 sites-available
中,创建软链接到 sites-enabled
,测试并重新加载 Nginx。现在 Nginx 就会根据配置的负载均衡算法将请求分发到这两台后端服务器上。
第十一章:配置 SSL/TLS (HTTPS)
为网站启用 HTTPS 可以加密客户端和服务器之间的通信,增强安全性,并且是许多现代 Web 功能(如 HTTP/2)的要求。
配置 HTTPS 需要一个 SSL 证书和私钥。你可以从认证机构购买证书(如 Comodo, DigiCert),也可以使用免费的 Let’s Encrypt 证书,或者在测试环境中生成自签名证书。这里我们演示使用一个假设已有的证书文件。
假设你的 SSL 证书文件是 /etc/nginx/ssl/myapp.crt
,私钥文件是 /etc/nginx/ssl/myapp.key
。
“`nginx
server {
listen 80;
server_name myapp.com www.myapp.com;
# 将 HTTP 请求重定向到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2; # 监听 443 端口,启用 SSL 和 HTTP/2
server_name myapp.com www.myapp.com;
# 指定 SSL 证书和私钥文件路径
ssl_certificate /etc/nginx/ssl/myapp.crt;
ssl_certificate_key /etc/nginx/ssl/myapp.key;
# 推荐的 SSL 设置 (增强安全性)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3; # 只允许安全的 TLS 版本
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS';
ssl_prefer_server_ciphers on;
# OCSP Stapling (可选,提高性能和隐私)
# ssl_stapling on;
# ssl_stapling_verify on;
# resolver 8.8.8.8 8.8.4.4 valid=300s; # Google DNS
# resolver_timeout 5s;
# Strict-Transport-Security 头 (可选,增强安全性,让浏览器强制使用 HTTPS)
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
# 这里是你的反向代理或静态文件服务配置
proxy_pass http://localhost:3000; # 示例:转发给后端应用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https; # 重要:告知后端是 HTTPS 连接
# ... 其他 location 配置
}
}
“`
请将 ssl_certificate
和 ssl_certificate_key
的路径替换为你自己的证书文件路径。然后启用配置,测试并重新加载 Nginx。
第十二章:日志记录
Nginx 记录两种主要的日志:访问日志 (Access Log) 和错误日志 (Error Log)。日志对于监控服务器状态、排查问题和分析流量非常重要。
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
: 定义访问日志的路径和格式。通常在http
,server
,location
块中使用。path
: 日志文件路径。format
: 使用log_format
指令预定义的格式名称(如前面http
块示例中的main
)。off
: 关闭访问日志。
error_log path level;
: 定义错误日志的路径和级别。可以在main
,http
,server
,location
块中使用。path
: 日志文件路径。level
: 错误级别,从低到高依次为debug
,info
,notice
,warn
,error
,crit
,alert
,emerg
。只会记录指定级别及更高级别的错误。生产环境通常设置为warn
或error
。
log_format name string ...;
: 在http
块中定义自定义的日志格式。
默认情况下,访问日志通常在 /var/log/nginx/access.log
,错误日志在 /var/log/nginx/error.log
。
示例(在 http
块中定义格式并在 server
块中使用):
“`nginx
http {
# …
log_format my_custom_format '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'Request Time: $request_time'; # 添加请求处理时间
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com_access.log my_custom_format; # 使用自定义格式
error_log /var/log/nginx/example.com_error.log error; # 只记录 error 级别及以上的错误
# ... location blocks
}
}
“`
第十三章:入门后的进阶方向
本教程涵盖了 Nginx 的基础知识和最常见的应用场景。要更深入地掌握 Nginx,你可以继续学习:
- 更高级的负载均衡算法和配置
- Nginx 缓存(Proxy Cache)的配置和优化
- 使用 Nginx 进行 Gzip 或 Brotli 压缩
- 限制请求速率和连接数
- 基本的安全加固,如防止 DDoS 攻击、限制 IP 访问等
- Nginx 变量的使用
- 编写复杂的
rewrite
规则 - 使用 Nginx 处理 FastCGI (如 PHP)、uWSGI (如 Python) 等协议与后端应用通信
- Lua 模块或其他第三方模块
- Nginx Plus (商业版) 的更多功能
掌握 Nginx 的最佳方法是实践。尝试在虚拟机或云服务器上搭建环境,修改配置文件,观察 Nginx 的行为,并查阅官方文档。
结论
Nginx 是一款功能强大、性能卓越的 Web 服务器软件。通过本教程的学习,你应该对 Nginx 的基本概念、安装、配置结构、服务静态文件、虚拟主机、Location 匹配、常用指令、反向代理、负载均衡、SSL 配置以及日志记录有了初步的了解。
从处理简单的静态网站到作为复杂分布式系统的入口,Nginx 都能发挥关键作用。掌握 Nginx 不仅能帮助你更好地部署和管理 Web 应用,也能让你对 Web 服务器的工作原理有更深刻的认识。
继续探索,不断实践,你将能充分发挥 Nginx 的强大能力,为你的网站和应用提供高性能和高可靠性的服务。祝你学习顺利!