一、关于 Nginx 反向代理、配置及负载均衡算法的回答
1. 先明确:Nginx 反向代理的核心理解
反向代理是 Nginx 的核心功能之一,本质是 客户端不直接访问后端业务服务器,而是通过 Nginx 作为中间代理层转发请求------Nginx 接收客户端请求后,根据配置将请求分发到后端的一台或多台服务器,再将后端响应结果返回给客户端。
核心作用:
- 隐藏后端服务器地址,提升安全性(客户端仅能看到 Nginx 地址);
- 实现负载均衡(将请求分摊到多台后端,避免单点压力);
- 动静分离(静态资源由 Nginx 直接返回,动态请求转发给后端);
- SSL 卸载(Nginx 处理 HTTPS 握手、证书解密,减轻后端压力);
- 缓存静态资源、请求过滤(如拦截非法请求)等。
2. Nginx 服务器配置(以「反向代理+负载均衡」为例)
Nginx 配置核心是 nginx.conf 主配置文件,结构分为「全局块→events 块→http 块→server 块→location 块」,以下是完整的实用配置示例(重点讲反向代理+负载均衡):
第一步:安装 Nginx 后,找到配置文件(默认路径)
- Linux:
/etc/nginx/nginx.conf(主配置)、/etc/nginx/conf.d/(子配置目录,推荐拆分配置到这里) - Windows:
nginx安装目录/conf/nginx.conf
第二步:核心配置示例(实现反向代理+负载均衡)
nginx
# 1. 全局块:配置全局参数(如 worker 进程数、日志路径)
worker_processes auto; # 自动匹配 CPU 核心数(推荐)
error_log /var/log/nginx/error.log warn; # 错误日志路径
pid /var/run/nginx.pid; # Nginx 进程 PID 文件
# 2. events 块:配置 Nginx 与客户端的网络连接
events {
worker_connections 1024; # 每个 worker 进程最大并发连接数
use epoll; # 启用 epoll 事件模型(Linux 下高性能,默认可能已开启)
}
# 3. http 块:核心配置(反向代理、负载均衡、缓存等都在这里)
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; # 启用高效文件传输模式
tcp_nopush on; # 配合 sendfile 提升性能
tcp_nodelay on;
keepalive_timeout 65; # 长连接超时时间(秒)
# ========== 负载均衡配置:定义后端服务器集群 ==========
upstream backend_servers { # backend_servers 是集群名称(自定义)
# 后端服务器 1:IP+端口,weight 是权重(默认 1,权重越高,分配到的请求越多)
server 192.168.1.100:8080 weight=5;
# 后端服务器 2:backup 表示「备用机」,只有其他服务器宕机才会启用
server 192.168.1.101:8080 backup;
# 后端服务器 3:down 表示「手动下线」,不参与负载均衡
server 192.168.1.102:8080 down;
# 可选:配置健康检查相关参数(被动健康检查,后面会讲)
max_fails 3; # 最大失败次数(默认 1)
fail_timeout 30s; # 失败后标记为不可用的时间(默认 10s)
}
# ========== server 块:虚拟主机配置(接收客户端请求) ==========
server {
listen 80; # Nginx 监听端口(默认 80,HTTP 协议)
server_name www.mydomain.com; # 绑定的域名(可填 IP,如 192.168.1.200)
# ========== location 块:请求匹配规则(核心反向代理配置) ==========
location / { # 匹配所有以 / 开头的请求(即所有请求)
proxy_pass http://backend_servers; # 转发请求到上面定义的后端集群
# 反向代理核心参数(必须配置,否则后端可能无法获取客户端真实信息)
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)
# 代理超时配置(避免后端无响应导致 Nginx 一直等待)
proxy_connect_timeout 5s; # 连接后端超时时间
proxy_read_timeout 10s; # 读取后端响应超时时间
}
# 动静分离示例:静态资源(js/css/img)由 Nginx 直接返回,不转发给后端
location ~* \.(js|css|png|jpg|gif|ico)$ {
root /usr/share/nginx/html; # 静态资源存放目录
expires 30d; # 静态资源缓存 30 天(提升性能)
autoindex off; # 禁止列出目录
}
}
}
第三步:配置生效命令(面试必提,证明实际操作过)
bash
nginx -t # 检查配置文件语法是否正确(关键,避免配置错误导致启动失败)
nginx -s reload # 平滑重启 Nginx,加载新配置(不中断现有连接)
# 其他常用命令
nginx # 启动 Nginx
nginx -s stop # 强制停止
nginx -s quit # 优雅停止(处理完现有请求再停止)
3. Nginx 负载均衡的核心算法(分「内置常用」和「扩展特殊」)
负载均衡算法的作用是:决定 Nginx 如何将客户端请求分配到后端集群的不同服务器,核心算法如下:
| 算法类型 | 原理 | 适用场景 |
|---|---|---|
| 1. 轮询(默认) | 按后端服务器顺序依次分配请求(1→2→3→1→2→3...),权重默认都是 1 | 后端所有服务器性能一致、配置相同的场景 |
| 2. 权重轮询 | 给后端服务器设置 weight 权重(如 weight=5),权重越高,分配到的请求越多 |
后端服务器性能不均(如有的服务器 CPU 更强) |
| 3. IP 哈希 | 对客户端 IP 进行哈希计算,固定将同一 IP 的请求分配到同一台后端服务器 | 需要「会话保持」的场景(如用户登录后会话不丢失) |
| 4. 最少连接数 | 优先将请求分配给当前活跃连接数最少的后端服务器 | 请求分布不均匀(有的请求耗时久,导致连接数多) |
| 5. URL 哈希 | 对请求 URL 进行哈希计算,固定 URL 分配到同一台后端(需第三方模块 ngx_http_upstream_hash_module) |
静态资源缓存、API 接口幂等性要求高的场景 |
| 6. Fair 算法 | 按后端服务器的响应时间分配(响应越快,分配越多,需第三方模块 ngx_http_upstream_fair_module) |
对响应速度敏感的场景(如实时接口) |
| 7. 一致性哈希 | 解决普通哈希的「雪崩问题」(后端服务器上下线时,仅影响少量请求分配,需第三方模块) | 后端集群频繁扩缩容的场景 |
面试重点:优先掌握前 4 种内置算法(轮询、权重轮询、IP 哈希、最少连接数),能说清原理和适用场景即可,扩展算法可简单带一句(证明知识面)。
二、后端服务器宕机,Nginx 如何检查(健康检查机制)
Nginx 对后端服务器的健康检查分「被动健康检查」(默认开启)和「主动健康检查」(需配置/第三方模块),核心是「检测后端是否可用,不可用时自动剔除,恢复后自动加回」。
1. 被动健康检查(默认启用,无需额外模块)
核心逻辑:Nginx 转发请求给后端时,通过「请求结果」判断后端状态 ,如果多次请求失败,就将该后端标记为「不可用」,并在 fail_timeout 时间内不再分配请求,超时后会重试探测。
关键配置参数(在 upstream 块中配置)
nginx
upstream backend_servers {
server 192.168.1.100:8080;
server 192.168.1.101:8080;
max_fails 3; # 允许的最大失败次数(默认 1 次)
fail_timeout 30s; # 失败后标记为不可用的时间(默认 10s)
}
什么情况判定为「请求失败」?
- 后端服务器无响应(连接超时、读超时,对应
proxy_connect_timeoutproxy_read_timeout); - 后端返回 5xx 状态码(如 502 坏网关、503 服务不可用、504 网关超时);
- 后端主动拒绝连接(如端口未监听、服务宕机)。
恢复机制:
fail_timeout 时间到后,Nginx 会尝试将请求再次分配给该后端,如果请求成功,就将其重新标记为「可用」,加入负载均衡池。
2. 主动健康检查(需配置,更精准)
被动健康检查的缺点是「只有有请求时才会检测」,如果后端宕机后长时间无请求,第一次请求会命中宕机节点(导致失败)。主动健康检查是 Nginx 定期主动发送探测请求到后端,提前判断状态,避免客户端请求失败。
配置方式(分两种场景):
-
场景 1:使用 Nginx Plus(商业版,内置主动健康检查):
nginxupstream backend_servers { server 192.168.1.100:8080; server 192.168.1.101:8080; # 主动健康检查配置 health_check interval=5s timeout=2s fails=2 passes=2; health_check_uri /health; # 探测后端的健康检查接口(如 /health 返回 200 表示正常) } -
场景 2:开源版 Nginx(需编译安装
ngx_http_upstream_check_module第三方模块):nginxupstream backend_servers { server 192.168.1.100:8080; server 192.168.1.101:8080; # 主动探测配置:每隔 3 秒探测一次,超时 1 秒,2 次失败标记不可用,2 次成功恢复 check interval=3000 rise=2 fall=2 timeout=1000; check_type tcp; # 探测类型(tcp:检查端口是否通;http:检查接口返回码) check_http_send "GET /health HTTP/1.1\r\nHost: localhost\r\n\r\n"; # HTTP 探测请求 check_http_expect_alive http_2xx; # 期望返回 2xx 状态码表示健康 }
3. 面试总结(简洁版)
后端宕机后,Nginx 主要通过「被动健康检查」(默认)和「主动健康检查」(可选)实现状态检测:
- 被动检查:转发请求时,若后端多次超时或返回 5xx,Nginx 会暂时剔除该节点,超时后重试恢复;
- 主动检查:定期发送探测请求(如访问 /health 接口),提前标记不可用节点,避免客户端请求失败;
- 核心目标:保证请求始终分配到「可用的后端服务器」,提升系统可用性。
面试回答技巧
- 先总述核心逻辑,再分点展开(比如讲反向代理先定义+作用,再讲配置);
- 配置部分一定要带「关键指令」和「生效命令」(证明实际操作过,不是纯背理论);
- 负载均衡算法重点讲常用的 4 种,说清「原理+适用场景」(面试官更关注实际应用);
- 健康检查分「被动+主动」,讲清默认行为和优化方案(体现思考深度)。