11

WCF を使用する VB .NET アプリケーションがあります。コード内のすべてのクライアント タイムアウトを設定しました。

    Dim oMastSrv As MastSvc.IclsIOXferClient = Nothing

    Dim binding As New ServiceModel.NetTcpBinding("NetTcpBinding_IclsIOXfer")
    Dim intTimeout As Integer = 2500
    binding.SendTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.ReceiveTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.OpenTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.CloseTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    Dim address As New ServiceModel.EndpointAddress("net.tcp://" & GetSrvIP(intSrvID) & ":30000/MyMastSvc")

    oMastSrv = New MastSvc.IclsIOXferClient(binding, address)
    Try
        oMastSrv.ServiceConnect( ... )
        oMastSrv.InnerChannel.OperationTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    Catch ex As Exception
        ...
    End Try

ただし、接続しているサービスがクラッシュすると、指定した 2.5 ではなく、Endpoint Not Found 例外がスローされるまでに 20 秒以上かかります。これは私のロード バランシングを本当にいじっています。サービスが 2.5 秒以内になくなったことを知る必要があります。この例外を目的の期間内にスローする方法はありますか?

ところで、例外は次のようになります。

net.tcp://192.168.227.130:30000/MXIOXfer に接続できませんでした。接続の試行は、00:00:02.4209684 の期間継続しました。TCP エラー コード 10060: 接続先が一定時間後に適切に応答しなかったため、接続の試行に失敗したか、接続されたホストが 192.168.227.130:30000 に応答しなかったために確立された接続が失敗しました。

しかし、実際には 20 秒以上かかります。WCF トレースをオンにすると、例外の直前に TCP 操作が失敗したという警告が表示され、REAL 時間が表示されます。

net.tcp://192.168.227.130:30000/MXIOXfer に接続できませんでした。接続の試行は、00:00:21.0314092 の期間継続しました。TCP エラー コード 10060: 接続先が一定時間後に適切に応答しなかったため、接続の試行に失敗したか、接続されたホストが 192.168.227.130:30000 に応答しなかったために確立された接続が失敗しました。

違いがある場合、サービスへのすべての通信は別のスレッドで行われます。

編集:

このスレッドは、ソケットのタイムアウトがオペレーティング システムによって設定されていることを示しているようです。そのようなもののためのレジストリ設定はありますか?

4

2 に答える 2

3

私と eol が参照した SO と MSDN のソーシャル スレッドで見つかった詳細を組み合わせて、次のレジストリ設定にたどり着きました。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces{xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx}\TcpInitialRTT

値のタイプ: REG_DWORD - 数値

有効な範囲: 0 ~ 0xFFFF

デフォルト: 3 秒

説明: このパラメーターは、TCP 接続要求に使用される初期タイムアウトと、インターフェイスごとの初期データ再送信を制御します。指数バックオフが使用されるため、このパラメーターを使用してチューニングする場合は注意してください。この値を 3 より大きい値に設定すると、存在しないアドレスへのタイムアウトが大幅に長くなります。

.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces{xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx}\TcpMaxConnectRetransmissions

値のタイプ: REG_DWORD - 数値

有効な範囲: 0 ~ 255 (10 進数)

デフォルト: 2

説明: このパラメーターは、試行を中止する前に、TCP が接続要求 (SYN) を再送信する回数を決定します。再送信のタイムアウトは、特定の接続試行で連続する再送信ごとに 2 倍になります。初期タイムアウトは、TcpInitialRtt レジストリ値によって制御されます。

.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces{xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx}\TcpMaxDataRetransmissions

値のタイプ: REG_DWORD - 数値

有効な範囲: 0 ~ 0xFFFFFFFF

デフォルト: 5

説明: このパラメータは、TCP が接続を中止する前に個々のデータ セグメント (接続要求セグメントではない) を再送信する回数を制御します。再送信タイムアウトは、接続で連続して再送信されるたびに 2 倍になります。応答が再開されるとリセットされます。再送信タイムアウト (RTO) の値は、各接続で測定された履歴ラウンドトリップ時間 (Smoothed Round Trip Time、または SRTT) を使用して動的に調整されます。新しい接続で開始する RTO は、TcpInitialRtt レジストリ値によって制御されます。

失敗した接続のタイムアウト値は再試行ごとに 2 倍になるため、デフォルト値では、最初の試行は 3 秒で失敗し、2 回目は 6 秒で失敗し、3 回目と最後の試行は 12 秒で失敗し、合計 21 秒になります。ところで、TcpMaxDataRetransmissionsキーはこれとは何の関係もありません。完全性と後で来る人のために含めます。

これらの値はデフォルトでは存在しないため、変更するには追加する必要があります。これを行うインターフェイスを特定するのは簡単です。各インターフェイスには、現在の IP アドレスを含むキーがあります。(localhost 用もあります。) 私の場合、 VM インターフェイスでTcpMaxConnectRetransmissionsをゼロ (0) に設定するだけで、VM インターフェイスのソケット タイムアウトがデフォルトで 3 秒になり、動作するには 2.5 に十分近くなります。現在、WCF サービスがクラッシュしたときに負荷分散が機能します。

于 2012-08-15T13:24:50.147 に答える
1

この投稿は同じ問題について話していると思います: wcf channelfactory と opentimeout

問題は、基になるソケットのデフォルトのタイムアウトが 20 秒程度であり、WCF がオーバーライドしていないことです。非同期で開くことによって独自のタイムアウトを実装する方法については、最後の回答を確認してください。

于 2012-08-14T12:59:46.670 に答える