Azure Web ロールでの SignalR パフォーマンス カウンターの使用

作成者: Luke Latham

警告

このドキュメントは、SignalR の最新バージョン用ではありません。 SignalR の ASP.NET Coreを見てみましょう。

SignalR パフォーマンス カウンターは、Azure Web ロールでアプリのパフォーマンスを監視するために使用されます。 カウンターは Microsoft Azure Diagnosticsによってキャプチャされます。 スタンドアロンアプリまたはオンプレミス アプリに使用されるのと同じツール であるsignalr.exeを使用して、SignalR パフォーマンス カウンターを Azure にインストールします。 Azure ロールは一時的なものであるため、起動時に SignalR パフォーマンス カウンターをインストールして登録するようにアプリを構成します。

前提条件

  • Visual Studio 2015 または 2017
  • Microsoft Azure SDK for Visual Studio注: SDK をインストールした後、コンピューターを再起動します。
  • Microsoft Azure サブスクリプション: 無料の Azure 試用版アカウントにサインアップするには、「 Azure 無料試用版」を参照してください。

SignalR パフォーマンス カウンターを公開する Azure Web ロール アプリケーションの作成

  1. Visual Studio を開きます。

  2. Visual Studio で、 [ファイル]>[新規]>[プロジェクト] の順に選択します。

  3. [ 新しいプロジェクト ] ダイアログ ボックスで、左側の [Visual C#>Cloud ] カテゴリを選択し、 Azure Cloud Service テンプレートを選択します。 アプリに SignalRPerfCounters という名前を付け、[ OK] を選択します

    新しいクラウド アプリケーション

    Note

    クラウド テンプレート カテゴリまたは Azure Cloud Service テンプレートが表示されない場合は、Visual Studio 2017 用の Azure 開発ワークロードをインストールする必要があります。 [新しいプロジェクト] ダイアログの左下にある [Visual Studio インストーラーを開く] リンクを選択して、Visual Studio インストーラーを開きます。 Azure 開発ワークロードを選択し、[変更] を選択してワークロードのインストールを開始します。

    Visual Studio インストーラーでの Azure 開発ワークロード

  4. [ 新しい Microsoft Azure Cloud Service ] ダイアログで、[ ASP.NET Web ロール ] を選択し、ボタンを > 選択してロールをプロジェクトに追加します。 [OK] を選択します。

    ASP.NET Web ロールの追加

  5. [ 新しい ASP.NET Web アプリケーション - WebRole1 ] ダイアログで、 MVC テンプレートを選択し、[ OK] を選択します

    MVC と Web API の追加

  6. ソリューション エクスプローラーで、WebRole1下にある 診断.wadcfgx ファイルを開きます。

    ソリューション エクスプローラー 診断.wadcfgx

  7. ファイルの内容を次の構成に置き換え、ファイルを保存します。

    <?xml version="1.0" encoding="utf-8"?>
    <DiagnosticsConfiguration xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
      <PublicConfig>
        <WadCfg>
          <DiagnosticMonitorConfiguration overallQuotaInMB="4096">
            <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter="Error" />
            <Logs scheduledTransferPeriod="PT1M" scheduledTransferLogLevelFilter="Error" />
            <Directories scheduledTransferPeriod="PT1M">
              <IISLogs containerName ="wad-iis-logfiles" />
              <FailedRequestLogs containerName ="wad-failedrequestlogs" />
            </Directories>
            <WindowsEventLog scheduledTransferPeriod="PT1M">
              <DataSource name="Application!*[System[(Level=1 or Level=2 or Level=3)]]" />
              <DataSource name="Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]" />
            </WindowsEventLog>
            <CrashDumps containerName="wad-crashdumps" dumpType="Mini">
              <CrashDumpConfiguration processName="WaIISHost.exe" />
              <CrashDumpConfiguration processName="WaWorkerHost.exe" />
              <CrashDumpConfiguration processName="w3wp.exe" />
            </CrashDumps>
            <PerformanceCounters scheduledTransferPeriod="PT1M">
              <PerformanceCounterConfiguration counterSpecifier="\Memory\Available MBytes" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\ISAPI Extension Requests/sec" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\Bytes Total/Sec" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Requests/Sec" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Errors Total/Sec" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Queued" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Rejected" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\Processor(_Total)\% Processor Time" sampleRate="PT3M" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Memory(w3wp)\% Time in GC" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Exceptions(w3wp)\# of Exceps Thrown / sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR LocksAndThreads(w3wp)\# of current logical Threads" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR LocksAndThreads(w3wp)\# of current physical Threads" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR LocksAndThreads(w3wp)\Current Queue Length" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR LocksAndThreads(w3wp)\Contention Rate / sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Memory(w3wp)\# Bytes in all Heaps" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Memory(w3wp)\# GC Handles" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Memory(w3wp)\# of Pinned Objects" sampleRate="PT10S" />
    
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connections Connected" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connections Reconnected" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connections Disconnected" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connections Current" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connection Messages Received Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connection Messages Sent Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connection Messages Received/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Connection Messages Sent/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Messages Received Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Messages Received/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Message Bus Messages Received/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Messages Published Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Messages Published/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Subscribers Current" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Subscribers Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Subscribers/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Allocated Workers" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Busy Workers" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Message Bus Topics Current" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: All Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: All/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Hub Resolution Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Hub Resolution/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Hub Invocation Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Hub Invocation/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Tranport Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Errors: Transport/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Streams Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Streams Open" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Streams Buffering" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Errors Total" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Errors/Sec" sampleRate="PT10S" />
              <PerformanceCounterConfiguration counterSpecifier="\SignalR(*)\Scaleout Send Queue Length" sampleRate="PT10S" />
            </PerformanceCounters>
          </DiagnosticMonitorConfiguration>
        </WadCfg>
        <StorageAccount></StorageAccount>
      </PublicConfig>
      <PrivateConfig>
        <StorageAccount name="" key="" endpoint="" />
      </PrivateConfig>
      <IsEnabled>true</IsEnabled>
    </DiagnosticsConfiguration>
    
  8. [ツール>]NuGet パッケージ マネージャーからパッケージ マネージャーコンソールを開きます。 次のコマンドを入力して、最新バージョンの SignalR と SignalR ユーティリティ パッケージをインストールします。

    install-package microsoft.aspnet.signalr
    install-package microsoft.aspnet.signalr.utils
    
  9. SignalR パフォーマンス カウンターが起動時またはリサイクル時にロール インスタンスにインストールするようにアプリを構成します。 ソリューション エクスプローラーで、WebRole1 プロジェクトを右クリックし、[新しいフォルダー追加]> を選択します。 新しいフォルダーに Startup という名前 を付けます

    スタートアップ フォルダーの追加

  10. signalr.exe ファイル (Microsoft.AspNet.SignalR.Utils パッケージで追加) をプロジェクト フォルダー>/SignalRPerfCounters/packages/Microsoft.AspNet.SignalR.Utils から<コピーします。<前の手順で作成したスタートアップ フォルダーへのバージョン>/ツール。

  11. ソリューション エクスプローラーで、[スタートアップ] フォルダーを右クリックし、[既存の項目追加]> を選択します。 表示されるダイアログで、[ signalr.exe ] を選択し、[追加] を選択 します

    プロジェクトにsignalr.exeを追加する

  12. 作成した スタートアップ フォルダーを右クリックします。 [追加]>[新しい項目] の順に選択します。 [ 全般 ] ノードを選択し、[ テキスト ファイル] を選択し、新しい項目 に SignalRPerfCounterInstall.cmd という名前を付けます。 このコマンド ファイルは、SignalR パフォーマンス カウンターを Web ロールにインストールします。

    SignalR パフォーマンス カウンターのインストール バッチ ファイルを作成する

  13. Visual Studio で SignalRPerfCounterInstall.cmd ファイルが作成されると、メイン ウィンドウで自動的に開きます。 ファイルの内容を次のスクリプトに置き換え、ファイルを保存して閉じます。 このスクリプトは 、signalr.exe実行され、SignalR パフォーマンス カウンターがロール インスタンスに追加されます。

    SET SignalR_LogDir=%~dp0Log\
    MKDIR "%SignalR_LogDir%"
    cd %~dp0
    signalr.exe ipc >> "%SignalR_LogDir%SignalR_Log.txt" 2>&1
    net localgroup "Performance Monitor Users" "Network Service" /ADD >> "%SignalR_LogDir%NetworkAdd.txt" 2>&1
    
  14. ソリューション エクスプローラーでsignalr.exe ファイルを選択します。 ファイルの [プロパティ] で、[ コピー] を [出力ディレクトリ] に [ 常にコピー] に設定します。

    [コピー] を [出力ディレクトリ] に [常にコピー] に設定する

  15. SignalRPerfCounterInstall.cmd ファイルに対して前の手順を繰り返します。

  16. SignalRPerfCounterInstall.cmd ファイルを右クリックし、[ ファイルを開く] を選択します。 表示されるダイアログで、[ バイナリ エディター ] を選択し、[ OK] を選択します

    バイナリ エディターで開く

  17. バイナリ エディターで、ファイル内の先頭のバイトを選択し、削除します。 ファイルを保存して閉じます。

    先頭のバイトを削除する

  18. ServiceDefinition.csdef を開き、サービスの起動時に SignalrPerfCounterInstall.cmd ファイルを実行するスタートアップ タスクを追加します。

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceDefinition name="SignalRPerfCounters" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
      <WebRole name="WebRole1" vmsize="Small">
        <Startup>
          <Task commandLine="Startup\SignalRPerfCounterInstall.cmd" executionContext="elevated" taskType="background" />
        </Startup>
        <Sites>
          <Site name="Web">
            <Bindings>
              <Binding name="Endpoint1" endpointName="Endpoint1" />
            </Bindings>
          </Site>
        </Sites>
        <Endpoints>
          <InputEndpoint name="Endpoint1" protocol="http" port="80" />
        </Endpoints>
      </WebRole>
    </ServiceDefinition>
    
  19. ファイルの末尾から jQuery バンドル スクリプトを開 Views/Shared/_Layout.cshtml いて削除します。

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>
    
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
    </body>
    </html>
    
  20. サーバーで メソッドを継続的に呼び出す increment JavaScript クライアントを追加します。 内容を開 Views/Home/Index.cshtml き、次のコードに置き換えます。

    @{
        ViewBag.Title = "Home Page";
    }
    
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
    <script src="~/signalr/hubs" type="text/javascript"></script>
    
    <div id="body">
        <section class="featured">
            <div class="content-wrapper">
                <p>
                    Hello World!
                </p>
                <div style="font-size:large;">
                    My Counter: <span id="counter"></span>
                </div>
            </div>
        </section>
        <section class="content-wrapper main-content clear-fix"></section>
    </div>
    
    <script type="text/javascript">
      $(document).ready(function () {
        var hub = $.connection.myHub;
    
        hub.client.sendResult = function (x) {
          console.log('sendResult(' + x + ')');
          $("#counter").text(x);
          window.setTimeout(function () {
            hub.server.increment(x);
          }, 1000);
        };
    
        $.connection.hub.connected = function () {};
        $.connection.hub.disconnected = function () {};
    
        $.connection.hub.stateChanged(function (change) {
          console.log('new State' + change.newState);
          if (change.newState === $.signalR.connectionState.disconnected) {
            $.connection.hub.start();
          }
          if (change.newState === $.signalR.connectionState.reconnecting) {
            console.log('Re-connecting');
          } else if (change.newState === $.signalR.connectionState.connected) {
            console.log('The server is online');
          }
        });
    
        $.connection.hub.error(function (error) {
          console.log('error ' + error);
        });
        
        $.connection.hub.logging = true;
        
        $.connection.hub.reconnected(function () {
          console.log('Reconnected');
          hub.server.increment(0);
        });
    
        $.connection.hub.start().done(function () {
          console.log('hub started');
          hub.server.increment(0);
        });
      });
    </script>
    
  21. WebRole1 プロジェクトに Hubs という名前の新しいフォルダーを作成します。 ソリューション エクスプローラーHubs フォルダーを右クリックし、[新しい項目追加]> を選択します。 [ 新しい項目の追加 ] ダイアログ ボックスで、 Web>SignalR カテゴリを選択し、 SignalR Hub Class (v2) 項目テンプレートを選択します。 新しいハブに MyHub.cs という名前をけ、[追加] を選択します。

    [新しい項目の追加] ダイアログの [Hubs] フォルダーへの SignalR Hub クラスの追加

  22. MyHub.cs は、メイン ウィンドウで自動的に開きます。 内容を次のコードに置き換え、ファイルを保存して閉じます。

    using System.Threading.Tasks;
    using Microsoft.AspNet.SignalR;
    
    namespace WebRole1.Hubs
    {
        public class MyHub : Hub
        {
            public async Task Increment(int x)
            {
                await this.Clients.Caller.sendResult(x + 1);
            }
        }
    }
    
  23. Crank.exe は、SignalR コードベースで提供される接続密度テスト ツールです。 クランクには永続的な接続が必要なので、テスト時に使用するためにサイトに追加します。 PersistentConnections という名前の新しいフォルダーを WebRole1 プロジェクトに追加します。 このフォルダーを右クリックし、[クラス追加]> を選択します。 新しいクラス ファイルに MyPersistentConnections.cs という名前を 付け、[追加] を選択します。

  24. Visual Studio によって、メイン ウィンドウに MyPersistentConnections.cs ファイルが開きます。 内容を次のコードに置き換え、ファイルを保存して閉じます。

    using System.Threading.Tasks;
    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Infrastructure;
    
    namespace WebRole1.PersistentConnections
    {
        public class MyPersistentConnection : PersistentConnection
        {
            protected override Task OnReceived(IRequest request, string connectionId, string data)
            {
                //Return data to calling user
                return Connection.Send(connectionId, data);        
            }
        }
    }
    
  25. クラスを Startup 使用すると、SignalR オブジェクトは OWIN の起動時に開始されます。 Startup.cs を開くか作成し、内容を次のコードに置き換えます。

    using Microsoft.Owin;
    using Owin;
    using WebRole1.PersistentConnections;
    
    // Marks this class for automatic OWIN startup
    [assembly: OwinStartup(typeof(WebRole1.Startup))]
    namespace WebRole1
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuth(app);
                // Only needed if "No Authentication" was not selected for the project
                app.MapSignalR();
                app.MapSignalR<MyPersistentConnection>("/echo");
            }
        }
    }
    

    上記のコードでは、 属性によってこのクラスが OwinStartup OWIN を開始するようにマークされています。 メソッドは Configuration SignalR を開始します。

  26. F5 キーを押して、Microsoft Azure Emulatorでアプリケーションをテストします。

    Note

    MapSignalRFileLoadException が発生した場合は、web.configのバインド リダイレクトを次のように変更します。

    <dependentAssembly>
      <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.0.0" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.0.0" />
    </dependentAssembly>
    
  27. 約 1 分待ちます。 Visual Studio で [クラウド エクスプローラー ツール] ウィンドウを開き ([クラウド エクスプローラーの表示>] ) パス(Local)/Storage Accounts/(Development)/Tablesを展開します。 WADPerformanceCountersTable をダブルクリックします。 テーブル データに SignalR カウンターが表示されます。 テーブルが表示されない場合は、Azure Storage の資格情報を再入力する必要がある場合があります。 [更新] ボタンを選択して Cloud エクスプローラーのテーブルを表示するか、開いているテーブル ウィンドウで [更新] ボタンを選択してテーブル内のデータを表示する必要があります。

    Visual Studio Cloud エクスプローラーで WAD パフォーマンス カウンター テーブルを選択する

    WAD パフォーマンス カウンター テーブルで収集されたカウンターの表示

  28. クラウドでアプリケーションをテストするには、 ServiceConfiguration.Cloud.cscfg ファイルを 更新し、 を Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString 有効な Azure Storage アカウント接続文字列に設定します。

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceConfiguration serviceName="SignalRPerfCounters" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2015-04.2.6">
      <Role name="WebRole1">
        <Instances count="1" />
        <ConfigurationSettings>
          <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=&lt;account-name&gt;;AccountKey=&lt;account-key&gt;" />
        </ConfigurationSettings>
      </Role>
    </ServiceConfiguration>
    
  29. アプリケーションを Azure サブスクリプションにデプロイします。 Azure にアプリケーションをデプロイする方法の詳細については、「 クラウド サービスを作成してデプロイする方法」を参照してください。

  30. 数分待ちます。 [クラウド エクスプローラー] で、上記で構成したストレージ アカウントを見つけて、その中のテーブルをWADPerformanceCountersTable見つけます。 テーブル データに SignalR カウンターが表示されます。 テーブルが表示されない場合は、Azure Storage の資格情報を再入力する必要がある場合があります。 [更新] ボタンを選択して Cloud エクスプローラーでテーブルを表示するか、開いているテーブル ウィンドウの [更新] ボタンを選択してテーブル内のデータを表示する必要がある場合があります。

このチュートリアルで使用される元のコンテンツの Martin Richard に感謝します。