본문 바로가기
네트워크

Go 에서 HTTP client 를 작성할 때 주의할 점

by hayz 2024. 4. 12.

go 에서 제공하는 http 관련 패키지(net/http)를 이용해서 코드를 작성할 때 주의해야할 점이 있다. 

 

go 에서는 아래와 같이 client 객체가 구성되어 있고, 기본으로 사용되는 DefaultClient 는 단순히 해당 객체를 반환한 값이다. 

type Client struct {
	// Transport specifies the mechanism by which individual
	// HTTP requests are made.
	// If nil, DefaultTransport is used.
	Transport RoundTripper

	// CheckRedirect specifies the policy for handling redirects.
	// If CheckRedirect is not nil, the client calls it before
	// following an HTTP redirect. The arguments req and via are
	// the upcoming request and the requests made already, oldest
	// first. If CheckRedirect returns an error, the Client's Get
	// method returns both the previous Response (with its Body
	// closed) and CheckRedirect's error (wrapped in a url.Error)
	// instead of issuing the Request req.
	// As a special case, if CheckRedirect returns ErrUseLastResponse,
	// then the most recent response is returned with its body
	// unclosed, along with a nil error.
	//
	// If CheckRedirect is nil, the Client uses its default policy,
	// which is to stop after 10 consecutive requests.
	CheckRedirect func(req *Request, via []*Request) error

	// Jar specifies the cookie jar.
	//
	// The Jar is used to insert relevant cookies into every
	// outbound Request and is updated with the cookie values
	// of every inbound Response. The Jar is consulted for every
	// redirect that the Client follows.
	//
	// If Jar is nil, cookies are only sent if they are explicitly
	// set on the Request.
	Jar CookieJar

	// Timeout specifies a time limit for requests made by this
	// Client. The timeout includes connection time, any
	// redirects, and reading the response body. The timer remains
	// running after Get, Head, Post, or Do return and will
	// interrupt reading of the Response.Body.
	//
	// A Timeout of zero means no timeout.
	//
	// The Client cancels requests to the underlying Transport
	// as if the Request's Context ended.
	//
	// For compatibility, the Client will also use the deprecated
	// CancelRequest method on Transport if found. New
	// RoundTripper implementations should use the Request's Context
	// for cancellation instead of implementing CancelRequest.
	Timeout time.Duration
}

var DefaultClient = &Client{}

 

 

주의할 점 : default client 의 Timeout

위에서 보이는 것처럼 DefaultClient 를 사용하면 빈 client 가 반환되고, 그 내부의 Timeout 필드가 0 으로 설정되어 들어가게 된다. 그런데, Timeout 의 0 은 no limit 을 의미하기 때문에 해당 client 를 사용할 경우 응답이 지연될시 무한정으로 기다리게 되는 이슈가 발생한다. 

왜 무한정 기다리면 안될까? 

서비스를 제공할 때 http 통신에 의해 응답을 기다리느라 다른 작업이 밀리게 될 수도 있고, 빠른 대응을 할 수 없기 때문에 일정 시간 이상 지나면 Timeout 확인을 해주는 것이 좋다. 

 

DefaultClient 에서 Timeout 값을 설정하기 위해서는 아래 처럼 설정해 주는 것으로 해결할 수 있다. 

var client = httplib.Client{
	Timeout: HttpTimeout * time.Second,
}

 

 

Reference. 

https://medium.com/@nate510/don-t-use-go-s-default-http-client-4804cb19f779

댓글