[设计模式/网络/WebServer/Nginx]设计模式之代理模式(网络代理 : 正向代理与反向代理)【7】
1 代理模式
1.1 模式定义
代理模式
(Proxy Pattern
):为其他对象提供一种代理服务以对这个被代理的对象进行控制访问。[ 设计模式、面向对象程序设计思想的鼻祖————GoF]
Subject
: 定义了RealSubject
和Proxy
的共用接口。这样就在任何地方使用RealSubject
的地方都可以使用Proxy
RealSubject
: 定义了Proxy
所代表的真实实体Proxy
: 保存一个引用(realSubject)
,使得代理可以访问实体,并提供一个与Subject
的接口相同的接口。这样代理就阔以用来代替真实实体
1.2 样例代码
Subject
public abstract class Subject {
public abstract void service();
}
RealSubject
public class RealSubject extends Subject {
@overrite
public void service(){
System.out.println("真实的请求!");
}
}
Proxy
public class Proxy {
RealSubject realSubject;
public void service(){
if(realSubject == null) {
realSubject = new RealSubject();
}
realSubject.service();
}
}
Client
public Client {
public void main(String[] args) {
Proxy proxy = new Proxy();
proxy.service();
}
}
1.3 应用场景
1.4 主要角/主要组件
代理模式是设计模式中的一种经典设计模式,又称为:委托模式。
该模式涉及3个关键角色:(牢牢记住、理解这3个角色,反向代理与正向代理就不会乱!!!)
- (源)目标服务提供者
- 委托者
真正【享用】目标服务的实体 - 代理者
实际【首先发起 (请求/接收/转发)】目标服务的实体
代理者可访问委托者,并提供委托者需要的与(源)目标服务相同的(代理)目标服务
1.5 网络代理
那么,我们常说的网络代理又是怎么个情况?
"刚开始的时候,代理多数是帮助[内网]client访问[外网]server用的" (外网: 相对于client而言)
"后来出现了反向代理,"反向"这个词在这儿的意思————其实是指方向相反,即
代理将来自[外网]client的请求转发到[内网]server" (外网: 相对于server而言)
2 正向代理(Forward Proxy)
- (源)目标服务提供者: 网络服务器(服务源)
- 委托者:浏览器
- 代理者: 代理服务器
代理服务器能同时联通 委托者 和 源目标服务提供者
(即 代理服务器既能与委托者通信,又能与源目标服务提供者通信)
2-1 简述
最早出现的网络代理模式,其出现先于后出现的反向代理模式。
"正向代理类似一个跳板机,代理访问外部资源"
[场景1]国内网民访问被GWF防火墙黑名单屏蔽的Google/Youtube等外网资源,需通过代理服务器间接访问。
国内网民访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器。
浏览器直接请求代理服务器,代理服务器(能够)直接访问谷歌。
这样,由代理服务器去谷歌服务器取到返回数据,再返回给国内网民的浏览器。以此间接访问谷歌等被屏蔽的外网资源。
防火墙【黑名单】
+ 黑名单右侧/国际网络上侧的服务器————Blacklist Servers:
防火墙左侧[国内网络(香港部分节点除外)]任一服务器 无法访问 Blacklist Servers
防火墙【白名单】
+ 白名单右侧/国际网络下侧的服务器————Whitelist Servers:
防火墙左侧[国内网络]任一服务器 均能访问 Whitelist Servers
2-2 用途
- 1 [隐藏委托者] 代理服务器 隐藏 客户端的真实信息
对目标服务器而言,客户端信息被屏蔽了。 - 2 [突破委托者网络] 代理服务器 (FQ/反屏蔽/冲破客户端网络) 获取客户端原本获取不到的目标服务器的网络资源
[突破客户端自身IP的访问限制]
访问原来无法访问的资源,如: Google,Youtube,... - 3 [缓存加速访问目标服务的速度] 代理服务器 做缓存 加速客户端访问(目标服务器的网络资源)速度
- 4 [客户端的防火墙]
- 上网鉴权+授权。对客户端访问授权,上网进行认证
- 管理委托者网络行为。代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
2-3 应用实践
以正向代理Google为例,用户访问地址: http://g.example.com
参考文献
使用nginx代理google - CSDN
[未亲测,不完全保证其可用性]
proxy_cache_path conf/cache/one levels=1:2 keys_zone=one:10m max_size=10g;
proxy_cache_key "$host$request_uri";
upstream google_server {
server 173.194.127.212;
server 173.194.127.208;
server 173.194.127.209;
server 173.194.127.210;
server 173.194.127.211;
}
server {
listen 80;
server_name g.example.com;
access_log /var/log/nginx/access.log;
rewrite ^(.*) https://g.example.com$1 permanent;
}
server {
listen 443;
server_name g.example.com;
resolver 8.8.8.8; # 可设置,可不设置
# [resolver] nginx 通过 proxy_pass 和 upstream server 通信的时候,可能需要手动指定 resolver。
# 1 因为某些时候 DNS 解析失败,就会出现此错误: domain.com could not be resolved.
# 2 参考文献: [ http://www.zzvips.com/article/22410.html ]
access_log /var/log/nginx/access.log;
ssl on;
ssl_certificate ssl/g.crt;
ssl_certificate_key ssl/g.key;
location / {
proxy_cache one;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 1m;
proxy_redirect off;
proxy_pass https://www.google.com.hk/;
proxy_redirect https://www.google.com.hk/ /;
proxy_cookie_domain www.google.com g.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
proxy_set_header User-Agent $http_user_agent;
proxy_set_header Accept-Language "zh-CN";
proxy_set_header Cookie "PREF=ID=047808f19f6de346:U=0f62f33dd8549d11:FF=2:LD=zh-CN:NW=1:TM=1325338577:LM=1332142444:GM=1:SG=2:S=rE0SyJh2W1IQ-Maw";
subs_filter www.google.com g.example.com;
}
}
3 反向代理(Reverse Proxy)
- (源)目标服务提供者: 浏览器
对于 网络服务器(服务源)而言,浏览器的网络请求(数据) 即 网络服务器的(源)目标服务。 - 委托者: 网络服务器(服务源)
- 代理者: 代理服务器
代理服务器能同时联通 委托者 和 源目标服务提供者
(即 代理服务器既能与委托者通信,又能与源目标服务提供者通信)
3-1 简述
反向代理(Reverse Proxy)实际运行方式:
用代理服务器来接受internet上的连接请求;
接着,将请求转发给内部网络上的服务器;
然后,将从服务器上得到的结果返回给internet上请求连接的客户端。
此时,代理服务器 对外(对终端浏览器) 而言,就表现为一个服务器。
即 用户和负载均衡服务器直接通信 => 用户 解析 网站域名时得到的是负载均衡服务器的IP
3-2 用途
- 负载均衡
通过反向代理服务器来优化网站的负载。 - 解决浏览器的跨域问题
- 保证服务器内网安全
代理服务器 隐藏 网络服务器的真实信息。
保证内网的安全,阻止web攻击。
通常地,大型网站将反向代理服务器作为公网访问地址,Web服务器部署在内网。
3-3 应用实践
#1 负载均衡(Load Balancing)
[.../conf/nginx.conf]
...
http{
include taobao/*.conf;
}
...
[.../conf/taobao/serviceA.conf]
upstream serviceA_server {
ip_hash;
server a1.taobao.com:8081 weight=8;
server a2.taobao.com:8081 weight=2;
server 172.xx.yy.zz:8081 weight=1;
# ...
server a(...).taobao.com:8081 weight=1;
}
server {
#listen 443 ssl; # replace old config - https
listen 80;
server_name a.taobao.com;
charset utf-8;
proxy_redirect http:// $scheme://;
port_in_redirect on;
# ssl on; # replace old config - https
location / {
return 301 http://a.taobao.com/serviceA;
# return 301 http://a.taobao.com/index.html;
# return 301 https://a.taobao.com/index.html;
}
location /serviceA { # 用户请求: http://a.taobao.com/serviceA
proxy_pass http://serviceA_server/serviceA;
# 转发到: http://a1.taobao.com:8081/serviceA (此服务崩溃后或当前流量过高时,其它备用的服务器服务顶上)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# ...
error_page 404 403 500 502 503 504 /404.html;
location = /404.html {
#root /usr/share/nginx/html;
root /usr/local/nginx/html;
}
}
#2 解决浏览器跨域问题
"跨域资源共享"(Cross-Origin Resource Sharing)
[.../conf/nginx.conf]
...
http{
include wahaha.com/*.conf;
}
...
[.../conf/wahaha.com/cors-config.conf]
upstream serviceB_server {
ip_hash;
server 192.168.2.2:8082 weight=1;
# ... serviceB 的 备份服务器
}
upstream serviceC_server {
ip_hash;
server 192.168.2.3:8083 weight=1;
# ... serviceC 的 备份服务器
}
upstream serviceD_server {
ip_hash;
server 192.168.2.4:8084 weight=1;
# ... serviceD 的 备份服务器
}
upstream serviceE_server {
ip_hash;
server 192.168.2.5:8085 weight=1;
# ... serviceE 的 备份服务器
}
server {
#listen 443 ssl; # replace old config - https
listen 80;
server_name wahaha.com;
charset utf-8;
proxy_redirect http:// $scheme://;
port_in_redirect on;
# ssl on; # replace old config - https
location / {
return 301 http://wahaha.com/serviceB/index.html;
# serviceB/index.html 调用 其它涉及跨域(跨服务器)的服务
# return 301 https://wahaha.com/serviceB/index.html;
}
location /serviceB { # 用户请求: http://wahaha.com/serviceB
proxy_pass http://serviceB_server/serviceB;
# 转发到: http://192.168.2.2:8082/serviceB (此服务崩溃后或当前流量过高时,其它备用的服务器服务顶上)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /serviceC { # 用户请求: http://wahaha.com/serviceC
proxy_pass http://serviceC_server/serviceC;
# 转发到: http://192.168.2.3:8083/serviceC (此服务崩溃后或当前流量过高时,其它备用的服务器服务顶上)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /serviceD { # 用户请求: http://wahaha.com/serviceD
proxy_pass http://serviceD_server/serviceD;
# 转发到: http://192.168.2.4:8084/serviceD (此服务崩溃后或当前流量过高时,其它备用的服务器服务顶上)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /serviceE { # 用户请求: http://wahaha.com/serviceE
proxy_pass http://serviceE_server/serviceE;
# 转发到: http://192.168.2.5:8085/serviceB (此服务崩溃后或当前流量过高时,其它备用的服务器服务顶上)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# ...
error_page 404 403 500 502 503 504 /404.html;
location = /404.html {
#root /usr/share/nginx/html;
root /usr/local/nginx/html;
}
}
4 正向代理与反向代理的异同
4-1 相同点
- 代理模式 三角色 / 三实体
代理模式三角色 : (源)目标服务提供者 / 委托者 / 代理者
三真实实体: 网络服务器 / 浏览器 / 代理服务器
(【实体】在代理模式中扮演的【角色】和【作用】,在正向代理和反向代理中不同。)
- 代理者: 代理服务器
代理服务器始终扮演:代理者的角色;
代理服务器始终能够:代理服务器能同时联通 委托者 和 源目标服务提供者 (即 代理服务器既能与委托者通信,又能与源目标服务提供者通信)
- 网络请求流程
Step1 客户端 客户请求 代理服务器
Step2 代理服务器 代理请求 网络服务器
Step3 网络服务器 响应代理请求 代理服务器
Step4 代理服务器 响应客户请求 客户端
4-2 差异点
- 委托者/(源)目标服务提供者的角色
正向代理 代理 客户端,反向代理 代理 网络服务器。
正向代理:
委托者 - 客户端
(源)目标服务提供者 - 网络服务器
反向代理:
委托者 - 网络服务器
(源)目标服务提供者 - 客户端
M Nginx
Nginx常用于:搭建HTTP代理服务器
Nginx 主要能够代理如下几种协议:
- Web: HTTP
- Mail: POP3/IMAP/STMP
- Stream Media: RTMP
RTMP := Real Time Messaging Protocol := 实时消息传输协议
Y 延伸
-
概念
VPN / 堡垒机(跳板机) / 镜像网站 / 正向代理 / 反向代理
CSRF/XSS -
如何借Nginx实现: 正向代理 / 反向代理? [√]
详见本文即可 ---- 2020/10/15
X 参考/推荐文献
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!