[设计模式/网络/WebServer/Nginx]设计模式之代理模式(网络代理 : 正向代理与反向代理)【7】

2023-06-14,,

1 代理模式

1.1 模式定义

代理模式(Proxy Pattern):为其他对象提供一种代理服务以对这个被代理的对象进行控制访问。[ 设计模式、面向对象程序设计思想的鼻祖————GoF]

Subject : 定义了RealSubjectProxy的共用接口。这样就在任何地方使用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 参考/推荐文献

反向代理和正向代理区别 [推荐] - 博客园
《大话设计模式.清华大学出版社.程杰》:Page 63
Nginx详解(正向代理、反向代理、负载均衡原理) - CSDN

[设计模式/网络/WebServer/Nginx]设计模式之代理模式(网络代理 : 正向代理与反向代理)【7】的相关教程结束。

《[设计模式/网络/WebServer/Nginx]设计模式之代理模式(网络代理 : 正向代理与反向代理)【7】.doc》

下载本文的Word格式文档,以方便收藏与打印。