lib/promscrape: retry target scraping when the target closes previously established keep-alive connection to it

This should fix the following error:

the server closed connection before returning the first response byte. Make sure the server returns 'Connection: close' response header before closing the connection
This commit is contained in:
Aliaksandr Valialkin 2020-04-16 23:24:33 +03:00
parent e2c3e1d2e5
commit 266bbec52d

View file

@ -79,8 +79,8 @@ func (c *client) ReadData(dst []byte) ([]byte, error) {
req.Header.Set("Authorization", c.authHeader) req.Header.Set("Authorization", c.authHeader)
} }
resp := fasthttp.AcquireResponse() resp := fasthttp.AcquireResponse()
// There is no need in calling DoTimeout, since the timeout is already set in c.hc.ReadTimeout. err := doRequestWithPossibleRetry(c.hc, req, resp)
err := c.hc.Do(req, resp)
fasthttp.ReleaseRequest(req) fasthttp.ReleaseRequest(req)
if err != nil { if err != nil {
fasthttp.ReleaseResponse(resp) fasthttp.ReleaseResponse(resp)
@ -120,3 +120,16 @@ var (
scrapesGunzipped = metrics.NewCounter(`vm_promscrape_scrapes_gunziped_total`) scrapesGunzipped = metrics.NewCounter(`vm_promscrape_scrapes_gunziped_total`)
scrapesGunzipFailed = metrics.NewCounter(`vm_promscrape_scrapes_gunzip_failed_total`) scrapesGunzipFailed = metrics.NewCounter(`vm_promscrape_scrapes_gunzip_failed_total`)
) )
func doRequestWithPossibleRetry(hc *fasthttp.HostClient, req *fasthttp.Request, resp *fasthttp.Response) error {
// There is no need in calling DoTimeout, since the timeout must be already set in hc.ReadTimeout.
err := hc.Do(req, resp)
if err == nil {
return nil
}
if err != fasthttp.ErrConnectionClosed {
return err
}
// Retry request if the server closed the keep-alive connection during the first attempt.
return hc.Do(req, resp)
}