16

現在、私は理解できない問題に直面しています。同時に複数のスレッドを介して(両方とも同じマシン上で)wcfサービスを呼び出すwcfクライアントがあります。時々、よく知られているSystem.ServiceModel.CommunicationExceptionに遭遇します

「xxxへのHTTP応答の受信中にエラーが発生しました。これは、HTTPプロトコルを使用していないサービスエンドポイントバインディングが原因である可能性があります。これは、サーバーによってHTTP要求コンテキストが中止されたことが原因である可能性もあります(サービスのシャットダウンが原因である可能性があります)。 )詳細については、サーバーログを参照してください。」

時々それは動作します。サービス呼び出しが成功した場合、それは完全にランダムに見えます。

リクエストは非常に小さく、(int、bool、enum)呼び出しにすぎません。リクエストには約が含まれています。MSSQLデータベースからの300〜500KBのレコード。

私はWebサイトで何百ものソリューションを検索し、タイムアウト値、バッファー値、クライアント側とサービス側の要求と応答のサイズ値を増やしました。[DataContract]属性と[DataMember]属性が欠落している場合は、それらを追加しました。それでも変化はありません。

非常に奇妙な動作を確認するために、完全なトレースをアクティブにしました。

クライアントからの呼び出しは、指定された例外を除いてローカルで停止しますが、サーバーはそれらを処理して応答を送信しますが、クライアントには到達しません。指定されたトレースで時間を確認します。クライアントは中止し、サーバーは続行します。

トレースでは、次のグラフのような重さがわかります。

ここに画像の説明を入力してください

どうか、誰かがこの無限の検索を止めるのを手伝ってもらえますか?

アップデート1:

クライアントサーバーの構成をアップロードしました。これが役立つかもしれません。

アップデート2:

Yahiaから提案されたように、ConnectionLimit(connection = 80)の構成パラメーターを含めました。現在、これで問題は解決したようですが、それでもエラーの再現を試みています。

アップデート3:

くそ。3時間後、同じ動作が再び見られます...別の提案がありました。ご覧のとおり、クライアントでは20スレッドから始まるquartz.netを使用しています。クォーツエンジンが実行するジョブは、当社のサービスに接続します。ここで、たとえば7つのスレッドが同時にサービスに接続しようとするとどうなるかを想像してみます。

アップデート4:

