网络代理于网络转发区别

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重



网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_02



网络代理:

用户不直接连接服务器,网络代理去连接,获取数据后返回给用户

网络转发:

是路由器对报文的转发操作,中间可能对数据包修改


网络代理类型:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_服务器_03


 网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_负载均衡_04




正向代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_05


 实现一个web浏览器代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_服务器_06


 代码实现一个web浏览器代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_负载均衡_07


 代码实现:



反向代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_负载均衡_08



如何实现一个反向代理:

  • 这个功能比较复杂,我们先实现一个简版的http反向代理。
  • 代理接收客户端请求,更改请求结构体信息
  • 通过一定的负载均衡算法获取下游服务地址
  • 把请求发送到下游服务器,并获取返回的内容
  • 对返回的内容做一些处理,然后返回给客户端


启动两个http服务(真是服务地址)

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

real_server



启动一个代理服务

代理服务 127.0.0.1:2002(此处代码并没有使用负载均衡算法,只是简单地固定代理到其中一个服务器)

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

reverse_proxy



用户访问127.0.0.1:2002   反向代理到  127.0.0.1:2003


http代理

上面演示的是一个简版的http代理,不具备一下功能:

  • 错误回调及错误日志处理
  • 更改代理返回内容
  • 负载均衡
  • url重写
  • 限流、熔断、降级



用golang官方提供的ReverseProxy实现一个http代理

  • ReverseProxy功能点
  • ReverseProxy实例
  • ReverseProxy源码实现



拓展ReverseProxy功能

  • 4中负载轮训类型实现以及接口封装
  • 拓展中间件支持:限流、熔断实现、权限、数据统计


用ReverseProxy实现一个http代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_13




ReverseProxy修改返回的内容

重写 


ReverseProxy补充知识:

特殊Header头:X-Forward-For、X-Real-Ip、Connection、TE、Trailer

第一代理取出标准的逐段传输头(HOP-BY-HOP)

X-Forward-For

  • 记录最后直连实际服务器之前,整个代理过程
  • 可能会被伪造

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_负载均衡_14



X-Real-Ip

  • 请求实际服务器的IP
  • 每过一层代理都会被覆盖掉,只需要第一代里设置转发
  • 不会被伪造

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_负载均衡_15

 代码实现:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

第一层代理



第二层代理

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

View Code



实际服务器:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

View Code


负载均衡策略:

  • 随机负载
  • 随机挑选目标服务器ip
  • 轮询负载
  • ABC三台服务器,ABCABC一次轮询
  • 加权负载
  • 给目标设置访问权重,按照权重轮询
  • 一致性hash负载
  • 请求固定的url访问固定的ip


随机负载:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

random.go


网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

random_test



轮询负载:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

round_tobin


网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

round_robin_test



加权负载均衡:

  • Weight
  • 初始化时对节点约定的权重
  • currentWeight
  • 节点临时权重,每轮都会变化
  • effectiveWeight
  • 节点有效权重,默认与Weight相同
  • totalWeight
  • 所有节点有效权重之和:sum(effectiveWeight)



  • 1,currentWeight = currentWeight + effectiveWeight
  • 2,选中最大的currentWeight节点为选中的节点
  • 3,currentWeight = currentWeight-totalWeight(4+3+2=9)

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_服务器_30


 计算方法如下:

第一次:

  • currentWeight = currentWeight + effectiveWeight
  • currentWeight    {A=4+4,B=3+3,C=2+2}   ==  {A=8,B=6,C=4}
  •   选中最大的currentWeight节点为选中的节点
  •     A最大 此时作为节点
  •   currentWeight = currentWeight-totalWeight(4+3+2=9)  【选中的节点currentWeight = currentWeight-totalWeight】
  •     currentWeight  {A=8-9,B=6,C=4}  == {A=-1,B=6,C=4}

第二次:{A=-1,B=6,C=4} 开始

  • currentWeight = currentWeight + effectiveWeight
  • currentWeight    {A=-1+4,B=6+3,C=4+2}   ==  {A=3,B=9,C=6}
  •   选中最大的currentWeight节点为选中的节点
  •     B最大 此时作为节点
  •   选中的节点currentWeight = currentWeight-totalWeight(4+3+2=9)
  •     currentWeight  {A=3,B=9-9,C=6}  == {A=3,B=0,C=6}

。。。。。。。以此类推。。。。。。。。。

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_31

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

weight_tound_robin.go

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

test


一致性hash(ip_hash、url_hash)

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_36

为了解决平衡性:引入了虚拟节点概念(把个节点 均匀的覆盖到环上)

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

consistent_hash.go


网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_09网络代理之HTTP代理(golang反向代理、负载均衡算法实现)_权重_10

test.go

工厂方法简单封装上述几种拒载均衡调用:

interface.go

factory.go

调用: