转到http客户端超时与上下文超时

问题描述

http.Client中设置的超时与请求上下文中设置的超时有什么区别?

我已经看到了两种在http客户端中设置超时的方法

第一:

ctx,cancel := context.WithTimeout(context.Background(),2*time.Second)
defer cancel()
req,err := http.NewRequestWithContext(ctx,http.MethodGet,"http://localhost:8080",nil)

第二:

client := http.Client{
    Timeout: 2 * time.Second,}
resp,err := client.Do(req)
if err != nil {
    panic(err)
}

什么时候可以使用另一个

解决方法

通常,当我们只想为http请求设置超时时,我们将使用此方法

client := http.Client{
    Timeout: 2 * time.Second,}
resp,err := client.Do(req)
if err != nil {
    panic(err)
}

我认为问题是我们何时应该使用上下文,如果您去查阅文档,会发现

Package上下文定义了Context类型,其中包含截止日期, API中的取消信号和其他请求范围的值 边界和过程之间。

因此,假设您有一个需要在一段时间内响应的API,并且需要一种方法来跟踪它创建的所有go例程,并希望同时发出信号以停止它们;在这种情况下,使用上下文并将其传递给由一个API调用创建的所有go例程是很有意义的,并且真正容易知道上下文何时过期以及何时每个人都需要停止工作。

尽管您可以执行http请求,但是创建对特定请求明确的上下文并没有多大意义,除非可以说您的请求在goroutine中运行,并且您需要传递一个cancel信号。执行后收到的其他输入。

理想情况下,在大多数情况下,上下文用于确定需要发出信号的请求/ goroutine链的范围。

您应该阅读此内容,以更清楚地了解何时使用上下文 https://blog.golang.org/context

,

由于超时,两者都可以达到终止请求的目的。

但是使用上下文是此任务的首选方法。在将上下文添加到Go中之前,该字段存在超时。您必须在创建请求时选择一个超时,因为该请求将选择要应用的较小超时,从而使其他时间无用。在这种情况下,首选方法是使用上下文超时,因为您可以对其进行更多控制,如果要通过逻辑决策取消请求,则可以在不指定超时的情况下使用cancel。使用上下文,您还可以通过它传递描述请求范围值的任何值。

使用上下文是特定于请求的,而使用客户端超时可能会应用到客户端拥有的Do方法的所有请求传递。如果要针对每个请求专门设置截止时间/超时,请使用上下文,否则,如果每个出站请求都希望1个超时,则使用客户端超时就足够了。

您也可以在这里Specify timeout when tracing HTTP request in Go

进行阅读。