Go net/http Timeout Guide

Source: Internet
Author: User
Tags response write
This is a creation in Article, where the information may have evolved or changed.

When writing a Go language HTTP server or client, timeout is the most easy and most sensitive error, there are many choices, an error can result in a long time without results, know that the network has failed, or the process is down.

HTTP is a complex multi-stage protocol, so there is no one-size-fits-all solution for timeouts . Think of the endpoint of a stream with the JSON API endpoint and the comet endpoint. In fact, the default value is often not what you want.

In this article, I will take different stages and you may need to apply a timeout and implement it in a different way than the server and the client.

The wild and the The husband
Translated 7 days ago

1 Person top

top translation of good Oh!

Other translation versions (1)
Loading ...

set deadline (timeout)

First, You need to understand the initial level of network timeout implementations that go provides: deadlines (deadline). The

implements deadlines in the Go standard library net.conn, with set[read| Write]deadline (time. Time) method to set. Deadlines is an absolute time, and once that is done, all I/O operations are stopped and a time-out error is generated. "Time." The precision of Time is nanosecond)

deadlines itself is not timed out . Once set, it will remain in effect (until once again setdeadline), and it does not care if the link exists during this period and how it is used. Therefore, you need to use Setdeadline to set a timeout length before each read/write operation.

In real-world development, you do not need to call setdeadline directly, but instead use a higher-level timeout setting in standard library net/http. However, it is important to note that all deadlines-based timeouts are executed, so does not need to reset the timeout before each receive/send operation. (This is also true for TCP, UDP, Unix-socket, see Standard Library net).

server timeout

It is critical to set the client link timeout for an HTTP server deployed on the Internet. Otherwise, an ultra-slow or disappearing client may leak the file descriptor and eventually cause an exception. As follows:

 http: accept error: accept tcp [::]:80: accept4: too  MANY OPEN FILES; RETRYING IN 5MS 

Caotj72
Translated 7 days ago

1 Person top

top translation of good Oh!

http. Server has two ways to set timeouts: ReadTimeout and Andwritetimeout '. You can set them explicitly:

SRV: = &http. server{Readtimeout:5 * time. Second, Writetimeout:10 * time. Second,}log. Println (SRV. Listenandserve ())

The time calculation of the readtimeout is completely read from the connection accepted (accept) to the request body (if you do not read the body, the time expires until the header is read). Its internal implementation is to call the Setreaddeadline method immediately in the Accept-code.

The writetimeout time is calculated normally from the end of the read of the request header to the end of response write (that is, the declaration period of the Servehttp method). It is implemented by calling Setwritedeadline at the end of the Readrequest Method-code.

However, when the connection is HTTPS, Setwritedeadline calls the-code immediately after the accept, so its time calculation also includes the time that the TLS handshake was written. The annoying thing is that this means (and only in this case) that the time set by WriteTimeout also contains the time to read Headerd to read the first byte of the body.

When you are dealing with untrusted clients and networks, you should set a read-write timeout at the same time, so that the client does not hold the connection because it is slow to read or slow to write.

Finally, there is an HTTP. Timeouthandler method. It is not a server parameter, but a handler wrapper function that can restrict servehttp calls. It caches response and sends 504 Gateway Timeout errors if deadline is exceeded. Note that this function has a problem in 1.6 and is corrected in 1.6.2.

Sheepbao
Translated 7 days ago

0 Person Top

top translation of good Oh!

Other translation versions (1)
Loading ...

http. Listenandserve Problem

Unfortunately, http. Listenandserve, http. Convenient functions such as LISTENANDSERVETLS and Http.serveare, which pass through http.server, are not suitable for external publishing network services.
because these functions default turns off the time-out setting and cannot be set manually. With these functions, the connection is quickly leaked, and then the file descriptor is exhausted. I have made at least 6 such mistakes in this regard.
for this, you should use the http.server! When creating an Http.server instance, call the appropriate method to specify ReadTimeout (read time-out time) and WriteTimeout (write time-out time), there are some cases below.

about Flow

The annoying thing is the inability to access objects under the Net.conn package from Serverhttp, so a server that wants to respond to a stream must de-writetimeout settings (that's why the default value is 0). Because access to net is not available. Conn package, you cannot call Setwritedeadline before each write operation to set a reasonable idle time-out.

Imqipan
Translated 7 days ago

0 Human Top

top   Good translation!

Similarly, due to the inability to confirm Responsewriter . Close supports concurrent write operations, so responsewriter.write can cause blocking and cannot be canceled.

(Translator Note: in Go 1.6.2, the interface Responsewriter definition has no Close method and needs to be implemented in the interface implementation itself.) Speculation is that the author implemented the method in development)

Unfortunately, this means that the streaming media server will not be able to effectively guarantee its own efficiency and stability when confronted with a low-speed client.

I have submitted some suggestions and I look forward to some feedback.

client timeout

Client timeouts, depending on your decision, can be simple or complex. But it is also important to prevent resources from leaking and blocking. The simplest way to use timeouts for

is HTTP. Client. It covers the entire interaction process, from initiating the connection to receiving the response message end.

