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

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 参考/推荐文献

posted @ 2020-10-15 01:04  千千寰宇  阅读(665)  评论(0编辑  收藏  举报