4.1 代理基础知识
代理分为两种,分别是正向代理和反向代理
正向代理(Forward Proxy) 和 反向代理(Reverse Proxy) 是两种常见的代理服务器,它们用于处理网络通信中的不同方向和用途
正向代理(Forward Proxy)
特点
用途
反向代理(Reverse Proxy)
特点
用途
相同和不同
相同点
不同点
4.2 Nginx 和 LVS
Nginx 和 LVS(Linux Virtual Server) 都是流行的代理和负载均衡解决方案,但它们有一些不同的特点和应用场景
选择使用 Nginx 还是 LVS 取决于具体的应用需求和复杂度。Nginx 更适合作为 Web 服务器和应用层负载均衡器,而 LVS 更适用于传输层负载均衡
相同点
不同点
LVS 不监听端口,不处理请求数据,不参与握手流程,只会在内核层转发数据报文
Nginx 需要在应用层接收请求,根据客户端的请求参数和Nginx中配置的规则,再重新作为客户端向后端服务器发起请求
4.3 实现 http 协议反向代理
4.3.1 相关指令和参数
Nginx 可以基于ngx_http_proxy_module 模块提供 http 协议的反向代理服务,该模块是 Nginx 的默认模块
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
proxy_pass URL; proxy_hide_header field; proxy_pass_header field; proxy_pass_request_body on|off; proxy_pass_request_headers on|off; proxy_connect_timeout time; proxy_read_timeout time; proxy_send_timeout time; proxy_set_body value; proxy_set_header field value; proxy_http_version 1.0|1.1; proxy_ignore_client_abort on|off; proxy_headers_hash_bucket_size size; proxy_headers_hash_max_size size; proxy_next_upstream error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_403|http_404|http_429|non_idempotent| off ...; proxy_cache zone|off; proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size[inactive=time] [max_size=size] [min_free=size] [manager_files=number][manager_sleep=time] [manager_threshold=time] [loader_files=number][loader_sleep=time] [loader_threshold=time] [purger=on|off][purger_files=number] [purger_sleep=time] [purger_threshold=time]; proxy_cache_key string; proxy_cache_valid [code ...] time; proxy_cache_use_stale error|timeout|invalid_header|updating|http_500|http_502|http_503|http_504|http_403|http_404|http_429|off ...; proxy_cache_methods GET|HEAD|POST ...;
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.210; }}[root@ubuntu ~]hello world
[root@ubuntu ~]hello world
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.210:8080; }}
server { listen 8080; root /var/www/html/8080;}[root@ubuntu ~]hello 8080
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://www.node-1.com; }}[root@ubuntu ~]10.0.0.210 www.node-1.com
server { listen 80; root /var/www/html/www.node-1.com; server_name www.node-1.com;}[root@ubuntu ~]
[root@ubuntu ~]node-1
[root@ubuntu ~]10.0.0.206 www.m99-josedu.com
[root@ubuntu ~]10.0.0.210 www.m99-josedu.comserver { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.210; proxy_set_header Host $http_host; }}
server { listen 80; root /var/www/html/www.m99-josedu.com; server_name www.m99-josedu.com;}[root@ubuntu ~]
[root@ubuntu ~]m99
[root@ubuntu ~][root@ubuntu ~]<html><head><title>502 Bad Gateway</title></head><body><center><h1>502 Bad Gateway</h1></center><hr><center>nginx</center></body></html>
[root@ubuntu ~]HTTP/1.1 502 Bad GatewayServer: nginxDate: Sun, 11 Feb 2025 12:41:53 GMTContent-Type: text/html; charset=utf8Content-Length: 150Connection: keep-alive
#如果连接后端服务器超时,会报504
#启动Nginx 服务,并设置防火墙规则,如果是中间服务器的请求就DROP[root@ubuntu ~]# systemctl start nginx.service[root@ubuntu ~]# iptables -A INPUT -s 10.0.0.206 -j DROP
#客户端测试,60S 后超时,显示504[root@ubuntu ~]# time curl http://www.m99-josedu.com<html><head><title>504 Gateway Time-out</title></head><body><center><h1>504 Gateway Time-out</h1></center><hr><center>nginx</center></body></html>
real 1m0.057suser 0m0.009ssys 0m0.010s
#修改超时时长为10Sserver { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.210; proxy_set_header Host $http_host; proxy_connect_timeout 10s; }}
#客户端再次测试[root@ubuntu ~]# time curl http://www.m99-josedu.com<html><head><title>504 Gateway Time-out</title></head><body><center><h1>504 Gateway Time-out</h1></center><hr><center>nginx</center></body></html>
real 0m10.032suser 0m0.005ssys 0m0.014s
#修改后端服务器策略[root@ubuntu ~]# iptables -F[root@ubuntu ~]# iptables -A INPUT -s 10.0.0.206 -j REJECT
#客户端测试直接返回 502[root@ubuntu ~]# time curl http://www.m99-josedu.com<html><head><title>502 Bad Gateway</title></head><body><center><h1>502 Bad Gateway</h1></center><hr><center>nginx</center></body></html>
real 0m0.013suser 0m0.005ssys 0m0.006s
4.3.3 实现动静分离
根据条件进行调度,实现动静分离
#client 配置[root@ubuntu ~]# cat /etc/hosts10.0.0.206 www.m99-josedu.com
#Proxy Server 配置server { listen 80; server_name www.m99-josedu.com; #root /var/www/html/www.m99-josedu.com; location /api { proxy_pass http: proxy_set_header Host "api.m99-josedu.com";}
location /static { proxy_pass http: proxy_set_header Host "static.m99-josedu.com"; }}
#API Server 配置server { listen 80; root /var/www/html/api.m99-josedu.com/; server_name api.m99-josedu.com;}[root@ubuntu ~]# cat /var/www/html/api.m99-josedu.com/api/index.htmlapi
#Static Server 配置server { listen 80; root /var/www/html/static.m99-josedu.com; server_name static.m99-josedu.com;}
[root@ubuntu ~]# cat /var/www/html/static.m99-josedu.com/static/index.htmlstatic[root@ubuntu ~]# curl http:api[root@ubuntu ~]# curl http:static
location /api { proxy_pass http://10.0.0.159; proxy_set_header Host "api.m99-josedu.com";}
location /api { proxy_pass http://10.0.0.159/; proxy_set_header Host "api.m99-josedu.com";}
location ~ \.(jpe?g|png|bmp|gif)$ { proxy_pass http://10.0.0.159; proxy_set_header Host "api.m99-josedu.com";}
4.3.4 代理服务器实现数据缓存
前置条件:各服务器时间和时区先统一,方便测试
#Proxy Server 配置#定义缓存proxy_cache_path /tmp/proxycache levels=1:2 keys_zone=proxycache:20m inactive=60s max_size=1g;
server { listen 80; server_name www.m99-josedu.com; location /static { proxy_pass http: proxy_set_header Host "static.m99-josedu.com"; proxy_cache proxycache; #使用缓存 proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 90s; proxy_cache_valid any 2m; #此处一定要写,否则缓存不生效 }}
#重载,生成缓存目录[root@ubuntu ~]# nginx -s reload[root@ubuntu ~]# ll /tmp/proxycache/total 8drwx------ 2 www-data root 4096 Feb 12 23:09 ./drwxrwxrwt 14 root root 4096 Feb 12 23:09 ../
#Static Server 配置server { listen 80; root /var/www/html/static.m99-josedu.com; server_name static.m99-josedu.com;}[root@ubuntu ~]# ls -lh /var/www/html/static.m99-josedu.com/static/total 8.0K-rw-r--r-- 1 root root 657 Feb 12 15:14 fstab-rw-r--r-- 1 root root 7 Feb 12 04:42 index.html
#客户端测试[root@ubuntu ~]# curl http:
#查看 Proxy Server 上的缓存数据,文件名就是key 的 hash 值[root@ubuntu ~]# tree /tmp/proxycache//tmp/proxycache/└── 3└── ab└── 2d291e4d45687e428f0215bec190aab3
#并不是一个文本文件[root@ubuntu ~]# file /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3/tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3: data
#查看当前时间和缓存文件时间[root@ubuntu ~]# dateMon Feb 12 11:35:55 PM CST 2025[root@ubuntu ~]# stat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3File: /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3Size: 1270 Blocks: 8 IO Block: 4096 regular fileDevice: fd00h/64768d Inode: 786517 Links: 1Access: (0600/-rw-------) Uid: ( 33/www-data) Gid: ( 33/www-data)Access: 2025-02-12 23:35:50.506517303 +0800Modify: 2025-02-12 23:35:50.506517303 +0800Change: 2025-02-12 23:35:50.506517303 +0800Birth: 2025-02-12 23:35:50.506517303 +0800
#除了文件内容外,还有头部信息[root@ubuntu ~]# cat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3
#生命周期结束后文件被删除[root@ubuntu ~]# dateMon Feb 12 11:36:54 PM CST 2025[root@ubuntu ~]# stat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3stat: cannot statx '/tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3': No such file or directory
#但是在缓存有效期内,后端服务器内容发生了更新,客户端获取的还是缓存数据#后端真实数据删除,客户端还能拿到缓存数据[root@ubuntu ~]# rm -f /var/www/html/static.m99-josedu.com/static/fstab
#客户端测试[root@ubuntu ~]# curl http://www.m99-josedu.com/static/fstab
proxy_cache_path /tmp/proxycache levels=1:2 keys_zone=proxycache:20m inactive=60s max_size=1g;
server { listen 80; server_name www.m99-josedu.com; location /static { proxy_pass http://10.0.0.210; proxy_set_header Host "static.m99-josedu.com"; proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 90s; proxy_cache_valid any 2m; add_header X-Cache $upstream_cache_status; }}
[root@ubuntu ~]/tmp/proxycache/└── 3 └── ab
[root@ubuntu ~]HTTP/1.1 200 OKServer: nginxDate: Mon, 12 Feb 2025 15:51:48 GMTContent-Type: application/octet-streamContent-Length: 657Connection: keep-aliveLast-Modified: Mon, 12 Feb 2025 15:14:44 GMTETag: "65ca35e4-291"X-Cache: MISS #首次访问,没有命中缓存,MISSAccept-Ranges: bytes
[root@ubuntu ~]HTTP/1.1 200 OKServer: nginxDate: Mon, 12 Feb 2025 15:51:54 GMTContent-Type: application/octet-streamContent-Length: 657Connection: keep-aliveLast-Modified: Mon, 12 Feb 2025 15:14:44 GMTETag: "65ca35e4-291"X-Cache: HIT #缓存数据在生命周期内,被命中Accept-Ranges: bytes
[root@ubuntu ~]-rw-r----- 1 root root 242K Feb 13 00:08 /var/www/html/static.m99-josedu.com/static/syslog
[root@ubuntu ~]This is ApacheBench, Version 2.3 <$Revision: 1879490 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.m99-josedu.com (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requests......Total transferred: 3190000 bytesHTML transferred: 1620000 bytesRequests per second: 3300.30 [Time per request: 30.300 [ms] (mean)Time per request: 0.303 [ms] (mean, across all concurrent requests)Transfer rate: 1028.12 [Kbytes/sec] received
proxy_cache_path /tmp/proxycache levels=1:2 keys_zone=proxycache:20m inactive=60s max_size=1g;
server { listen 80; server_name www.m99-josedu.com; location /api { proxy_pass http://10.0.0.159/; proxy_set_header Host "api.m99-josedu.com";}
location /static { proxy_pass http://10.0.0.210; proxy_set_header Host "static.m99-josedu.com"; proxy_cache off; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 90s; proxy_cache_valid any 2m; add_header X-Cache $upstream_cache_status; }}
[root@ubuntu ~]This is ApacheBench, Version 2.3 <$Revision: 1879490 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.m99-josedu.com (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requests......Total transferred: 3190000 bytesHTML transferred: 1620000 bytesRequests per second: 1845.59 [Time per request: 54.183 [ms] (mean)Time per request: 0.542 [ms] (mean, across all concurrent requests)Transfer rate: 574.94 [Kbytes/sec] received
4.3.5 实现客户端IP地址透传
在使用 Nginx 做代理的情况下,默认后端服务器无法获取客户端真实IP地址
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.210; }}
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { return 200 ${remote_addr}---${http_x_real_ip}---${http_x_forwarded_for}; }}
[root@ubuntu ~]10.0.0.206------
server { listen 80; server_name www.m99-josedu.com; #root /var/www/html/www.m99-josedu.com; location / { proxy_pass http: proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
#表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addr proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#客户端测试 $remote_addr 获取代理IP,$http_x_real_ip 获取真实客户端IP,$http_x_forwarded_for 获取真实客户端IP[root@ubuntu ~]# curl www.m99-josedu.com10.0.0.206---10.0.0.208---10.0.0.208
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.159; }}
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { proxy_pass http://10.0.0.210; }}
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { return 200 ${remote_addr}---${http_x_real_ip}---${http_x_forwarded_for}; }}
[root@ubuntu ~]10.0.0.159------
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.159; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
[root@ubuntu ~]10.0.0.159---10.0.0.208---10.0.0.208
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { proxy_pass http://10.0.0.210; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
[root@ubuntu ~]10.0.0.159---10.0.0.206---10.0.0.208, 10.0.0.206
server { listen 80; server_name www.m99-josedu.com; location / { proxy_pass http://10.0.0.159; }}
[root@ubuntu ~]10.0.0.159---10.0.0.206---10.0.0.206
— END —
阅读原文:原文链接
该文章在 2025/7/1 23:13:07 编辑过