Nice programing

응답을 닫지 않으면 어떻게 될 수 있습니까?

nicepro 2020. 12. 12. 12:26
반응형

응답을 닫지 않으면 어떻게 될 수 있습니까?


golang에서 몇 가지 http 응답이 있으며 때때로 전화하는 것을 잊습니다.

resp.Body.Close()

이 경우 어떻게됩니까? 메모리 누수가 있습니까? 또한 defer resp.Body.Close()응답 대상을받은 직후 에 넣어도 안전한 가요?

client := http.DefaultClient
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
    return nil, err
}

어떤이 오류가 발생, 수있는 경우 resp또는 resp.Body전무 할?


이 경우 어떻게됩니까? 메모리 누수가 있습니까?

리소스 누출입니다. 연결은 다시 사용되지 않으며 열린 상태로 유지 될 수 있으며이 경우 파일 설명자가 해제되지 않습니다.

또한 응답 객체를 얻은 직후 defer resp.Body.Close ()를 넣어도 안전합니까?

아니오, 문서에 제공된 예를 따르고 오류를 확인한 후 즉시 닫으십시오.

client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
    return nil, err
}
defer resp.Body.Close()

로부터 http.Client문서 :

반환 된 오류가 nil이면 응답에는 사용자가 닫을 것으로 예상되는 nil이 아닌 본문이 포함됩니다. 본문이 EOF로 읽혀지고 닫혀 있지 않으면 클라이언트의 기본 RoundTripper (일반적으로 전송)가 후속 "연결 유지"요청을 위해 서버에 대한 영구 TCP 연결을 재사용하지 못할 수 있습니다.


만약이 Response.Body폐쇄되지 않습니다 Close()FD와 관련된 자원이 해제되지 않습니다보다 방법. 이것은 리소스 누출입니다.

폐쇄 Response.Body

에서 응답 소스 :

Body를 닫는 것은 호출자의 책임입니다.

따라서 개체에 바인딩 된 종료자가 없으며 명시 적으로 닫아야합니다.

오류 처리 및 지연된 정리

오류시 모든 응답을 무시할 수 있습니다. nil이 아닌 오류가있는 nil이 아닌 응답은 CheckRedirect가 실패한 경우에만 발생하며 반환 된 Response.Body는 이미 닫혀 있습니다.

resp, err := http.Get("http://example.com/")
if err != nil {
    // Handle error if error is non-nil
}
defer resp.Body.Close() // Close body only if response non-nil

https://golang.org/src/net/http/client.go를 참조 하십시오.
"err이 nil이면 resp는 항상 nil이 아닌 resp.Body를 포함합니다."

그러나 그들은 err! = nil, resp가 항상 nil이라고 말하지 않습니다. 그들은 계속해서
"resp.Body가 닫히지 않으면 클라이언트의 기본 RoundTripper (일반적으로 전송)가 후속"연결 유지 "요청을 위해 서버에 대한 지속적인 TCP 연결을 재사용하지 못할 수 있습니다."라고 말합니다.

그래서 나는 일반적으로 다음과 같은 문제를 해결했습니다.

client := http.DefaultClient
resp, err := client.Do(req)
if resp != nil {
   defer resp.Body.Close()
}
if err != nil {
    return nil, err 
}

처음에는 위에서 언급 한 것처럼 디스크립터가 닫히지 않습니다.

And what's more, golang will cache the connection (using persistConn struct to wrap) for reusing it, if DisableKeepAlives is false.

In golang after use client.Do method, go will run goroutine readLoop method as one of the step.

So in golang http transport.go, a pconn(persistConn struct) won't be put into idleConn channel until the req canceled in the readLoop method, and also this goroutine(readLoop method) will be blocked until the req canceled.

Here is the code showing it.

If you want to know more, you need to see the readLoop method.

참고URL : https://stackoverflow.com/questions/33238518/what-could-happen-if-i-dont-close-response-body-in-golang

반응형