c := &http. Client{      timeout: 15 * time. Second,}resp, err := c.get ("https://blog.filippo.io/") 

is similar to the server-side situation, using HTTP. Get package-level easy-to-use functions when creating clients, you cannot set timeouts. Application in an open network environment, there is a great risk.

caotj72
Translated 6 days ago

0 Human Top

top   Good translation!

There are other ways to get more granular time-out control:

    • Net. Dialer.timeout limit the time it takes to create a TCP connection (if a new link is required)

    • http. Transport.tlshandshaketimeout Limit the time the TLS handshake is used

    • http. Transport.responseheadertimeout limit the time it takes to read a response message header

    • http. Transport.expectcontinuetimeout restricts the time that the client waits to receive a go-ahead response message after sending an HTTP header containing: 100-continue. In 1.6, this setting is not valid for HTTP/2. (A specific package defaulttransport is provided in the 1.6.2)

c := &http. client{      transport: &transport{         Dial:  (&net. Dialer{                timeout :    30 * time. second,                 Keepalive: 30 * time. second,        }). Dial,        tlshandshaketimeout:   10 * time . Second,        responseheadertimeout: 10 * time. Second,        expectcontinuetimeout: 1 * time. second,    }} 

As far as I know, there is no mechanism to limit the time it takes to send requests. The current solution is to pass time after the client method returns. Timer to manually control when the request information is read (see "How to cancel a request" below).

Finally, in the new version 1.7, Http.Transport.IdleConnTimeout is provided. It is used to control the retention time of an idle connection in the connection pool, regardless of the stage at which a client request is blocked.

Note that the client will use the default redirection mechanism. Because of HTTP. Transport is an underlying system mechanism, without the redirection concept, so http. The client.timeout covers the time spent on redirection, and finer-timed timeouts can be tailored to different requests.

Caotj72
Translated 6 days ago

0 Person Top

top translation of good Oh!

Cancel and Context

Net/http provides two methods for revoking client requests: Request.cancel and the context provided in the new version 1.7.

The Request.cancel is an optional channel. When the request.timeout is triggered, the request.cancel will be set and closed, causing the request to be interrupted (basically "undo" is the same mechanism, when writing this article, I found a 1.7 bug, all undo operation, will be as a timeout error returned).

We can use Request.cancel and time.timer to build a time-out more controllable client that can be used for streaming media. It can reset the deadline after successful response to some of the data in the genre (Body).

package mainimport  (       "io"      "Io/ioutil"      "Log"      "Net/http"      "Time") Func main ()  {      c := make (chan struct{})      Timer := time. Afterfunc (5*time. Second, func ()  {        close (c)     })         // serve 256 bytes every second.     req, err := http. Newrequest ("GET",  "http://httpbin.org/range/2048?duration=8&chunk_size=256",  nil)      if err != nil {        log. Fatal (Err)     }    req. Cancel = c    log. Println ("Sending request ...")     resp, err := http. Defaultclient.do (req)     if err != nil {         log. Fatal (Err)     }    defer resp. Body.close ()     log. Println ("Reading body ...")     for {         timer. Reset (2 * time. Second)                 //  try instead: timer. Reset (50 * time.millisecond)         _, err = io. Copyn (Ioutil. Discard, resp. body, 256)         if err == io. eof {            break         } else if err != nil { &Nbsp;          log. Fatal (Err)         }    }}

In the above example, we set a 5-second timeout in the request phase. But read the response message phase, we need to read 8 times, at least 8 seconds. For each read operation, set a timeout of 2 seconds. With this mechanism, we can gain unrestricted access to streaming media without worrying about the risk of blocking. If we do not read any data within 2 seconds, Io. Copyn will return an error message: Net/http:request canceled.

A new context package has been added to the 1.7 version of the standard library. About contexts, we have a lot of things to learn. Based on the gist of this article, the first thing you should know is that contexts will replace request.cancel and no longer suggest (oppose) using Request.cancel.

Caotj72
Translated 6 days ago

0 Person Top

top translation of good Oh!

In order to use contexts to revoke a request, We need to create a new context and its Context.withcancel-based cancel () function, as well as create a request based on Request.withcontext. When we want to revoke a request, we actually revoke the corresponding context through the Cancel () function (replacing the original way of closing the Cancel channel):

ctx, cancel := context. Withcancel (context. TODO ())   timer := time. Afterfunc (5*time. Second, func ()  {      cancel ()}) req, err := http. Newrequest ("GET",  "http://httpbin.org/range/2048?duration=8&chunk_size=256",  nil)   if  err != nil {      log. Fatal (Err)}req = req. Withcontext (CTX) 

In the context (which we provide to the context. Withcancel) has been withdrawn, the contexts has a more advantageous position. We can send commands to the entire pipeline.

That's it. I hope you understand readdeadline more deeply than I do.

Caotj72
Translated 6 days ago

0 Person Top

top translation of good Oh!

All translations in this article are for learning and communication purposes only, please be sure to indicate the translator, source, and link to this article.
Our translation work in accordance with the CC agreement, if our work has violated your rights and interests, please contact us promptly
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.