Go | Go 结合 Consul 实现动态反向代理(类似 Spring Cloud Gateway)

本文介绍了如何使用Go语言构建动态反向代理,包括原生代码实现和使用httputil.ReverseProxy工具,以及如何结合Consul实现服务发现动态代理。通过自定义Director函数修改请求地址,结合Consul获取服务实例,实现代理服务器根据请求自动转发到正确后端服务。

Go 结合 Consul 实现动态反向代理

代理的核心功能可以用一句话概括:接受客户端的请求,转发到后端服务器,获得应答之后返回给客户端。



反向代理

反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

实现逻辑

根据代理的描述一共分成几个步骤:

  1. 代理接收到客户端的请求,复制了原来的请求对象
  2. 根据一些规则,修改新请求的请求指向
  3. 把新请求发送到根据服务器端,并接收到服务器端返回的响应
  4. 将上一步的响应根据需求处理一下,然后返回给客户端

Go 语言实现

原生代码

因为要接收并转发 http 请求,所以要实现 http.Handler

type OriginReverseProxy struct {
   
   
	servers []*url.URL
}

func NewOriginReverseProxy(targets []*url.URL) *OriginReverseProxy {
   
   
	return &OriginReverseProxy{
   
   
		servers: targets,
	}
}

// 实现 http.Handler, 用于接收所有的请求
func (proxy *OriginReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
   
   
	// 1. 复制了原来的请求对象
	r2 := clone(req)

	// 2. 修改请求的地址,换为对应的服务器地址
	target := proxy.servers[rand.Int()%len(proxy.servers)]
	r2.URL.Scheme = target.Scheme
	r2.URL.Host = target.Host

	// 3. 发送复制的新请求
	transport := http.DefaultTransport

	res, err := transport.RoundTrip(r2)
	
	// 4。处理响应
	if err != nil {
   
   
		rw.WriteHeader(http.StatusBadGateway)
		return
	}

	for key, value := range res.Header {
   
   
		for _, v := range value {
   
   
			rw.Header().Add(key, v)
		}
	}

	rw.WriteHeader(res.StatusCode)
	io.Copy(rw, res.Body)
	res.Body.Close()
}

// 复制原请求,生成新的请求
func clone(req *
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值