如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多系列文章在我博客[1]

Golang 实现简版反向代理

正向代理 和 反向代理

如果说昨天介绍的 正向代理服务器 是从 用户端 角度出发。使得用户端能够:

  1. 访问无法访问的数据 —— 访问谷歌
  2. 加速页面访问速度的缓存 —— CDN 缓存
  3. 对客户端访问内容过滤, 访问授权 —— 公司内网不能访问购物网站; 网吧
  4. 上网管理记录用户访问记录,对外隐藏特殊信息 —— 路由访问记录

那么今天要说的 反向代理服务器 则从 服务端 考虑

  1. 负载均衡, 提高服务可扩展、稳定性 —— 服务器集群、多中心机房、灾备
  2. ip白名单、限制开发端口, 保护内网安全 —— 网关
  3. 限流、熔断、降级 —— 网关
  4. 访问数据统计、访问内容权限控制 —— 网关
  5. 内网、外网通过代理转发,对外隐藏实现细节。增加内部服务安全性 —— 网关

举个现有的例子:就是使用广受欢迎的Nginx。个人感觉反向代理在业务上面更多以网关角色呈现, 而网关则更像一个定制化 Nginx

简版反向代理实现

《HTTP 权威指南》中概括用一句话概括了 代理的核心功能:接受客户端的请求,转发到后端服务器,获得响应并返回给客户端

这些都没在下面的代码实现中一一找到对应:

  1. 接受客户端的请求:第 11 行 设置路由, 所有请求 代理服务器 由 handler() 方法处理
  2. handler() 方法内 第 27 行 解析 下游服务器 的 请求协议、ip地址。并设入请求变量 r
  3. 转发到后端服务器:请求 r 由 第 33 行 transport.RoundTrip(r), 转发请求至下游服务器
  4. 获得响应:下游服务器 请求 Header 信息 在 第 40 ~ 44 行 设入代理服务器的响应 w
  5. 返回给客户端:代理服务器的响应 w 并返回

启动 下游(被代理)服务器

$ go run reverse_proxy_v1/real_server/main.go
2021/06/12 17:59:24 starting httpserver at 127.0.0.1:2003
2021/06/12 17:59:24 starting httpserver at 127.0.0.1:2004

测试 下游(被代理)服务器

$ curl 'http://127.0.0.1:2003/sda?sda=111'


http://127.0.0.1:2003/sda
RemoteAddr=127.0.0.1:49795,X-Forwarded-For=,X-Real-Ip=
headers =map[Accept:[*/*] User-Agent:[curl/7.69.1]]




$ curl 'http://127.0.0.1:2004/sda?sda=111'


http://127.0.0.1:2003/sda
RemoteAddr=127.0.0.1:49795,X-Forwarded-For=,X-Real-Ip=
headers =map[Accept:[*/*] User-Agent:[curl/7.69.1]]

启动 代理服务器

$ go run reverse_proxy/reverse_proxy_v1/reverse_proxy_base/main.go
2021/06/12 18:32:21 start serving on port2002

测试 代理服务器

$ curl 'http://127.0.0.1:2002/sda?sda=111'


# 转发至 2003 并返回结果
http://127.0.0.1:2003/sda
RemoteAddr=127.0.0.1:57595,X-Forwarded-For=,X-Real-Ip=
headers =map[Accept:[*/*] Accept-Encoding:[gzip] User-Agent:[curl/7.69.1]]

请求代理服务器,返回结果`http://127.0.0.1:2003/sda`; 与直接请求 `http://127.0.0.1:2003/sda?sda=111` 结果一致。代理成功

References

[1] 更多系列文章在我博客: https://coderdao.github.io/