レジストリと設定でtcpパラメータを設定しました。再起動後、まったく変化はありませんでした:(

これらはレジストリの変更でした:

HKLM \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters-TcpNumConnections = 65534
HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters-MaxUserPort = 65534
HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet Settings-MaxConnectionsPer1_0Server = 20
HKLM \ Software \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTIONSPERSERVER-iexplore.exe = 20
HKLM \ Software \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTIONSPERSERVER-MyClientsExeName.exe = 20

アップデート5:

クライアントトレース サーバートレース

アップデート6:

[DataContract]
public class Currency
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Code { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public ForeignNoteDetails ForeignNoteDetails { get; set; }

    [DataMember]
    public CurrencyRates Rates { get; set; }

    [DataMember]
    public PreciousMetallDetails PreciousMetallDetails { get; set; }

    [DataMember]
    public CurrencyType Type { get; set; }
}

[DataContract]
public class ForeignNoteDetails
{
    [DataMember]
    public double CardholderBillingCurrencyCode { get; set; }

    [DataMember]
    public string Country { get; set; }

    [DataMember]
    public string CountryCode { get; set; }

    [DataMember]
    public int CurrencyUnit { get; set; }

    [DataMember]
    public List<string> Notes { get; set; }
}

[DataContract]
public class CurrencyRates
{
    [DataMember]
    public ExchangeRate PurchaseRate { get; set; }

    [DataMember]
    public ExchangeRate SellRate { get; set; }
}

[DataContract]
public class PreciousMetallDetails
{
    [DataMember]
    public string PreciousMetalType { get; set; }

    [DataMember]
    public double Fineness { get; set; }
}

サービスへの呼び出し:

        protected IEnumerable<Currency> GetCurrencyLevel(int id, bool netRate = true, RatesCalculationSource ratesSource = RatesCalculationSource.ReutersRates)
    {
        return this.calculationClient.GetCurrencyLevel(new RatesCalculationSetting() { CalculationLevelId = id, CalculateGrossRates = !netRate, Soruce = ratesSource });
    }

クライアントの作成:

protected ICalculationServiceClientService calculationClient = IoC.DependencyManager.Resolve<ICalculationServiceClientService>();

サービスへの別の呼び出し(動作中):

this.calculationClient.DistributeTradingOfficeRatesLevels(branchOfficeLevelId, tradingLevelId);

これが次のように定義されている場合

void DistributeTradingOfficeRatesLevels(int branchOfficeRatesLevelId, int tradingOfficeRatesLevelId)

アップデート7:

例外の詳細

4

5 に答える 5

4

HTTPプロトコルは、同じWebサーバーへの同時に2つの接続の制限を定義します...

httpを使用しているため、表示される動作はその制限に関連している可能性があります...

これにはレジストリ設定プログラム的な方法があります-おそらくクライアントでその制限を増やす必要があります(使用しているスレッドの数によって異なります)...

その他の関連する設定(クライアント側)は、ここにあります。

于 2013-03-21T14:45:31.783 に答える
4

さて、これが起こっていることです-あなたは数時間後に過熱している欠陥のあるネットワークカードを持っています、そしてそれが起こるときそれは短絡し始めます、その結果あなたのクライアント側はサーバーがシャットダウンされたと「考えます」。話の終わり-100%確実です。私の賞金はどこにありますか?

ところで:それは、特にラップトップを使用している場合、またはすでにラップトップに損傷が存在するために、デザインが悪いために過熱しています。

于 2013-04-04T14:32:38.583 に答える
2

2つのポイントを確認することをお勧めします:

  1. サーバーでのスロットル、

    動作name="Throttled"
    serviceThrottling
    maxConcurrentCalls = "1"
    maxConcurrentSessions = "1"
    maxConcurrentInstances = "1"

  2. 閉じられていないWCFセッション-使用後にすべてのセッション(クライアントプロキシ)を閉じますか?
    私の場合、すべてのタイムアウトを最大に拡大すると、X呼び出しの後で、サービスが「スタック」する状況が発生しました。タイムアウトを変更すると、あなたのような例外が発生しました。

数年前だったので、正確には覚えていませんでした。また、この(セッション)問題を解決するためにサービスインスタンスモードを変更する方法と理由が説明された良い記事を見つけたことを覚えています。

于 2013-03-28T21:17:05.843 に答える
2

WCF側でトレースを有効にしてみてください。サーバー側で何が起こっているかについて、詳細な情報が得られます。

また、クライアントが大量の要求を送信すると、WCFチャネルファクトリが突然閉じられることがあります。WCFで証明書認証を使用したときに、同様の問題に直面しました。その点で、この一時的なエラーを回避するためにRetryPolicyをデバイス化しました。このエラーが発生した場合は、例外をスローするのではなく、チャネルファクトリを中止し、再作成して再送信します。

 while (retryCount <= MAXRETRY)
            {
                try
                {
                    return _proxyService.GetData(); // _proxyService is WCF proxy class
                }
                catch (CommunicationException transientException)
                {
                     if (SLEEPINTERVAL> 0)
                    {
                        Thread.Sleep(SLEEPINTERVAL);
                    }
                    ((IClientChannel) _proxyService).Abort();
                    _proxyService = functionToCreateProxy();
                }

                retryCount++;
            }
于 2013-04-04T06:00:50.943 に答える
0

私も同じ問題を抱えていました。私の場合、それは私の間違いでした。スレッドを開始した後、channelFactory(プロキシ)を閉じました。

于 2015-10-19T00:44:35.053 に答える