ホームページ > バックエンド開発 > Golang > http `client.Do(...)` によって `response` が返される `ReadAll(response.Body)` を試行すると、Goroutine でリークが発生します。

http `client.Do(...)` によって `response` が返される `ReadAll(response.Body)` を試行すると、Goroutine でリークが発生します。

PHPz
リリース: 2024-02-09 23:06:18
転載
370 人が閲覧しました

当尝试 `ReadAll(response.Body)` 时,goroutine 泄漏,其中 `response` 由 http `client.Do(...)` 返回

#php エディター Baicao は、プログラミングの問題を解決する際によくある goroutine リークを発見しました。 `ReadAll(response.Body)` を使用しようとすると、返される `response` オブジェクトは、`http` パッケージの `client.Do(...)` メソッドによって返されます。ただし、この操作ではゴルーチンのリーク問題が発生する可能性があります。これを回避するには、http 応答を適切に処理するための対策を講じる必要があります。

質問の内容

この質問は、http メソッド呼び出し後に応答本文からすべてのバイトが読み取られるという、非常に一般的なシナリオからのものです。

https://github.com/uber-go/goleak の助けを借りて、興味深い goroutine リークを発見しました。

問題を実証するには、go test を使用して次のテスト コードを実行します。その結果、予期しない goroutine が見つかりました:

リーリー

完全なテスト出力:

リーリー

この問題の解決方法を知っている人はいますか?

###ありがとう!

解決策

Goでは、

http.ClientTransport(http.RoundTripperインターフェース)を使用します。 http.Transport がデフォルトの実装です。デフォルトの http.Transfer は、何らかの理由でアクティブまたはアイドル状態のままの接続を保持する接続プールを維持します。

基本的に必要なのは、

goleak.Verify を呼び出すときに、プール内に接続がないことを確認することだけです*

これは次の方法で実行できます:

  1. リクエストを実行する前に、すべての http クライアントのキープアライブを無効にします:
    クライアント := http.Client{トランスポート: &http.Transport{DisableKeepAlive: true}}
  2. goleak.Verify*: を呼び出す前にアイドル状態の接続を閉じてください。 client.CloseIdleConnections()
    // Go 1.12 以降で利用可能

以上がhttp `client.Do(...)` によって `response` が返される `ReadAll(response.Body)` を試行すると、Goroutine でリークが発生します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:stackoverflow.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート