英文:
Measuring reverse proxy response times in Go
问题
我有一个基于http/net的Web反向代理。我正在使用NewSingleHostReverseProxy函数。如何测量目标Web服务器的响应时间?
英文:
I have a web reverse proxy based on http/net. I'm using NewSingleHostReverseProxy function. How can I measure response times of target web server ?
答案1
得分: 2
你可以这样做。将proxy.Transport
包装在另一个实现了http.Roundtripper
接口的结构体中,该结构体会计算RoundTrip响应所花费的时间。
我认为这通常会显示“响应时间”,而不是“请求时间”,因为仍然可以从响应中读取响应体,所以请求可能仍在进行中,但这应该能够显示服务器响应请求所花费的大致时间。
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"time"
)
func main() {
url, _ := url.Parse("https://stackoverflow.com")
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.Transport = NewTimingRoundtripper(http.DefaultTransport)
}
type TimingRoundtripper struct {
transport http.RoundTripper
}
func NewTimingRoundtripper(transport http.RoundTripper) http.RoundTripper {
return TimingRoundtripper{transport: transport}
}
func (rt TimingRoundtripper) RoundTrip(r *http.Request) (resp *http.Response, err error) {
start := time.Now()
resp, err = rt.transport.RoundTrip(r)
fmt.Println("request", r.URL, time.Since(start))
return resp, err
}
如果你想传递自定义的*tls.Config
(如下面的问题所问),你可以使用与http.DefaultTransport
相同的参数创建一个新的传输对象,但使用自定义的*tls.Config
。
var myTransport http.RoundTripper = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
然后像这样初始化:
proxy.Transport = NewTimingRoundtripper(myTransport)
英文:
You could do something like this. Wrap the proxy.Transport
with another http.Roundtripper
implementation that times how long it takes RoundTrip to respond.
I think this will generally show you "response time". Not "request time", since the body can still be read from the response, so the request could still be ongoing, but this should show you roughly how long it takes the server to respond to the request.
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"time"
)
func main() {
url, _ := url.Parse("https://stackoverflow.com")
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.Transport = NewTimingRoundtripper(http.DefaultTransport)
}
type TimingRoundtripper struct {
transport http.RoundTripper
}
func NewTimingRoundtripper(transport http.RoundTripper) http.RoundTripper {
return TimingRoundtripper{transport: transport}
}
func (rt TimingRoundtripper) RoundTrip(r *http.Request) (resp *http.Response, err error) {
start := time.Now()
resp, err = rt.transport.RoundTrip(r)
fmt.Println("request", r.URL, time.Since(start))
return resp, err
}
If you would like to pass a custom *tls.Config
(as asked below) you can create a new transport with the same parameters as the http.DefaultTransport
but with a custom *tls.Config
.
var myTransport http.RoundTripper = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
And then initialize like so:
proxy.Transport = NewTimingRoundtripper(myTransport)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论