Golang——ReverseProxy源码分析


由于发文章时涉及到一些 m g 词汇,所以反复删除了原有的一些理解,这才能发表成功。

其中,一些词也纯拼音表示了,比如 dai li

ReverseProxy 位于 net.http.httputil 包下(只保留了这句 55555…)

功能点:

  • 支持自定义修改响应内容
  • 支持连接池
  • 支持错误信息自定义处理
  • 支持 websocket 服务
  • 支持自定义负载均衡
  • 支持 https dai li
  • 支持 url 重写

源码分析

声明:go.14 版本

核心结构体

type ReverseProxy struct {
   
	Director func(*http.Request)
	Transport http.RoundTripper
	FlushInterval time.Duration
	ErrorLog *log.Logger
	BufferPool BufferPool
	ModifyResponse func(*http.Response) error
	ErrorHandler func(http.ResponseWriter, *http.Request, error)
}

字段解释

字段 解释
Director 控制器 是一个函数,函数内容可以对请求进行修改
Transport 连接池,如果为 nil,则使用 http.DefaultTransport
FlushInterval 刷新内容到客户端的时间间隔
ErrorLog 错误记录器
BufferPool 缓冲池,在复制 http 响应时使用,用以提高请求效率
ModifyResponse 可自定义修改响应的函数
ErrorHandler 错误处理回调函数,如果为 nil,则遇到错误会显示 502

核心方法

// 根据目的URL对象,返回一个新的 ReverseProxy
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
   }

// 核心中的核心,实现了Handler接口
func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
   }

本文具体讲解 ServeHTTP方法,逻辑比较长,所以概括了下实现步骤:

声明:每个步骤的代码都是单独列出,是连续的,中间没有删除和增加任何代码,和源码保持一致,除了一些注释信息

step 1 设置连接池

如果没有配置,则使用 http 的默认连接池

transport := p.Transport
if transport == nil {
   
	transport = http.DefaultTransport
}

step 2 验证请求是否终止

从请求中取出上下文,然后通过类型断言 rw.(http.CloseNotifier),来判断连接(请求)是否终止,true 表示终止

如果终止了则直接放弃本次请求,即调用cancel(),取消此上下文,当然对应的资源也就释放了。

其中http.CloseNotifier是一个接口,只有一个方法CloseNotify() <-chan bool,作用是检测连接是否断开

ctx := req.Context()
if cn, ok := rw.(http.CloseNotifier); ok {
   
	var cancel context.CancelFunc
	ctx, cancel = context.WithCancel(ctx)
	defer cancel
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值