この記事は機械翻訳のミラー記事です。元の記事にジャンプするにはこちらをクリックしてください。

眺める: 6079|答える: 4

[出典] HttpClientを誤って使うとソフトウェアが壊れる可能性があります

[リンクをコピー]
掲載地 2022/05/14 17:11:56 | | | |
私は何年もHttpClientを誤って使ってきましたが、ついに悪夢が訪れました。 私のウェブサイトは不安定で、顧客は非常に怒りましたが、簡単な修正でパフォーマンスが大幅に改善され、不安定さは解消されました。



同時に、ソケットの効率的な利用によってアプリケーションのパフォーマンスも向上しました。

マイクロサービスは扱いにくい問題です。 より多くのサービスが追加され、モノリシックなアプリケーションが分解されるにつれて、サービス間の通信経路が増えていく傾向があります。 多くの通信手段がありますが、HTTPが非常に人気があります。 もしマイクロサービスがC#や.NET言語で構築されているなら、すでにHttpClientを使っている可能性が高いです。


問題はここにあります

using 文は C# の機能で、ワンタイムオブジェクトを扱います。 使用ブロックが完了すると、ワンタイムオブジェクト(この場合はHttpClient)はスコープ外となり処分されます。 処分方法に連絡して、使用されている資源を片付けてください。 これは.NETで非常に典型的なパターンで、データベースからフローライターまであらゆる用途で使われています。 実際、外部リソースをクリーンアップする必要があるオブジェクトは、そのIDisposableインターフェースを使用します。

そして、それを使いながら包みたいと思うのは責められません。 まず、そうすることは良い慣習と考えられています。 実際、Microsoftの公式ドキュメントは以下の通りです:


一般的に、IDisposableオブジェクトを使用する場合は、使用文で宣言しインスタンス化されるべきです。
次に、あなたが見たかもしれないすべてのコードです...... HttpClientの冒頭には、使用文ブロックの使用を指示し、サイトの最新ドキュメントも含めて使うように ASP.NET。 同じことがインターネットの記事にも書かれています。

しかしHttpClientは異なります。 IDisposableインターフェースを実装していますが、実際には共有オブジェクトです。 つまり、裏ではリエントラントでスレッドセーフです。 HttpClientのインスタンスはアプリケーションのライフ期間中ずっと共有し、各実行ごとに新しいインスタンスを作成するのではなく、 HttpClient、なぜそうなのか見てみましょう。

自分の目で確かめてください

こちらはHttpClientを示す簡単なプログラムです:

この件は以下の方に向けられます。  http://aspnetmonsters.comリクエストを10件開いてGETを行ったら、ステータスコードを印刷するだけで動作していることを確認します。 出力は次のようになります:

待って、まだある!

すべての仕事も、すべてが世界にとって正しいものだと。 しかし、そうではありません。 netstatツールを取り出して、それを動かしているマシンのソケット状態を見ると、次のようになります:

C:\code\socket>NETSTAT.EXE
...
  プロトローカルアドレス 外国アドレス 状態
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 設立
...
変だな...... アプリケーションは終了しましたが、ASP.NET MonstersのウェブサイトをホストしているAzureマシンへの接続はまだ多く開いています。 彼らは入ったTIME_WAITステータスは、一方の接続(私たちの側)が閉じられていることを意味しますが、ネットワーク上のどこかで遅延している可能性のある他のパケットが届くかどうかまだ待っています。 TCP/IPの状態の図はこちらです:



Windowsはこの状態で240秒間接続を維持します(設定HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]で設定します)。 Windowsには新しいソケットを開く速度に制限があるため、接続プールが尽きると次のようなエラーが出ることがあります:

リモートサーバーに接続できません
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Googleで検索すると、接続タイムアウトを減らすための悪いアドバイスが出てきます。 実際、HttpClientや同様の構成のアプリケーションを正しく使うサーバー上で動作すると、タイムアウトを減らすことは他の悪影響をもたらすことがあります。 「正しい」とは何かを理解し、根本的な問題を解決し、機械レベルの変数をいじるのではなく、

直せ

HttpClientのインスタンスを共有しれば、ソケットの無駄を減らして再利用できます:

アプリケーション全体で共有インスタンスは1つだけであることに注意してください。 HttpClientは以前と同じように動作しています(実際、ソケットの再利用で少し高速になっています)。 ネットスタットは現在、以下のみを表示します:

TCP 10.211.55.6:12254 waws-prod-bay-017:http 確立済み
本番環境では、私のソケット数は平均約4000でピークは5000を超え、サーバーの利用可能なリソースを圧迫し、サービスがクラッシュします。 変更後、使用中のソケット数は平均4000以上から一貫して400未満、通常は100未満に減少しました。

これは、限られた数の修正証明を特定のマイクロサービスに展開した後に何が起こるかを示す監視ツールのチャートの一部です。




劇的だった。 もし負荷がかかる場合は、次の2点を念頭に置いておく必要があります。

HttpClientは静的にしましょう。
特定の動作(例えばサービスが故障するなど)を明確に求めている場合を除き、使用量を廃棄またはパッケージ化しないでください。 Httpクライアント


概要

数ヶ月間悩んでいたソケットの消耗問題は解消され、お客様はバーチャルパレードを楽しめます。 このミスがいかに目立たないか、過小評価できません。 これまでに実装されたオブジェクトやIDisposable、R#やCodeRushのような多くのリファクタリングツールは、そうでなければ警告を出してくれます。 この場合、HttpClientを処分するのは間違ったアプローチです。 HttpClientがIDisposableを実装し、悪い行動を助長するのは残念です

翻訳元:ハイパーリンクのログインが見えます。




先の:ASP.NET コアはIISのインプロセスモデルとアウトオブプロセスモデルをホストしています
次に:ASP.NET Core(XV)はHttpClientを使ってHTTPリクエストを送信します
 地主| 掲載地 2022/05/14 17:25:22 |
TCP TIME_WAITは通常のTCPプロトコル動作であり、最後のFIN-ACKが渡された後、クライアントは最大寿命(MSL)倍の時間が経過するまで待ち、リモートTCPが接続終了要求の確認応答を受け取ることを確認します。 デフォルトではMSLは2分です。 TIME_WAITに最大4分間滞在できる、いわゆる2回のMSLと呼ばれます。

https://docs.microsoft.com/en-us ... t-from-netstat.html
掲載地 2022/05/14 22:35:22 |
学ぶために
掲載地 2022/05/19 9:39:05 |
すべて中国語ですが、文につながっていると理解できません
 地主| 掲載地 2023/11/06 7:16:05 |
試験
免責事項:
Code Farmer Networkが発行するすべてのソフトウェア、プログラミング資料、記事は学習および研究目的のみを目的としています。 上記の内容は商業的または違法な目的で使用されてはならず、そうでなければ利用者はすべての結果を負うことになります。 このサイトの情報はインターネットからのものであり、著作権紛争はこのサイトとは関係ありません。 ダウンロード後24時間以内に上記の内容を完全にパソコンから削除してください。 もしこのプログラムを気に入ったら、正規のソフトウェアを支持し、登録を購入し、より良い本物のサービスを受けてください。 もし侵害があれば、メールでご連絡ください。

Mail To:help@itsvse.com