在Go中测量反向代理的响应时间

huangapple go评论95阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2022年1月2日 00:27:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/70550180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定