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.com
server {
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 Gateway
Server: nginx
Date: Sun, 11 Feb 2025 12:41:53 GMT
Content-Type: text/html; charset=utf8
Content-Length: 150
Connection: 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.057s
user 0m0.009s
sys 0m0.010s
#修改超时时长为10S
server {
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.032s
user 0m0.005s
sys 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.013s
user 0m0.005s
sys 0m0.006s
4.3.3 实现动静分离
根据条件进行调度,实现动静分离
#client 配置
[root@ubuntu ~]# cat /etc/hosts
10.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.html
api
#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.html
static
[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 8
drwx------ 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 ~]# date
Mon Feb 12 11:35:55 PM CST 2025
[root@ubuntu ~]# stat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3
File: /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3
Size: 1270 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 786517 Links: 1
Access: (0600/-rw-------) Uid: ( 33/www-data) Gid: ( 33/www-data)
Access: 2025-02-12 23:35:50.506517303 +0800
Modify: 2025-02-12 23:35:50.506517303 +0800
Change: 2025-02-12 23:35:50.506517303 +0800
Birth: 2025-02-12 23:35:50.506517303 +0800
#除了文件内容外,还有头部信息
[root@ubuntu ~]# cat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3
#生命周期结束后文件被删除
[root@ubuntu ~]# date
Mon Feb 12 11:36:54 PM CST 2025
[root@ubuntu ~]# stat /tmp/proxycache/3/ab/2d291e4d45687e428f0215bec190aab3
stat: 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 OK
Server: nginx
Date: Mon, 12 Feb 2025 15:51:48 GMT
Content-Type: application/octet-stream
Content-Length: 657
Connection: keep-alive
Last-Modified: Mon, 12 Feb 2025 15:14:44 GMT
ETag: "65ca35e4-291"
X-Cache: MISS #首次访问,没有命中缓存,MISS
Accept-Ranges: bytes
[root@ubuntu ~]
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 12 Feb 2025 15:51:54 GMT
Content-Type: application/octet-stream
Content-Length: 657
Connection: keep-alive
Last-Modified: Mon, 12 Feb 2025 15:14:44 GMT
ETag: "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 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
......
Total transferred: 3190000 bytes
HTML transferred: 1620000 bytes
Requests 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 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
......
Total transferred: 3190000 bytes
HTML transferred: 1620000 bytes
Requests 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.com
10.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 编辑过