3

私の手には興味深い状況があります。数年前から、ロギングに使用するネットワーク上のIISボックスで実行されるWCFサービスがあります。アプリケーションはbasicHttpBindingを使用してログメッセージを送信し、データベースに記録します。他のすべてのアプリケーションからのログのほとんどは、操作ごとに数十ログに制限されています。最近、このロギングサービスを使用するために別のアプリケーションを移植しました。このアプリケーションは、ログサービスの他のどのクライアントよりもかなり積極的にログを記録します。コース中に100,000を超えるメッセージをログに記録できる操作があります(これは、CSVファイルを介して100,000レコードをインポートするためのものです)。

これをより効率的に実行する方法を見つけるために、アプリケーションがログサービスと直接通信するのではなく、MSMQを使用してログ要求をキューに入れ、サービスに転送することをお勧めします(要求パフォーマンスのために別のスレッド)。このようにして、ログの書き込み中にアプリケーションがブロックされることはありません。このMSMQソリューションの概念実証をローカルマシンに実装しましたが、これまでMSMQを使用したことがなく、技術的にその場所が何であるかを学習しているだけなので、多くの質問といくつかの回答があります。 。私が書いたこの概念実証をより適切にデバッグできるように、誰かがMSMQの動作に関する簡潔な情報を教えてくれることを願っています。

MSMQを実装した後に表示される内容:

  • ログをMSMQに送信する私のアプリケーションは、(ログがコミットされるのを待つのではなく)ほぼ即座に返されます。これは私が望んでいることです。
  • 1000ログをMSMQアプリケーションに30秒未満で送信しましたが、1000ログすべてがデータベースに到達するまでに数分かかります。私のキューでは、ログリクエストを保留しているときに何らかのスロットリングが有効になっているように見えますが、それを確認する方法/場所がわかりません。
  • MSMQサービスからログを受信するサーバーでnet.tcpを使用すると、大量のサービスタイムアウトエラーが発生し、ログの90%(またはそれ以上)だけがデータベースに到達しますが、basicHttpBindingを使用すると確実に機能します。

これが私のMSMQサービスのコードです:

public void QueueLog(Log log)
{
    try
    {
        ServiceClient writeLog = getLoggingService();

        string exceptionText = log.Exception == null ? string.Empty : log.Exception.ToString();
        writeLog.WriteCompatibleLog(log.LoggerName, (LoggingService.Logging.LogType)log.LogType, exceptionText, log.Message, log.ApplicationName, Utility.GetAssemblyVersion(Assembly.GetCallingAssembly()),
            Utility.GetFirstIPAddress(), Utility.GetHostName(), log.Category);
    }
    catch (Exception ex)
    {
        Debug.WriteLine("LoggingServiceWrapper.DotNet Error\n\n" + ex.GetBaseException().Message + "\n\n" + ex.GetBaseException().StackTrace);
    }
}

private ServiceClient getLoggingService()
{
    return new ServiceClient(new BasicHttpBinding(), new EndpointAddress("http://MyServer/Service.svc"));

}

これがMSMQサービスを作成する私のコードです

if (!MessageQueue.Exists(Properties.Settings.Default.QueueName))
{
    MessageQueue.Create(Properties.Settings.Default.QueueName, true);
}

ServiceHost serviceHost = new ServiceHost(typeof(LoggingServiceQueue.LoggingServiceQueue), new Uri(Properties.Settings.Default.Address));
{
    serviceHost.Open();

    Console.ReadLine();

    serviceHost.Close();
}

MSMQサービスを呼び出すために使用するアプリケーションのコードは次のとおりです。

LoggingServiceQueueClient client = new LoggingServiceQueueClient(new NetMsmqBinding(NetMsmqSecurityMode.None), new EndpointAddress("net.msmq://localhost/private/Logging"));

client.QueueLog(new LoggingServiceQueue.Log
{
    LoggerName = loggerName,
    LogType = (LoggingServiceQueue.LogType)logType,
    ApplicationName = applicationName,
    Category = category,
    Exception = exception,
    Message = message,
    SourceHostName = Utility.GetHostName(),
    SourceIp = Utility.GetFirstIPAddress(),
    Version = Utility.GetAssemblyVersion(callingAssembly)
});

私は誰かが提供できるどんな助けにも感謝します。MSMQを使用して利用できる機能のセットが正確にわからなくなっています。私はグーグルを介して6時間ほどの研究をしました。私が見つけたほとんどのドキュメントはかなり古く(2007年)、読むのが難しいです。おそらく彼らは、私がこの主題についてある程度の知識を持っていることを期待しています。

4

1 に答える 1

1

表示されているのは(WCFでnet.msmqバインディングを使用している場合)、発生するように設計されているものです。

ストアアンドフォワード機能としてのMSMQは、ネットワークまたは処理帯域幅のいずれかが使用可能になるまで、送信側クライアントと受信側サーバーのキューにメッセージを格納します。これは、プロセスを非同期にすることで、クライアントの負荷を軽減します(これまで見てきたように)。

パフォーマンスモニターを使用してキューのステータスを表示できます。アウトバウンドキュー(クライアント)のメッセージ数とサーバーキューは、パフォーマンスカウンターにリアルタイムで書き込まれ、表示および/またはログに記録できます。

パフォーマンスが最適ではない場合は、WCFスロットリング設定を変更して、サービスの動作でより多くの同時接続を許可することができます。

例えば

<serviceThrottling
         maxConcurrentCalls="20"
         maxConcurrentSessions="20"
         maxConcurrentInstances="20"
       />

于 2011-05-16T22:12:39.243 に答える