Golang发送HTTP2请求时如何指定流优先级
Go HTTP/2 客户端指定流优先级的实现方式
标准库net/http及扩展包golang.org/x/net/http2的http2.Transport没有提供全局配置流优先级的入口,也没法直接通过client.Get()这种便捷方法设置优先级,具体实现方式如下:
- 流优先级是绑定到单次HTTP请求对应HTTP/2流的配置,不是客户端全局参数,因此不能直接用
client.Get()这类封装好的便捷方法,需要手动构造*http.Request对象,配置完优先级后通过client.Do()发送请求。 - 配置单次请求优先级需要调用
http2.SetRequestPriority方法,传入构造好的请求对象,以及http2.Priority结构体参数:Weight:流权重,取值范围1~256,数值越高优先级越高Parent:当前流依赖的父流ID,新发起的请求默认填0(根连接流)即可Exclusive:是否独占父流依赖,设为true时当前流会成为父流的唯一高优先级依赖
代码示例
package main import ( "crypto/tls" "net" "net/http" "time" "golang.org/x/net/http2" ) func main() { client := http.Client{ Transport: &http2.Transport{ DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { return net.DialTimeout(network, addr, time.Second) }, AllowHTTP: true, }, } path := "https://example.com" // 手动构造请求对象,替代直接调用client.Get req, err := http.NewRequest(http.MethodGet, path, nil) if err != nil { panic(err) } // 给当前请求绑定HTTP/2流优先级 err = http2.SetRequestPriority(req, http2.Priority{ Weight: 200, // 权重设为200,高于默认优先级 Parent: 0, Exclusive: false, }) if err != nil { panic(err) } // 发送配置完成的请求 resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() }
注意事项
HTTP/2流优先级是协议层面给服务端的建议值,不是强制约束,服务端完全可以根据自身策略忽略优先级配置,实际请求处理顺序不一定完全匹配你设置的优先级规则。
如果需要给当前客户端所有发起的请求统一设置默认流优先级,可以自定义一个实现http.RoundTripper接口的包装层,在RoundTrip方法中统一给请求设置优先级后,再转发给底层的http2.Transport执行,不需要每次发请求都重复配置。
内容的提问来源于stack exchange,提问作者Navneet Priya
相关产品推荐
相关产品推荐

