diff --git a/imageproxy.go b/imageproxy.go index 6721056ea..5c253dae6 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -31,6 +31,7 @@ import ( "net/http" "net/url" "path" + "runtime" "strings" "time" @@ -113,6 +114,7 @@ func NewProxy(transport http.RoundTripper, cache Cache) *Proxy { Transport: &TransformingTransport{ Transport: transport, CachingClient: client, + limiter: make(chan struct{}, runtime.NumCPU()), log: func(format string, v ...interface{}) { if proxy.Verbose { proxy.logf(format, v...) @@ -151,7 +153,12 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { } timer := prometheus.NewTimer(metricRequestDuration) - defer timer.ObserveDuration() + metricRequestsInFlight.Inc() + defer func() { + timer.ObserveDuration() + metricRequestsInFlight.Dec() + }() + h.ServeHTTP(w, r) } @@ -427,6 +434,8 @@ type TransformingTransport struct { // responses are properly cached. CachingClient *http.Client + limiter chan struct{} + log func(format string, v ...interface{}) } @@ -440,6 +449,13 @@ func (t *TransformingTransport) RoundTrip(req *http.Request) (*http.Response, er return t.Transport.RoundTrip(req) } + if t.limiter != nil { + t.limiter <- struct{}{} + defer func() { + <-t.limiter + }() + } + f := req.URL.Fragment req.URL.Fragment = "" resp, err := t.CachingClient.Do(req) diff --git a/imageproxy_test.go b/imageproxy_test.go index 33267f8f2..771eb885d 100644 --- a/imageproxy_test.go +++ b/imageproxy_test.go @@ -492,6 +492,7 @@ func TestTransformingTransport(t *testing.T) { tr := &TransformingTransport{ Transport: testTransport{}, CachingClient: client, + limiter: make(chan struct{}, 1), } client.Transport = tr diff --git a/metrics.go b/metrics.go index e2d870a13..d77d9a35d 100644 --- a/metrics.go +++ b/metrics.go @@ -26,6 +26,11 @@ var ( Name: "request_duration_seconds", Help: "Request response times", }) + metricRequestsInFlight = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "http", + Name: "requests_in_flight", + Help: "Number of requests in flight", + }) ) func init() { @@ -33,4 +38,5 @@ func init() { prometheus.MustRegister(metricServedFromCache) prometheus.MustRegister(metricRemoteErrors) prometheus.MustRegister(metricRequestDuration) + prometheus.MustRegister(metricRequestsInFlight) }