一、正向代理与反向代理
什么是代理?
首先,让我们了解一下“代理”这个概念。代理就像是一个中间人,它代表着另一方执行任务。在计算机网络中,代理服务器就充当着客户端(你的电脑)和目标服务器(例如网站)之间的“中间人”。
1. 正向代理
定义:
正向代理(Forward Proxy)是一种代理服务器,客户端通过它向外部服务器发送请求。简单来说,它就是你去找一个代理人,所有的请求都由代理人帮你去做。
工作原理:
你(客户端)发送请求给正向代理服务器。
正向代理服务器代替你向目标服务器发送请求。
目标服务器不知道你是谁,只知道请求是通过代理服务器来的。
最后,正向代理服务器把目标服务器的响应内容返回给你。
实际生活中的例子:
假设你住在一个小区,里面有很多小朋友。小朋友们都想看国外的视频,但视频服务被小区的网络封锁了。于是你找到一个外面的“代理人”,让他代表你向外面的视频服务请求视频。你自己不直接和外面的视频服务沟通,而是通过这个代理人。
应用场景:
访问受限制的网站:例如在学校或公司,你的网络访问受到限制,可以通过正向代理访问被封锁的网站。
隐藏真实 IP 地址:例如你不想让别人知道你上网的地点或身份,通过正向代理可以隐藏你的真实信息。
提高匿名性:正向代理还可以提高匿名性,保护你的隐私。
2. 反向代理
定义:
反向代理(Reverse Proxy)是一种代理服务器,客户端的请求首先发送到反向代理服务器,反向代理再将请求转发给内部的目标服务器。和正向代理相反,反向代理隐藏的是后端服务器的真实信息。
工作原理:
你(客户端)向反向代理发送请求。
反向代理决定把请求转发给哪个真实的服务器(后端服务器)。
反向代理把后端服务器的响应返回给你。
实际生活中的例子:
想象你到了一家大型超市,门口有一个接待员。接待员会先了解你需要购买什么,然后带你去相应的货架。你不知道货架的位置,也不知道哪个货架上有你需要的商品。接待员(反向代理)帮你找到商品,并把它交给你。
应用场景:
负载均衡:例如有多台服务器来处理大量的用户请求,反向代理会根据不同的规则把请求分发到不同的服务器,保证负载均衡,提高性能。
提高安全性:反向代理可以隐藏真实服务器的 IP 地址,这样外部的用户就无法直接访问到内部的服务器,增强了安全性。
缓存:反向代理可以缓存常用的请求内容,减少后端服务器的负担,提高响应速度。
正向代理与反向代理的区别
特点 正向代理 反向代理 代理对象 客户端通过代理访问外部服务器。 客户端通过代理访问内部服务器。 目的 主要是帮助客户端访问外部的服务。 主要是帮助服务器管理外部的请求,保护内部服务器。 谁知道代理 目标服务器不知道客户端的真实地址。 客户端不知道后端服务器的真实地址。 常见应用 访问控制、绕过网络限制、匿名访问等。 负载均衡、安全保护、缓存、SSL 加速等。
总结
正向代理:是客户端使用代理服务器访问外部资源,隐藏客户端的信息和请求。
反向代理:是客户端通过代理服务器访问内部资源,隐藏后端服务器的信息,常用于负载均衡和安全防护。
正向代理:就像你委托朋友去商店买东西,商店并不知道你是谁,只知道你的朋友来买。
反向代理:就像你去超市,门口有接待员帮你决定哪个货架上有你需要的商品,超市不直接知道你是什么人。
正向代理: 帮助你绕过限制,访问你想去的地方。
反向代理: 帮助网站管理访问,保证服务更快、更安全。
二、nginx代理配置
Nginx 是一款高性能的 Web 服务器和反向代理服务器,常被用于负载均衡、反向代理、静态文件服务等场景。它的配置简单且功能强大,是目前最受欢迎的反向代理工具之一。
概述及其原理
Nginx 代理的原理:
反向代理:
客户端发出的请求先到达 Nginx 服务器,Nginx 根据配置规则将请求转发到真实的后端服务器(如应用服务器、数据库服务器等)。
客户端通常无法直接访问后端服务器,所有请求和响应都通过 Nginx 代理进行处理。
通过这种方式,Nginx 可以隐藏后端服务器的真实 IP,提供负载均衡、缓存等功能。
正向代理:
虽然 Nginx 的主流用途是反向代理,但它也可以配置为正向代理,用于让客户端访问被限制的资源。
环境搭建
安装 Nginx:
在 Linux 上可以通过包管理器(如yum
或apt
)来安装 Nginx。
CentOS/RHEL 系统:
sudo yum install nginx
Ubuntu/Debian 系统:
sudo apt update sudo apt install nginx
启动 Nginx:
sudo systemctl start nginx
检查 Nginx 是否安装成功:
在浏览器中访问http://localhost
或http://服务器IP
,如果看到 Nginx 的欢迎页面,说明安装成功。设置开机自启:
sudo systemctl enable nginx
基本配置及其语法
Nginx 配置文件通常位于
/etc/nginx/nginx.conf
或/etc/nginx/conf.d/
目录下。配置文件的基本语法包括:
主配置块: 定义 Nginx 运行的基本信息,如工作进程数、日志路径等。
user nginx; # 定义 Nginx 运行的用户 worker_processes 1; # 定义工作进程数 error_log /var/log/nginx/error.log; # 错误日志文件 pid /var/run/nginx.pid; # Nginx 进程 ID 文件
http 块: 包含了与 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; # 访问日志文件 }
server 块: 每个
server
块用于定义一个虚拟主机配置。server { listen 80; # 监听 80 端口 server_name localhost; # 域名 location / { # 根路径配置 root /usr/share/nginx/html; index index.html index.htm; } }
location 块: 用于定义具体 URL 路径的配置。
location /images/ { root /data; # 为 /images 路径提供文件服务,根目录为 /data }
Nginx 反向代理配置
在 Nginx 中配置反向代理非常简单。最基本的配置如下:
server { listen 80; # 监听 80 端口 server_name example.com; # 绑定域名 location / { # location /user/ { 假如是这样就表示 example.com/user/就会反向代理到下面地址 # 这种表示/user开头 proxy_pass http://backend_server; # 将请求转发到 backend_server proxy_set_header 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; # 转发协议信息 } }
这里,Nginx 会把客户端对
example.com
的请求转发到后端的backend_server
上,通常这是一个其他 Web 服务器或应用服务器的地址。Nginx 负载均衡配置
如果你有多个后端服务器,可以配置负载均衡,将请求分发到多个后端服务器上:
http { upstream backend { server backend1.example.com; server backend2.example.com; server backend3.example.com; } server { listen 80; location / { proxy_pass http://backend; # 将请求转发到 upstream 定义的服务器 } } }
这样,Nginx 会将请求均匀地分发到
backend1.example.com
、backend2.example.com
和backend3.example.com
上。
Nginx性能优化配置
下面是一个详细的 Nginx 性能优化配置文件,其中包含了每个配置项的说明和注释。这样你可以方便地理解每一项配置的作用。
# Nginx 性能优化配置文件 # 设定 worker 进程的数量。通常设置为 CPU 核心数,`auto` 会自动设置为 CPU 核心数量。 worker_processes auto; # 自动选择工作进程数为 CPU 核心数 # 配置每个工作进程最大连接数。这个值可以根据服务器的负载和并发情况进行调整。 worker_connections 1024; # 每个工作进程最大连接数 # 使用 epoll 模型(Linux 系统专用),它是事件驱动模型,适用于高并发的场景。 events { use epoll; # 使用 epoll 模型(仅适用于 Linux) worker_connections 1024; # 每个 worker 进程最大支持的连接数 } http { # 启用 Gzip 压缩,减小数据传输量,提高传输速度。 gzip on; # 启用 Gzip 压缩 gzip_comp_level 6; # 设置压缩级别,范围 1-9,9 是最高压缩比,但会消耗更多 CPU gzip_types text/plain text/css application/javascript application/json image/svg+xml; # 启用对这些类型文件的压缩 gzip_vary on; # 允许根据客户端请求的压缩 gzip_min_length 1000; # 文件大小大于 1000 字节才进行压缩 # 配置 TCP 参数优化 tcp_nopush on; # 启用 TCP_NOPUSH,减少网络包的发送数量 tcp_nodelay on; # 启用 Nagle 算法,减少延迟 # 配置 HTTP 连接的保持时间(Keep-Alive) keepalive_timeout 65; # 客户端和服务器之间保持连接的超时时间(秒) # 配置访问日志格式,减少日志记录对性能的影响 access_log /var/log/nginx/access.log main; # 配置默认的访问日志路径 # 配置日志格式(可以选择简化或禁用日志) log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 记录更多细节的日志格式 # 静态文件缓存配置,减少不必要的重复请求 location /images/ { root /var/www/html; # 设置文件根目录 expires 30d; # 缓存静态文件 30 天 add_header Cache-Control "public"; # 启用公共缓存 } # 反向代理缓存配置,缓存请求并减少后端服务器的压力 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off; server { location / { proxy_cache my_cache; # 启用代理缓存 proxy_cache_valid 200 1h; # 200 状态码的响应缓存 1 小时 proxy_cache_use_stale error timeout updating; # 错误或超时时使用过期缓存 proxy_pass http://backend; # 请求转发到后端服务器 } } # 配置限制请求速率,防止恶意流量或 DDoS 攻击 limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s; # 每秒 1 个请求 server { location / { limit_req zone=mylimit burst=5; # 每秒最大 1 个请求,最多允许 5 个请求突发 } } # 配置连接数限制,每个 IP 地址的连接数限制 limit_conn_zone $binary_remote_addr zone=addr:10m; # 限制每个 IP 的连接数 server { location / { limit_conn addr 10; # 每个 IP 最多 10 个并发连接 } } # 配置反向代理负载均衡(轮询方式) upstream backend { server backend1.example.com; # 后端服务器 1 server backend2.example.com; # 后端服务器 2 server backend3.example.com; # 后端服务器 3 } server { location / { proxy_pass http://backend; # 代理请求到负载均衡池 } } # 配置 SSL 加速,优化 TLS 设置 server { listen 443 ssl; # 启用 SSL ssl_certificate /etc/ssl/certs/server.crt; # SSL 证书路径 ssl_certificate_key /etc/ssl/private/server.key; # SSL 密钥路径 # 启用 SSL 会话缓存 ssl_session_cache shared:SSL:10m; # 使用 10MB 的共享会话缓存 ssl_session_timeout 1d; # 设置会话超时时间为 1 天 # 启用更安全的协议 ssl_protocols TLSv1.2 TLSv1.3; # 启用更安全的协议版本 # 配置加密套件 ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...'; # 设置加密套件 ssl_prefer_server_ciphers on; # 优先使用服务器端的加密套件 } }
配置说明:
worker_processes 和 worker_connections:这两个参数决定了 Nginx 能处理的最大连接数。
worker_processes
通常设置为 CPU 核心数,而worker_connections
决定了每个进程能处理的最大连接数。Gzip 压缩:开启 Gzip 压缩可以大大减少客户端和服务器之间传输的文件大小,提高带宽利用率。
TCP 参数:通过
tcp_nopush
和tcp_nodelay
优化 TCP 连接,减少数据包传输的延迟。Keep-Alive:可以减少每次请求时创建连接的开销,允许多个请求复用同一个连接。
缓存:通过缓存静态资源和代理缓存来减少服务器负载,提高响应速度。
请求限制:对过多的请求进行限制,防止恶意攻击(如 DDoS 攻击)。
负载均衡:配置反向代理负载均衡,将请求分发到多个后端服务器上,提高服务器的处理能力。
SSL 配置:优化 SSL/TLS 配置,确保安全和性能之间的平衡。
这些配置有助于提高 Nginx 的性能,减少资源消耗,保证高并发时的稳定性。你可以根据实际需求对这些配置进行调整。
获取真实 IP 地址
当客户端通过 Nginx 访问后端服务器时,Nginx 默认会把自己的 IP 地址作为请求头
X-Forwarded-For
传递给后端服务器。如果你想要获取客户端的真实 IP 地址,需要确保代理设置正确。在
proxy_set_header
配置中,我们已经传递了客户端的真实 IP 地址:proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
后端服务器获取客户端真实 IP 地址:
在后端服务器的日志中,可以通过读取
X-Real-IP
或X-Forwarded-For
请求头来获取客户端的真实 IP 地址。如果你使用的是 PHP,你可以通过以下代码获取真实 IP:
$client_ip = $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'];
如果你使用的是 Nginx 后端日志记录,可以配置日志格式为:
log_format main '$proxy_add_x_forwarded_for - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
这样,
X-Forwarded-For
中会包含客户端的真实 IP。
总结
环境搭建: 使用包管理工具安装 Nginx,启动服务后,确保可以访问
localhost
。基本配置: 配置 Nginx 的监听端口、日志格式、虚拟主机等基本设置。
反向代理配置: 使用
proxy_pass
配置将请求转发到后端服务器。负载均衡: 使用
upstream
块进行负载均衡配置,多个后端服务器的流量均衡分发。获取真实 IP: 配置
proxy_set_header
确保后端服务器获取到真实客户端的 IP 地址。希望这些内容能帮助你理解 Nginx 代理配置的基础!如果有任何疑问,随时告诉我!
三、动静分离部署(反向代理案例)
什么是动静分离部署?
动静分离是一种Web架构优化策略,将静态资源(如HTML、CSS、JavaScript、图片、视频等)和动态资源(如后端API、数据库交互等)分开部署,以提升性能、降低服务器压力并优化用户体验。
- 静态资源:内容固定或变化频率低,适合通过Web服务器(如Nginx)或CDN分发。
- 动态资源:需后端程序(如Java、PHP、Python)处理,运行在应用服务器(如Tomcat、Spring Boot)上。
为什么需要动静分离部署?
动静分离的核心优势在于性能优化和资源高效利用,尤其适合高并发、高流量场景(如电商、社交平台、内容分发网站)。具体好处:
- 提升加载速度:
- 静态资源通过Nginx或CDN分发,响应更快,支持高效缓存,减少用户等待时间。
- 示例:图片、视频可通过CDN从最近节点加载,延迟降低至毫秒级。
- 降低服务器负载:
- 静态请求由Nginx/CDN处理,动态请求交给后端,减轻应用服务器压力。
- 提高并发能力:
- Nginx处理静态资源的吞吐量远超Tomcat(约6倍),适合高并发场景。
- 便于维护与扩展:
- 前后端分离开发更清晰,静态资源可独立更新,动态逻辑由后端维护。
- 成本优化:
- CDN和静态服务器成本较低,适合高流量场景,减少带宽和计算资源消耗。
如何实现动静分离部署?
以下是一个通用的动静分离部署步骤,适用于大多数Web应用场景(如网站、API服务、内容平台)。假设你有一个Web项目,包含前端页面和后端API。
1. 划分静态与动态资源
- 静态资源:HTML、CSS、JavaScript、图片、视频、字体等。
- 示例:将静态文件存储在/var/www/static目录,包含index.html、styles.css、app.js、视频文件等。
- 动态资源:后端API、数据库查询、用户认证等。
- 示例:Spring Boot提供/api/users接口,处理用户数据请求。
2. 部署静态资源
- 使用Nginx作为静态资源服务器:
- 配置Nginx指向静态文件目录,启用缓存。
- 示例Nginx配置文件:
server { listen 80; server_name static.yourdomain.com; root /var/www/static; location / { try_files $uri $uri/ /index.html; # 支持前端路由 expires 30d; # 缓存30天 add_header Cache-Control "public"; } }
- 部署:将静态文件上传至/var/www/static,通过static.yourdomain.com访问。
- 使用CDN加速:
- 将静态资源同步到CDN(如阿里云CDN、AWS CloudFront)。
- 配置:设置CDN源站为Nginx服务器,启用全球节点分发。
- 优点:用户从最近的CDN节点获取资源,降低延迟。
3. 部署动态资源
- 使用应用服务器(如Tomcat、Spring Boot、Node.js)处理动态请求。
- 示例:Spring Boot应用运行在10.0.0.7:8080,提供API接口。
- 配置Nginx反向代理,将动态请求转发到后端:
nginx
server { listen 80; server_name api.yourdomain.com; location /api/ { proxy_pass http://10.0.0.7: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; } }
4. 配置动静分离规则
- 在Nginx中通过路径或文件类型区分静态和动态请求:
nginx
server { listen 80; server_name yourdomain.com; # 静态资源 location ~ .*\.(html|css|js|jpg|png|gif|mp4|woff2)$ { root /var/www/static; expires 30d; add_header Cache-Control "public"; } # 动态资源 location /api/ { proxy_pass http://10.0.0.7:8080; } # 默认路由到前端 location / { root /var/www/static; try_files $uri $uri/ /index.html; } }
- 说明:.html、.css等文件由Nginx直接返回,/api/请求转发到后端。
5. 优化与安全
- 缓存优化:
- 为静态资源设置expires和ETag,减少重复请求。
- 示例:视频文件设置expires 1y(缓存1年),动态数据禁用缓存。
- 安全配置:
- 配置HTTPS(使用Let’s Encrypt免费证书)。
- 限制后端服务器直接访问,仅允许Nginx反向代理。
- 示例:
nginx
server { listen 80; server_name api.yourdomain.com; return 301 https://$host$request_uri; # 重定向到HTTPS }
- 跨域处理:(nginx配置)
location /api/ { add_header Access-Control-Allow-Origin *; proxy_pass http://10.0.0.7:8080; }
- 监控与扩展:
- 使用工具(如Prometheus、Grafana)监控Nginx和后端性能。
- 高流量场景下,引入负载均衡(如Nginx Upstream)或容器化(如Docker、Kubernetes)。
适用场景与注意事项
- 适用场景:
- 高流量网站:如电商、社交媒体、视频平台,需快速加载静态资源。
- 前后端分离项目:前端用React/Vue,静态资源托管在Nginx,后端API用Spring Boot/Node.js。
- 内容分发:如视频、图片分发,CDN+动静分离可大幅提升用户体验。
- 注意事项:
- 文件路径管理:确保静态资源路径规范,避免404错误。
- CDN成本:评估流量需求,选择合适的CDN服务商(如阿里云、Cloudflare)。
- 后端性能:动态资源服务器需优化数据库查询,避免成为瓶颈。
- 版本控制:静态资源更新后,添加版本号(如app.v2.js)避免缓存问题。
四、负载均衡
概述
负载均衡(Load Balancing)是一种技术,用于将网络流量或计算任务分发到多个服务器或资源,以提高系统的性能、可靠性和可扩展性。它通过合理分配负载,防止单一服务器过载,确保高可用性和快速响应。负载均衡广泛应用于 Web 应用、数据库、微服务架构等场景。
核心目标:
- 高可用性:通过冗余服务器避免单点故障。
- 性能优化:均衡分发请求,提升响应速度。
- 可扩展性:支持动态添加或移除服务器。
- 容错性:当某服务器故障时,自动将请求重定向到其他可用服务器。
负载均衡可以分为:
- 硬件负载均衡:如 F5、Citrix NetScaler,使用专用硬件设备。
- 软件负载均衡:如 Nginx、HAProxy、LVS,或云服务(如 AWS ELB、阿里云 SLB)。
配置
负载均衡的配置通常包括以下步骤:
- 选择负载均衡器:
- 硬件:配置专用设备(如 F5)。
- 软件:安装 Nginx、HAProxy 或使用云服务(如 AWS Elastic Load Balancer)。
- 定义后端服务器:
- 配置后端服务器池(Backend Pool),列出所有可用的服务器地址和端口。
-
示例(Nginx 配置http下):
upstream backend { # 表示配置负载均衡(upstream) 后面的backend表示的是这个负载均衡的名字,自定义 server 192.168.1.101:80; # server 真实服务器地址 参数 weight=数字表示权重 #其他参数 # max_fails=10:默认次数为1,超过次数标记为该服务器失败 # fail_timeout=10s:在服务器被定义失败后,距离下一次检查时间间隔,默认10s # backup:热备份,仅当所有激活服务器都失败后,请求才会被转发到标记为backup的服务器 # down:标记服务器永不可用,用于维护或者测试,批核ip_hash使用时,服务器不可以被标记为down server 192.168.1.102:80; server 192.168.1.103:80; }
- 选择负载均衡算法:
- 根据需求选择合适的算法(如轮询、最少连接等,详见下文)。
- 健康检查:
- 配置健康检查机制,定期检测后端服务器的可用性。
- 示例(Nginx):
server 192.168.1.101:80 max_fails=3 fail_timeout=30s;
-
代理设置:
- 配置负载均衡器作为客户端与后端服务器之间的代理。
- 示例(Nginx):
server { listen 80; location / { proxy_pass http://backend; # 这里就是通过nginx反向代理完成对负载均衡的调度 # 反向代理其实就是服务员 # 正向代理:你 找朋友 在10个厨师中找指定的人做饭 厨师不知道你是谁 # 反向代理:你 想让厨师做饭,告诉服务员,服务员指定厨师做饭 你不知道谁哪个厨师 } }
- 其他配置:
- SSL/TLS 加密:为负载均衡器配置 HTTPS。
- 会话保持(Session Persistence):确保同一用户的请求始终路由到同一服务器。
- 日志和监控:记录请求分发情况,监控性能和故障。
算法
负载均衡算法决定了如何将请求分配到后端服务器。常见算法包括:
- 轮询(Round Robin):
- 按顺序将请求依次分配到每台服务器。
- 适用场景:后端服务器性能相近,负载均匀。
- 缺点:不考虑服务器的实际负载,可能导致性能较差的服务器过载。
- 加权轮询(Weighted Round Robin):
- 为每台服务器分配权重,性能高的服务器获得更多请求。
- 示例(Nginx):
upstream backend { server 192.168.1.101:80 weight=3; server 192.168.1.102:80 weight=1; }
- 最少连接(Least Connections):
- 将请求分配到当前连接数最少的服务器。
- 适用场景:处理时间较长的请求(如文件上传)。
upstream backend { least_conn; server 192.168.1.101:80; server 192.168.1.102:80; }
- 加权最少连接(Weighted Least Connections):
- 在最少连接基础上考虑服务器权重。
- IP 哈希(IP Hash):
- 根据客户端 IP 地址的哈希值分配请求,确保同一客户端的请求始终路由到同一服务器。
- 适用场景:需要会话保持的场景。
upstream backend { ip_hash; server 192.168.1.101:80; server 192.168.1.102:80; }
- 随机(Random):
- 随机分配请求,简单高效。
- 适用场景:服务器性能均匀,负载较低。
- 一致性哈希(Consistent Hashing):
- 使用哈希环分配请求,减少服务器增减时的重新分配。
- 适用场景:分布式系统(如缓存集群)。
upstream backend { hash $request_url;#根据客户端请求uri为计算哈希值的key server 192.168.1.101:80; server 192.168.1.102:80; #这里还可以和weight混合使用 }
- URL 哈希:
- 根据请求的 URL 进行哈希分配,适合内容缓存场景。
案例
Web 应用负载均衡(Nginx 示例):
- 场景:一个高流量的电商网站,部署了三台 Web 服务器。
- 配置:
http { upstream web_servers { least_conn; # 使用最少连接算法 server 192.168.1.101:80; server 192.168.1.102:80; server 192.168.1.103:80; } server { listen 80; location / { proxy_pass http://web_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
五、基于nginx的负载均衡
Nginx 是一个高性能的 Web 服务器和反向代理服务器,广泛用于实现负载均衡。它支持四层(传输层)和七层(应用层)负载均衡,适用于多种场景。以下从 OSI 模型出发,详细介绍 Nginx 的七层和四层负载均衡,并提供四层负载均衡的实验示例。
osi模型
OSI(开放系统互连)模型将网络通信分为七层,从低到高依次为:
- 物理层:处理物理连接和数据传输(如电缆、网卡)。
- 数据链路层:负责局域网内的数据传输(如以太网、MAC 地址)。
- 网络层:处理 IP 地址和路由(如 IP 协议)。
- 传输层:提供端到端的可靠数据传输(如 TCP、UDP)。
- 会话层:管理会话和连接的建立、维护、终止。
- 表示层:处理数据的格式化和加密(如 SSL/TLS)。
- 应用层:直接为用户提供服务(如 HTTP、FTP)。
Nginx 的负载均衡主要工作在:
- 四层(传输层):基于 TCP/UDP 协议,处理数据包转发。
- 七层(应用层):基于 HTTP、WebSocket 等协议,处理请求内容。
七层负载
七层负载均衡(应用层负载均衡)基于 HTTP/HTTPS 等协议,Nginx 通过分析请求的内容(如 URL、头部、Cookie)进行分发。
特点:
- 灵活性高:可以根据请求的 URL、域名、Cookie 等进行路由。
- 会话保持:支持基于 Cookie 或 IP 的会话持久性。
- 内容感知:可以根据请求内容(如文件类型、路径)选择后端服务器。
- 局限性:需要解析应用层协议,性能略低于四层负载均衡。
配置示例(HTTP 负载均衡):
http {
upstream backend {
server 192.168.1.101:80 weight=2; # 加权轮询
server 192.168.1.102:80;
server 192.168.1.103:80 backup; # 备用服务器
}
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;
}
# 根据 URL 路由到特定服务器
location /api {
proxy_pass http://192.168.1.104:8080;
}
}
}
适用场景:
- Web 应用分发(如静态资源到一组服务器,API 请求到另一组)。
- 需要会话保持的场景。
- 基于内容的路由(如按 URL 或域名分发)。
四层负载
四层负载均衡(传输层负载均衡)基于 TCP/UDP 协议,Nginx 通过 stream 模块处理数据包转发,不解析应用层内容。
特点:
- 高性能:无需解析 HTTP 协议,处理速度快。
- 协议无关:支持 TCP/UDP 协议,适用于非 HTTP 服务(如 MySQL、Redis)。
- 局限性:无法基于应用层内容(如 URL)进行路由。
- 要求:需要 Nginx 1.9.0+ 版本,并启用 stream 模块。
配置示例(TCP 负载均衡):
stream {
upstream tcp_backend {
server 192.168.1.101:3306; # MySQL 服务器
server 192.168.1.102:3306;
}
server {
listen 3306;
proxy_pass tcp_backend;
proxy_timeout 10s;
proxy_connect_timeout 5s;
}
}
适用场景:
- 非 HTTP 协议的负载均衡(如数据库、邮件服务器)。
- 高性能要求的场景。
- 需要简单转发的场景。
四层负载实验
以下是一个基于 Nginx 的四层负载均衡实验,模拟对 MySQL 服务器的负载均衡。
实验环境:
- Nginx 服务器:IP 为 192.168.1.100,安装 Nginx(包含 stream 模块)。
- 后端服务器:
- Server1:192.168.1.101:3306(MySQL 实例)。
- Server2:192.168.1.102:3306(MySQL 实例)。
- 客户端:任意机器,用于连接 Nginx 的 3306 端口。
- 操作系统:Ubuntu 20.04(或其他支持 Nginx 的系统)。
实验步骤:
安装 Nginx 并启用 stream 模块:
安装 Nginx:
bash
sudo apt update
sudo apt install nginx
确认 stream 模块已启用(默认 Nginx 可能不包含 stream,需要安装 nginx-full 或编译时启用):
bash
nginx -V 2>&1 | grep stream
如果没有 stream,需重新编译 Nginx 或安装支持的版本。
配置 Nginx 四层负载均衡:
编辑 Nginx 配置文件(通常在 /etc/nginx/nginx.conf 或 /etc/nginx/conf.d/ 下创建新文件,如 mysql_lb.conf):
nginx(stream和http模块同一等级)
stream {
upstream mysql_backend {
least_conn; # 使用最少连接算法
server 192.168.1.101:3306 max_fails=3 fail_timeout=30s;
server 192.168.1.102:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 10s;
proxy_connect_timeout 5s;
}
}
验证配置文件:
bash
sudo nginx -t
重启 Nginx:
bash
sudo systemctl restart nginx
配置后端 MySQL 服务器:
确保 192.168.1.101 和 192.168.1.102 上的 MySQL 服务运行在 3306 端口。
配置 MySQL 允许远程连接:
sql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
编辑 MySQL 配置文件(/etc/mysql/my.cnf),设置 bind-address = 0.0.0.0。
测试负载均衡:
从客户端使用 MySQL 客户端连接 Nginx:
bash
mysql -h 192.168.1.100 -P 3306 -u root -p
执行多次连接,观察请求是否分发到不同后端服务器。
验证健康检查:关闭一台 MySQL 服务器(例如 192.168.1.101),观察 Nginx 是否自动将请求路由到 192.168.1.102。
监控与日志:
启用 Nginx 访问日志(在 stream 块中添加):
nginx
stream {
access_log /var/log/nginx/stream_access.log;
...
}
查看日志,确认请求分发情况:
bash
tail -f /var/log/nginx/stream_access.log