一、nginx是什么?
Nginx是一款高性能、开源的 Web 服务器、反向代理服务器;它由俄罗斯程序员 Igor Sysoev 开发,最初是为了解决 C10K 问题(即单机同时处理 1 万个连接)而设计的。凭借其轻量级、高并发和模块化的特点,在现代网络架构中扮演着至关重要的角色。
简单来说,nginx就像大厦保安:
1、外部所有请求必须先经过他;再转发到你的后端服务(反向代理)
2、处理静态文件、压缩数据、防恶意攻击(安全保镖)
3、同时处理上千万个并发连接,比Tomcat单线程强百倍(高并发处理)
比如:你写了个校验接口,不想暴露IP怕被攻击,那就让nginx当中间人,外部只知道nginx的地址,真实服务器ip不再向外界暴露。
二、nginx的核心功能
2.1 反向代理&负载均衡
核心配置思路
实现目标主要依赖nginx的upstream模块和proxy_pass指令
1、定义服务器组:在upstream块中列出您的n台后端服务器。
2、设置负载均衡策略:选择一种算法来决定请求如何被分配。
3、配置健康检查:让nginx能自动检测并暂时隔离宕机的服务器。
4、设置反向代理:将客户和请求转发至定义好的服务器组。
5、隐藏真实ip:通过正确设置HTTP请求头,确保后端服务器能获取到真实的客户端信息。
关键配置示例与说明
以下是一个综合性的配置示例,可以根据注释理解各部分作用,并调整到您的nginx配置文件中(配置文件路径:/nginx/conf/nginx.conf)
http {
# 定义名为 backend_servers 的后端服务器组
upstream backend_servers {
# 配置负载均衡策略,例如最少连接数,适合负载不均的场景
least_conn;
# 列出您的3台后端服务器,可以配置权重(weight)
server 192.168.1.101:8080 weight=3; # 服务器1,性能较好,权重高
server 192.168.1.102:8080 weight=2; # 服务器2
server 192.168.1.103:8080 weight=1; # 服务器3,性能稍弱,权重低
# 配置健康检查参数:30秒内失败3次则判定该服务器不可用,30秒后再尝试连接
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.103:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name your-domain.com; # 您的域名或服务器IP
location / {
# 将请求反向代理到后端服务器组
proxy_pass http://backend_servers;
# 以下设置用于传递真实客户端信息,隐藏后端服务器IP
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; # 传递代理链IP
proxy_set_header X-Forwarded-Proto $scheme; # 传递原始协议(http/https)
# 可选的超时设置,根据后端服务处理能力调整,防止长时间等待
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}
}
各配置荐的作用
| 配置项 | 说明 |
|---|---|
upstream | 定义一个后端服务器池,Nginx据此进行负载均衡36。 |
least_conn | 使用最少连接数策略,将新请求发给当前连接数最少的服务器,有助于改善负载不均的情况8。您也可以使用默认的 轮询或其他如 ip_hash(需保持会话时)36。 |
weight | 设置服务器权重。权重越高,分配的请求越多。适合服务器性能不一致的场景38。 |
max_fails与 fail_timeout | 健康检查的关键参数。max_fails指在 fail_timeout时间内连续失败多少次后标记服务器不可用;在不可用期满后,Nginx会再次尝试发送请求38。这实现了”自动剔除挂掉的节点”。 |
proxy_pass | 将请求反向代理到上游服务器组,是请求转发的核心指令13。 |
proxy_set_header | 修改转发给后端服务器的请求头。这确保了后端服务能获取到真实的客户端IP(通过 X-Real-IP或 X-Forwarded-For)和域名,从而”隐藏真实IP”12。 |
关键点:
后端服务器ip全隐藏在nginx里,外部只能访问nginx的公网ip
遇到高并发时,流量均分到n台服务器,不用担心接口被压崩的情况
2.2 静态资源处理 & 动静分离
核心思路:动静分离
动静分离是指将动态请求(如API接口)和静态资源(如图片、CSS、JS)分开处理。让Nginx这个高性能的Web服务器直接接管静态文件,可以带来几个立竿见影的好处:
1、大幅提升加载速度:Nginx处理静态文件的效率远高于应用服务器(如Tomcat),能更快地将资源返回给浏览器。
2、显著减轻后端压力:后端服务器(如Spring Boot应用)可以专注于处理业务逻辑,不再被大量静态资源请求干扰。
3、便于缓存优化:可以为不同类型的静态资源设置更精细、更长久的缓存策略,进一步提升用户体验
配置实战:让nginx直接服务静态文件
实现动静分离的关键在于Nginx配置文件中的 location指令块。您需要根据静态资源在服务器上的实际存放路径,选择合适的配置方式。下面的表格对比了两种最常用的配置方法:
您遇到的这个问题,其实是典型的动静分离需求。下面我为您梳理一下核心思路和具体配置方法。
核心思路:动静分离
动静分离是指将动态请求(如API接口)和静态资源(如图片、CSS、JS)分开处理。让Nginx这个高性能的Web服务器直接接管静态文件,可以带来几个立竿见影的好处:
- •大幅提升加载速度:Nginx处理静态文件的效率远高于应用服务器(如Tomcat),能更快地将资源返回给浏览器5。
- •显著减轻后端压力:后端服务器(如Spring Boot应用)可以专注于处理业务逻辑,不再被大量静态资源请求干扰3。
- •便于缓存优化:可以为不同类型的静态资源设置更精细、更长久的缓存策略,进一步提升用户体验1。
配置实战:让Nginx直接服务静态文件
实现动静分离的关键在于Nginx配置文件中的 location指令块。您需要根据静态资源在服务器上的实际存放路径,选择合适的配置方式。下面的表格对比了两种最常用的配置方法:
| 配置方法 | 适用场景 | 配置示例 | 关键说明 |
|---|---|---|---|
root指令 | 静态文件位于Nginx的某个子目录下。 | location /static/ {root /var/www/myapp;expires 30d;} | 当访问 /static/css/style.css时,Nginx会查找 /var/www/myapp/static/css/style.css 文件1。 |
alias指令 | 静态文件存放在一个独立的、路径不匹配URL的目录。 | location /static/ {alias /data/static/assets/;expires 30d;} | 当访问 /static/css/style.css时,Nginx会直接查找 /data/static/assets/css/style.css 文件2。 |
完整的配置示例
可以将以下配置片段添加到Nginx的server块中(配置文件路径:/nginx/conf/nginx.conf)。该示例涵盖了常见的静态文件类型,并设置了浏览器缓存。
server {
listen 80;
server_name your-domain.com;
# 动态请求(API等)仍然转发给后端应用服务器
location / {
proxy_pass http://backend_server; # 替换为您的后端服务器地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 处理图片、图标等静态资源
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
# 使用 root 或 alias 指定您的图片实际存放路径
root /path/to/your/static/files;
# 设置浏览器缓存时间为30天
expires 30d;
add_header Cache-Control "public, no-transform";
}
# 处理CSS和JS静态资源
location ~* \.(css|js)$ {
# 使用 root 或 alias 指定您的CSS/JS实际存放路径
root /path/to/your/static/files;
# 设置浏览器缓存时间为30天
expires 30d;
add_header Cache-Control "public";
# 可关闭此位置的访问日志,提升性能
access_log off;
}
}
优化、验证
1、设置缓存:配置中的expires和Cache-Control头非常重要,这俩货会告诉浏览器将文件缓存起来,后续访问时,直接从本地读取,极大地加快了访问速度。
2、启动Gzip压缩:在nginx的http块中开启Gzip,可进一步减小传输文件的大小。
gzip on;
gzip_types text/css application/javascript;
3、检查配置并重载:配置完成后,务必执行下面的命令
sudo nginx -t # 检查配置文件语法是否正确
sudo nginx -s reload # 重载配置,使更改生效
4、验证效果:打开浏览器开发者工具(F12),访问一个静态文件,在Network标签页查看响应头。如果看到Cache-Control、expires等字段,并且响应来自disk cache(磁盘缓存),说明配置成功。
注意:
1、路径匹配:root和alias指令对路径的处理有重要区别,如果路径有误,会导致404错误
2、文件权限:确保nginx进程用户(通常是www-data或nginx)有权限读取静态文件所在的目录
3、资源更新:如果更新了静态文件,由于设置了长缓存,用户浏览器可能不会立即获取到新的文件。常见的解决方案是在文件名中加入版本号或哈希值(如:style.v2.css),以确保用户能获取到最新版本。
关键点:
静态文件直接由nginx返回,速度比后端处理快;
浏览器缓存+压缩,用户二次访问秒加载,前端小姐姐再也不用甩锅了!
2.3 限流防刷 & IP 黑白名单
nginx防护策略一览
| 防护策略 | 主要作用 | 适用场景/特点 |
|---|---|---|
| 限制请求频率 | 控制单个IP在单位时间内的请求数,防止洪水攻击。 | 应对CC攻击、恶意刷接口、爬虫过度抓取。 |
| 限制并发连接数 | 控制单个IP同时建立的连接数量,防止服务器资源被耗尽。 | 应对下载工具多线程抢占资源,或连接耗尽型攻击。 |
| 配置IP黑名单 | 直接拒绝特定IP或IP段的所有访问。 | 封禁已确认的恶意源IP,简单直接。 |
| 设置IP白名单 | 仅允许受信任的IP访问,拒绝其他所有流量。 | 对内部API、管理后台等需高安全性的接口进行访问控制。 |
核心配置详解
1、限制请求频率(基于 limit_req_zone)
此配置使用“令牌桶”算法来平滑处理请求流
http {
# 定义限流规则:在内存中开辟一个10M的共享区one,记录每个IP的访问频率,速率限制为每秒10个请求。
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; [5](@ref)
server {
location /api/ {
# 应用限流规则:突发请求队列容量为20个,且立即处理这些突发请求而不延迟。
limit_req zone=api_limit burst=20 nodelay; [4,5](@ref)
# 当请求被拒绝时,返回429状态码(Too Many Requests)。
limit_req_status 429; [5](@ref)
... # 其他代理配置
}
}
}
2、限制并发连接数(基于limit_conn_zone)
此配置直接限制同一IP的并发连接数
http {
# 定义连接限制区:在内存中开辟一个10M的共享区addr,用于记录每个IP的连接状态。
limit_conn_zone $binary_remote_addr zone=addr:10m; [3,4](@ref)
server {
location /download/ {
# 应用连接限制:每个IP同时最多只能有5个连接。
limit_conn addr 5; [3,5](@ref)
... # 其他配置
}
}
}
3、配置ip黑名单(基于deny指令)
直接拒绝特定ip的访问,配置灵活
http {
# 方法一:在配置文件中直接写(适合IP较少的情况)
server {
location / {
deny 192.168.1.100; # 封禁单个IP
deny 192.168.1.0/24; # 封禁整个C段IP段
allow all; # 允许其他所有IP访问
}
}
# 方法二:使用独立的黑名单文件(推荐,便于管理)
include /etc/nginx/conf.d/ip.black; [6,7](@ref)
}
黑名单文件 ip.black的内容格式为:
deny 10.0.0.1;
deny 203.0.113.50;
注意:
1、白名单豁免:对于监控系统、搜索引擎或可信IP,可以设置白名单使其不受限流规则影响。这通常结合 geo和 map模块实现。
2、动态封禁:可以通过编写Shell脚本分析Nginx的 access.log日志,自动将短时间内访问次数异常的IP加入黑名单文件,然后定时重载Nginx配置,实现动态智能封禁。
3、配置生效:每次修改配置文件后,务必先使用 nginx -t命令测试配置文件语法是否正确,确认无误后执行 nginx -s reload重载配置使其生效。
关键点:
如果遇到恶意ip频繁刷接口,直接返回403;
登录接口限流后,不用担心被cc攻击了。
2.4 HTTPS配置
场景: 用户反馈登录时浏览器提示「不安全」,被产品经理骂哭
配置目标: 启用 HTTPS,让数据加密传输,浏览器显示小绿锁
server {
listen 443 ssl; # 监听443端口(HTTPS)
server_name www.yourdomain.com;
# 证书路径(从CA机构申请的证书和私钥)
ssl_certificate /etc/nginx/ssl/yourdomain.crt;
ssl_certificate_key /etc/nginx/ssl/yourdomain.key;
ssl_protocols TLSv1.2 TLSv1.3; # 启用安全的TLS协议版本
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384; # 加密算法
ssl_prefer_server_ciphers on; # 优先使用服务器端的加密算法
# 重定向HTTP到HTTPS(让用户输入http自动转https)
rewrite ^(.*)$ https://$host$1 permanent;
location / {
proxy_pass http://backend_servers/;
}
}
关键点:
数据加密传输,用户密码不怕被中间人窃取
写在最后:
nginx配置不是一次性的,上线后要根据服务器压力、用户反馈动态调整,比如遇到高并发时 要加大限流阈值,发现恶意ip及时拉黑。
代码可以慢慢写,nginx必须移民如狗;配置写对了,项目运行才能放心!