1. 简介
Nginx 是一个高性能的 HTTP 和反向代理服务器,是普遍使用的七层(即应用层)负载均衡器,目前也支持四层负载。同时也是一个 IMAP/POP3/SMTP 邮件代理服务器。它最初是由俄罗斯程序员 Igor Sysoev 开发的,现在由 Nginx, Inc. 维护。
Nginx 以其轻量级和高并发处理能力著称,广泛用于处理高流量的 Web 服务。
以下是 Nginx 的一些主要功能:
- 反向代理:Nginx 可以作为反向代理服务器,将客户端的请求转发到后端服务器,起到负载均衡的作用。
- 负载均衡:Nginx 能够将流量分配到多个后端服务器,从而实现负载均衡,帮助提高应用的可用性和响应速度。
- 静态资源服务:Nginx 非常擅长处理静态内容(如 HTML、CSS、JS 文件),能够高效地将这些文件从服务器发送到客户端。
- HTTPS 支持:Nginx 支持 SSL/TLS,加密客户端和服务器之间的通信,确保数据传输的安全性。
- 缓存:Nginx 提供了缓存功能,可以缓存响应结果以减少服务器负载和响应时间。
2. 安装
2.1 二进制安装
源码包下载地址: http://nginx.org/en/download.html
安装可选的功能: http://nginx.org/en/docs/configure.html
# 下载源码包后传输到机器上
tar -xf nginx-1.26.2.tar.gz
useradd -M -s /sbin/nologin nginx
# 配置网路 YUM 源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
yum -y install gcc gcc-c++ openssl openssl-devel zlib zlib-devel pcre pcre-devel
# 安装依赖 C语言编译器、加密软件包、压缩软件包、Perl语言正则表达式库
cd /root/nginx-1.26.2
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-stream
# 执行configure命令,生成执行计划Makefile文件。其中,命令的参数含义是--prefix:指定安装路径,--user和—group指定服务管理的所有者和所属组、--http_stub_status_module是添加统计模块、--with-http_ssl_module是添加加密模块、--with-http_v2_module是添加http2协议、--with-stream是采用字节流进行传输
make && make install
ln -s /usr/local/nginx/sbin/nginx /sbin/nginx
#配置防火墙规则(所有人都可以访问)
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -L INPUT -v -n
nginx
lsof -i:80
lsof -u nginx
编译之前要规划好使用哪些模块,比如SSL模块、HTTP2.0模块。编译完成后就不能更改了,只有重新安装。
3. 配置文件详解
Nginx 配置文件主要分为全局设置、事件块(events)和 HTTP 模块三部分构成。
HTTP 模块中可以有多个 server 模块,每个 server 相当于一个 虚拟主机。
3.1 HTTP
# 全局设置
user nginx; # 指定 Nginx 运行的用户和用户组
worker_processes auto; # 指定工作进程的数量,可以设为 auto 自动适应 CPU 核心数
pid /var/run/nginx.pid; # 指定 Nginx 主进程的 PID 文件路径
error_log /var/log/nginx/error.log warn; # 定义错误日志文件和日志级别
# 事件块
events {
worker_connections 1024; # 每个工作进程允许的最大连接数
use epoll; # 采用的事件驱动模型,Linux 系统中常用 epoll 提升性能
}
# HTTP 服务块
http {
include /etc/nginx/mime.types; # 定义 MIME 类型的配置文件
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; # 定义访问日志路径和使用的日志格式
sendfile on; # 是否开启 sendfile,用于优化静态文件传输
tcp_nopush on; # 减少网络包的发送次数,提高性能
tcp_nodelay on; # 禁止小包延迟传输,加快 HTTP 响应
keepalive_timeout 65; # 客户端保持连接的超时时间
gzip on; # 开启 gzip 压缩,减少网络传输的数据量
# 定义上游服务器的负载均衡
upstream backend {
# 服务器列表,可以添加多个
server backend1.example.com weight=3; # 定义第一台上游服务器,权重为3
server backend2.example.com; # 第二台上游服务器,默认权重为1
# 可选配置:轮询负载均衡策略
# 其他可选策略包括 least_conn、ip_hash 等
# ip_hash; # 基于客户端IP地址的负载均衡
# least_conn; # 最少连接数优先
}
# 服务器块
server {
listen 80; # 监听端口 80,处理 HTTP 请求
server_name www.example.com; # 绑定域名 www.example.com
# 默认主页配置
location / {
proxy_pass http://backend; # 将请求代理到上游服务器 backend
proxy_set_header Host $host; # 设置代理请求中的 Host 头
proxy_set_header X-Real-IP $remote_addr; # 将客户端 IP 传递给上游服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递客户端的链路
}
# 静态文件处理
location /static/ {
root /var/www/html; # 指定静态文件的根目录
expires 30d; # 缓存静态文件30天
}
# 错误页面处理
error_page 500 502 503 504 /50x.html; # 定义50x错误的处理页面
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
# 加密模块
3.2 HTTPS&&h2
# 全局设置
user nginx;
worker_processes auto;
# 事件块
events {
worker_connections 1024;
}
# HTTP 模块,包含 HTTPS 和 HTTP/2 配置
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;
sendfile on;
keepalive_timeout 65;
gzip on;
# 第一个 server 块:处理 HTTP 请求并重定向到 HTTPS
server {
listen 80;
server_name www.example.com;
# 将 HTTP 请求强制重定向到 HTTPS
return 301 https://$host$request_uri;
}
# 第二个 server 块:处理 HTTPS 和 HTTP/2 的请求
server {
listen 443 ssl http2; # 启用 HTTP/2 和 SSL
server_name www.example.com;
# 配置 SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3; # 启用 TLS 1.2 和 1.3
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS 安全设置
add_header Strict-Transport-Security "max-age=31536000" always;
# 默认主页配置
location / {
root /var/www/html;
index index.html;
}
# 错误页面处理
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
}
}
4. 运维管理
4.1 指定运行用户
将 Nginx 配置为使用非特权用户(例如 www 或 nginx ),以提高系统安全性。运行 Nginx 进程的用户应具有最小的权限,减少潜在的安全风险。
use nginx;
4.2 重新加载配置和平滑重启
在对 Nginx 的配置文件进行修改后,先对配置文件进行准确性测试,可以帮助你在重新加载或重启 Nginx 之前发现配置中的语法错误或其他问题。
nginx -t
在更新配置文件后,不需要停止服务,可以平滑地重新加载配置,实现优雅重启,确保在更改配置或更新服务时不会中断现有用户的连接。
nginx -s reload
4.3 启用和管理缓存
-
静态文件缓存: 配置浏览器缓存静态资源,如 CSS、JS、图片等:
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 7d; add_header Cache-Control "public"; } -
反向代理缓存: 可以缓存来自后端服务器的响应,以减轻后端服务器的压力:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m inactive=60m; location / { proxy_cache my_cache; proxy_pass http://backend; ... }
4.4 监控和日志管理
使用 access_log 和 error_log 记录访问和错误信息,并分析日志以发现潜在问题。
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
4.5 优化连接处理
使用 worker_processes 和 worker_connections: 根据服务器的 CPU 数量和流量负载调整 Nginx 的工作进程和连接数设置。
worker_processes auto;
worker_connections 1024;
启用 keepalive: 减少重复的 TCP 连接建立和关闭开销,提高性能。
keepalive_timeout 65;
keepalive_requests 100;
keepalive_timeout 65
- 含义: 设置客户端与服务器之间的空闲连接在关闭之前可以保持活动状态的时间(以秒为单位)。这里设置的 65 秒意味着,如果客户端与服务器之间的连接在 65 秒内没有新的数据传输,Nginx 将关闭该连接。
- 用途: 长连接的保持时间,有助于减少客户端和服务器之间建立新的 TCP 连接的频率,从而降低开销,尤其是在处理高频请求时。
- 默认值: 通常默认值是 65 秒,具体时间可以根据服务器性能和需求调整。
keepalive_requests 100
- 含义: 设置在同一个长连接上可以处理的最大请求数量。这里设置的 100 意味着在关闭长连接之前,Nginx 最多会在这个连接上处理 100 个 HTTP 请求。达到 100 个请求后,Nginx 会主动关闭连接。
- 用途: 限制在一个长连接上处理的请求数量,以防止单个连接长期占用资源,导致服务器资源枯竭。适当的设置可以提高服务器的性能和响应速度。
- 默认值: 默认值通常为 100,具体可以根据负载情况和服务器资源调整。
4.6 启用 GZIP 压缩
可以启用 Gzip 压缩,以减少传输数据的大小,提高页面加载速度。
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
4.7 使用反向代理和负载均衡
使用 Nginx 作为反向代理,将请求分发到后端服务器:
# Nginx 配置文件示例
# 文件路径: /etc/nginx/nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
# 负载均衡的后端服务器列表
upstream backend {
# 服务器列表,可以添加多个
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
# 可选配置:轮询负载均衡策略
# 其他可选策略包括 least_conn、ip_hash 等
# ip_hash; # 基于客户端IP地址的负载均衡
# least_conn; # 最少连接数优先
}
# 反向代理服务器配置
server {
listen 80; # 监听端口
server_name example.com; # 域名
location / {
proxy_pass http://backend; # 将请求代理到上游服务器
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;
}
# 可选配置:静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1d;
add_header Cache-Control "public, no-transform";
}
# 可选配置:自定义错误页面
error_page 500 502 503 504 /50x.html;
ot /usr/share/nginx/html;
}
}
}
4.8 使用 SSL/TLS 和 HTTP/2
配置 SSL/TLS 以确保数据传输安全,并启用 HTTP/2 提高多路复用效率。
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
...
}
4.9 nginx 常用命令
nginx -s stop:停止 Nginx。
nginx -s quit:优雅停止 Nginx。
nginx -s reload:重新加载配置文件。
nginx -t:测试配置文件是否有语法错误。
nginx -v:查看 Nginx 版本。
nginx -V:查看详细版本信息和编译参数。
4.10 源码包安装的被 systemctl 纳管
要将二进制安装的 Nginx 纳入 systemctl 管理,需要创建一个系统服务单元文件。
-
创建服务文件:在
/etc/systemd/system/目录下创建一个新的服务文件,比如nginx.service。vi /etc/systemd/system/nginx.service -
编辑服务文件:将以下内容添加到文件中,确保
ExecStart指令指向你的 Nginx 二进制文件路径。[Unit] Description=A high-performance web server and reverse proxy server After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s stop PIDFile=/usr/local/nginx/logs/nginx.pid [Install] WantedBy=multi-user.target根据你的实际路径调整
ExecStart和PIDFile的位置。 -
重新加载
systemd配置:systemctl daemon-reload -
启动 Nginx 服务:
systemctl start nginx -
设置开机启动:
sudo systemctl enable nginx -
检查服务状态:
sudo systemctl status nginx
注意事项:用什么命令启动的,就用什么命令关闭。systemctl 和 nginx 两套不要混用。
4.11 Nginx 做四层代理
准备工作
使用四层代理需要stream模块。
# 安装组件
yum -y install nginx nginx-mod-stream.x86_64
# 验证 Nginx 是否已经支持 stream 模块
nginx -V 2>&1 | grep -- 'http_stub_status_module'
若输出中包含 --with-stream,则表示 Nginx 已经支持该模块修改配置文件
七层代理和四层代理的配置区别
# 四层
stream {
upstream backend_servers {
server backend1.example.com:3306;
server backend2.example.com:3306;
}
server {
listen 3306;
proxy_pass backend_servers;
}
}
# 七层
http {
upstream backend_servers {
server backend1.example.com:80;
server backend2.example.com:80;
}
server {
listen 80;
location / {
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
5. 常见故障
5.1 403 Forbidden (禁止访问)
- 含义: 服务器理解客户端的请求,但拒绝执行该请求。
- 常见原因:
- 客户端没有访问某个资源的权限,例如尝试访问需要授权的页面或文件。
- 服务器设置了访问控制规则,禁止了客户端的访问。
- 示例: 试图访问一个没有权限查看的文件或目录时,可能会遇到 403 错误。
5.2 404 Not Found (未找到)
- 含义: 服务器找不到客户端请求的资源。
- 常见原因:
- 请求的 URL 对应的资源不存在或已被删除。
- 客户端输入了错误的 URL。
- 示例: 访问一个不存在的页面时,通常会返回 404 错误。
5.3 503 Service Unavailable (服务不可用)
- 含义: 服务器暂时无法处理请求,通常是因为服务器超载或正在进行维护。
- 常见原因:
- 服务器资源不足(如 CPU、内存、带宽等)。
- 服务器正在维护或重启。
- 后端服务不可用或失败。
- 示例: 当服务器因流量过大或技术维护而无法处理请求时,会返回 503 错误。
5.4 504 Gateway Timeout (网关超时)
-
含义: 服务器在作为网关或代理时未能及时从上游服务器获得响应。
-
常见原因:
- 服务器需要从上游服务器获取数据,但上游服务器响应过慢或没有响应。
- 网络连接问题导致无法及时与上游服务器通信。
-
示例: 当一个反向代理服务器尝试与后端服务器通信但超时时,会返回 504 错误。
-
5. 故障日志
5.1 Nginx 作为代理时和后端服务器不通
故障现象

日志解析
2024/09/05 06:42:38 [error] 1299#0: *22 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.17.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://192.168.17.191:80/", host: "192.168.17.190"这个错误消息是Nginx在代理请求时遇到的问题。
2024/09/05 06:42:38 [error] 1299#0:
这部分表示错误发生的日期和时间(2024年9月5日6点42分38秒),以及Nginx进程的ID号(1299)。\*22 connect() failed (111: Connection refused) while connecting to upstream,
这是错误的核心部分。Nginx尝试连接到上游服务器(即代理目标)时,连接失败,系统返回的错误代码是“111”,意思是“连接被拒绝”。client: 192.168.17.1,
这表示发出请求的客户端IP地址是192.168.17.1。server: localhost,
表示Nginx正在处理一个以localhost为主机名的虚拟服务器的请求。request: "GET / HTTP/1.1",
这是客户端发出的请求,具体是一个HTTP GET请求,目标是根路径/,使用的是HTTP/1.1协议。upstream: "http://192.168.17.191:80/",
表示Nginx正在将请求代理到上游服务器,该服务器的地址是192.168.17.191:80(即IP地址为192.168.17.191,端口号为80的服务器)。host: "192.168.17.190"
这是请求中使用的主机名或IP地址。
Nginx在尝试连接到上游服务器(192.168.17.191:80)时,连接被拒绝。这可能是因为上游服务器没有运行、监听端口错误、或防火墙配置等原因导致无法建立连接。客户端IP地址为192.168.17.1,向Nginx发送了一个请求,而Nginx试图将这个请求代理到上游服务器,但失败了。
附录 HTTP 状态码
以下是常见的 HTTP 状态码及其对应的原因,按类别列出:
| 状态码 | 描述 | 说明 |
|---|---|---|
| 1xx | 信息性状态码 | 表示请求已被接受,继续处理。 |
| 100 | Continue | 继续请求。客户端应继续发送请求的其余部分。 |
| 101 | Switching Protocols | 服务器正在切换协议。 |
| 2xx | 成功状态码 | 表示请求已成功处理。 |
| 200 | OK | 请求成功。 |
| 201 | Created | 请求成功并创建了资源。 |
| 202 | Accepted | 请求已接受,但尚未处理。 |
| 203 | Non-Authoritative Information | 请求成功,但返回的信息可能不是原始服务器的。 |
| 204 | No Content | 请求成功,但没有返回内容。 |
| 205 | Reset Content | 请求成功,要求客户端重置视图。 |
| 206 | Partial Content | 服务器成功处理了部分 GET 请求。 |
| 3xx | 重定向状态码 | 表示需要进一步的操作才能完成请求。 |
| 300 | Multiple Choices | 请求的资源有多种选择。 |
| 301 | Moved Permanently | 请求的资源已被永久移动到新的 URL。 |
| 302 | Found | 请求的资源临时移动到新的 URL。 |
| 303 | See Other | 请求应通过另一个 URL 来获取响应。 |
| 304 | Not Modified | 资源未被修改。客户端可以使用缓存的版本。 |
| 305 | Use Proxy | 请求的资源必须通过指定的代理访问。 |
| 307 | Temporary Redirect | 请求的资源临时移动到新的 URL,客户端应继续使用原有请求方法。 |
| 308 | Permanent Redirect | 请求的资源永久移动到新的 URL,客户端应使用新的 URL。 |
| 4xx | 客户端错误状态码 | 表示请求可能有错误,导致服务器无法处理。 |
| 400 | Bad Request | 请求无效,服务器无法理解。 |
| 401 | Unauthorized | 请求需要身份验证。 |
| 402 | Payment Required | 需要付款,但目前尚不使用此状态码。 |
| 403 | Forbidden | 服务器理解请求,但拒绝处理。 |
| 404 | Not Found | 请求的资源未找到。 |
| 405 | Method Not Allowed | 请求的方法不被允许。 |
| 406 | Not Acceptable | 请求的资源不可接受。 |
| 407 | Proxy Authentication Required | 代理需要身份验证。 |
| 408 | Request Timeout | 请求超时,服务器未在规定时间内收到请求。 |
| 409 | Conflict | 请求与当前资源状态冲突。 |
| 410 | Gone | 请求的资源已被永久删除。 |
| 411 | Length Required | 请求必须包含 Content-Length 头部字段。 |
| 412 | Precondition Failed | 请求中的前提条件失败。 |
| 413 | Payload Too Large | 请求的负载太大,服务器无法处理。 |
| 414 | URI Too Long | 请求的 URI 过长,服务器无法处理。 |
| 415 | Unsupported Media Type | 请求的媒体类型不被支持。 |
| 416 | Range Not Satisfiable | 请求的范围无法满足。 |
| 417 | Expectation Failed | 服务器无法满足 Expect 请求头中的期望值。 |
| 5xx | 服务器错误状态码 | 表示服务器遇到错误或无法完成请求。 |
| 500 | Internal Server Error | 服务器遇到内部错误,无法完成请求。 |
| 501 | Not Implemented | 服务器不支持请求中所需的功能。 |
| 502 | Bad Gateway | 作为网关或代理的服务器收到无效响应。 |
| 503 | Service Unavailable | 服务器当前无法处理请求(过载或维护)。 |
| 504 | Gateway Timeout | 作为网关或代理的服务器在规定时间内未收到来自上游服务器的响应。 |
| 505 | HTTP Version Not Supported | 服务器不支持请求中所用的 HTTP 协议版本。 |
评论区