对 Go 的 http2 实现的困惑
Confusion over Go's http2 implementation
我 运行 大量通过 SSL 的流量。我正在考虑通过使用 http2 客户端来加快这些调用。但是,我很犹豫是否要这样做,因为感觉我对它的行为方式的控制较少。
这是一个使用 Go 基础的生产客户端 net/http
ClientHTTP := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: timeout * time.Second,
KeepAlive: 1 * time.Minute,
}).Dial,
TLSHandshakeTimeout: timeout * time.Second,
MaxIdleConns: 3000,
MaxIdleConnsPerHost: 3000,
IdleConnTimeout: 60 * time.Second,
},
Timeout: timeout * time.Second,
}
据我所知,我对传输的控制较少。
ClientHTTP2 := &http.Client{
Transport: &http2.Transport{
AllowHTTP: true,
},
Timeout: timeout * time.Second,
}
有什么我遗漏的吗? http2 生产准备好了吗?我知道 http2 使用单个 TCP 连接,因此像池这样的东西消失了。然而,它不知何故感觉不完整。这些行为是否与生产客户端相同?有没有更好的方法来实现 ClientHTTP2
最后,AllowHTTP
似乎什么也没做。在可能有 http 调用的情况下,我认为我能够安全地调用它,但它却出错了。
http.Transport
支持 HTTP2,但是您必须配置更现代的 DialContext,而不是 Dial(已弃用):
package main
import (
"fmt"
"net"
"net/http"
"net/http/httputil"
"time"
)
func main() {
c := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{ // use DialContext here
Timeout: 10 * time.Second,
KeepAlive: 1 * time.Minute,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
MaxIdleConns: 3000,
MaxIdleConnsPerHost: 3000,
IdleConnTimeout: 60 * time.Second,
},
Timeout: 1 * time.Second,
}
res, _ := c.Get("https://http2.akamai.com/")
b, _ := httputil.DumpResponse(res, false)
fmt.Println(string(b))
}
// HTTP/2.0 200 OK
// Content-Length: 11928
// Accept-Ch: DPR, Width, Viewport-Width, Downlink, Save-Data
// Access-Control-Allow-Credentials: false
// ...
使用 http2.Transport 的唯一原因是跳过初始连接升级(又名。先验知识)。如果这不是问题,请坚持使用标准客户端和传输。
我 运行 大量通过 SSL 的流量。我正在考虑通过使用 http2 客户端来加快这些调用。但是,我很犹豫是否要这样做,因为感觉我对它的行为方式的控制较少。
这是一个使用 Go 基础的生产客户端 net/http
ClientHTTP := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: timeout * time.Second,
KeepAlive: 1 * time.Minute,
}).Dial,
TLSHandshakeTimeout: timeout * time.Second,
MaxIdleConns: 3000,
MaxIdleConnsPerHost: 3000,
IdleConnTimeout: 60 * time.Second,
},
Timeout: timeout * time.Second,
}
据我所知,我对传输的控制较少。
ClientHTTP2 := &http.Client{
Transport: &http2.Transport{
AllowHTTP: true,
},
Timeout: timeout * time.Second,
}
有什么我遗漏的吗? http2 生产准备好了吗?我知道 http2 使用单个 TCP 连接,因此像池这样的东西消失了。然而,它不知何故感觉不完整。这些行为是否与生产客户端相同?有没有更好的方法来实现 ClientHTTP2
最后,AllowHTTP
似乎什么也没做。在可能有 http 调用的情况下,我认为我能够安全地调用它,但它却出错了。
http.Transport
支持 HTTP2,但是您必须配置更现代的 DialContext,而不是 Dial(已弃用):
package main
import (
"fmt"
"net"
"net/http"
"net/http/httputil"
"time"
)
func main() {
c := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{ // use DialContext here
Timeout: 10 * time.Second,
KeepAlive: 1 * time.Minute,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
MaxIdleConns: 3000,
MaxIdleConnsPerHost: 3000,
IdleConnTimeout: 60 * time.Second,
},
Timeout: 1 * time.Second,
}
res, _ := c.Get("https://http2.akamai.com/")
b, _ := httputil.DumpResponse(res, false)
fmt.Println(string(b))
}
// HTTP/2.0 200 OK
// Content-Length: 11928
// Accept-Ch: DPR, Width, Viewport-Width, Downlink, Save-Data
// Access-Control-Allow-Credentials: false
// ...
使用 http2.Transport 的唯一原因是跳过初始连接升级(又名。先验知识)。如果这不是问题,请坚持使用标准客户端和传输。