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 ロール アプリケーションの作成
Visual Studio を開きます。
Visual Studio で、 [ファイル]>[新規]>[プロジェクト] の順に選択します。
[ 新しいプロジェクト ] ダイアログ ボックスで、左側の [Visual C#>Cloud ] カテゴリを選択し、 Azure Cloud Service テンプレートを選択します。 アプリに SignalRPerfCounters という名前を付け、[ OK] を選択します。
Note
クラウド テンプレート カテゴリまたは Azure Cloud Service テンプレートが表示されない場合は、Visual Studio 2017 用の Azure 開発ワークロードをインストールする必要があります。 [新しいプロジェクト] ダイアログの左下にある [Visual Studio インストーラーを開く] リンクを選択して、Visual Studio インストーラーを開きます。 Azure 開発ワークロードを選択し、[変更] を選択してワークロードのインストールを開始します。
[ 新しい Microsoft Azure Cloud Service ] ダイアログで、[ ASP.NET Web ロール ] を選択し、ボタンを > 選択してロールをプロジェクトに追加します。 [OK] を選択します。
[ 新しい ASP.NET Web アプリケーション - WebRole1 ] ダイアログで、 MVC テンプレートを選択し、[ OK] を選択します。
ソリューション エクスプローラーで、WebRole1 の下にある 診断.wadcfgx ファイルを開きます。
ファイルの内容を次の構成に置き換え、ファイルを保存します。
<?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>
[ツール>]NuGet パッケージ マネージャーからパッケージ マネージャーコンソールを開きます。 次のコマンドを入力して、最新バージョンの SignalR と SignalR ユーティリティ パッケージをインストールします。
install-package microsoft.aspnet.signalr install-package microsoft.aspnet.signalr.utils
SignalR パフォーマンス カウンターが起動時またはリサイクル時にロール インスタンスにインストールするようにアプリを構成します。 ソリューション エクスプローラーで、WebRole1 プロジェクトを右クリックし、[新しいフォルダーの追加]> を選択します。 新しいフォルダーに Startup という名前 を付けます。
signalr.exe ファイル (Microsoft.AspNet.SignalR.Utils パッケージで追加) をプロジェクト フォルダー>/SignalRPerfCounters/packages/Microsoft.AspNet.SignalR.Utils から<コピーします。<前の手順で作成したスタートアップ フォルダーへのバージョン>/ツール。
ソリューション エクスプローラーで、[スタートアップ] フォルダーを右クリックし、[既存の項目の追加]> を選択します。 表示されるダイアログで、[ signalr.exe ] を選択し、[追加] を選択 します。
作成した スタートアップ フォルダーを右クリックします。 [追加]>[新しい項目] の順に選択します。 [ 全般 ] ノードを選択し、[ テキスト ファイル] を選択し、新しい項目 に SignalRPerfCounterInstall.cmd という名前を付けます。 このコマンド ファイルは、SignalR パフォーマンス カウンターを Web ロールにインストールします。
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
ソリューション エクスプローラーでsignalr.exe ファイルを選択します。 ファイルの [プロパティ] で、[ コピー] を [出力ディレクトリ] に [ 常にコピー] に設定します。
SignalRPerfCounterInstall.cmd ファイルに対して前の手順を繰り返します。
SignalRPerfCounterInstall.cmd ファイルを右クリックし、[ ファイルを開く] を選択します。 表示されるダイアログで、[ バイナリ エディター ] を選択し、[ OK] を選択します。
バイナリ エディターで、ファイル内の先頭のバイトを選択し、削除します。 ファイルを保存して閉じます。
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>
ファイルの末尾から jQuery バンドル スクリプトを開
Views/Shared/_Layout.cshtml
いて削除します。<div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - My ASP.NET Application</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
サーバーで メソッドを継続的に呼び出す
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>
WebRole1 プロジェクトに Hubs という名前の新しいフォルダーを作成します。 ソリューション エクスプローラーの Hubs フォルダーを右クリックし、[新しい項目の追加]> を選択します。 [ 新しい項目の追加 ] ダイアログ ボックスで、 Web>SignalR カテゴリを選択し、 SignalR Hub Class (v2) 項目テンプレートを選択します。 新しいハブに MyHub.cs という名前を 付 け、[追加] を選択します。
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); } } }
Crank.exe は、SignalR コードベースで提供される接続密度テスト ツールです。 クランクには永続的な接続が必要なので、テスト時に使用するためにサイトに追加します。 PersistentConnections という名前の新しいフォルダーを WebRole1 プロジェクトに追加します。 このフォルダーを右クリックし、[クラスの追加]> を選択します。 新しいクラス ファイルに MyPersistentConnections.cs という名前を 付け、[追加] を選択します。
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); } } }
クラスを
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 を開始します。F5 キーを押して、Microsoft Azure Emulatorでアプリケーションをテストします。
Note
MapSignalR で FileLoadException が発生した場合は、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>
約 1 分待ちます。 Visual Studio で [クラウド エクスプローラー ツール] ウィンドウを開き ([クラウド エクスプローラーの表示>] ) パス
(Local)/Storage Accounts/(Development)/Tables
を展開します。 WADPerformanceCountersTable をダブルクリックします。 テーブル データに SignalR カウンターが表示されます。 テーブルが表示されない場合は、Azure Storage の資格情報を再入力する必要がある場合があります。 [更新] ボタンを選択して Cloud エクスプローラーのテーブルを表示するか、開いているテーブル ウィンドウで [更新] ボタンを選択してテーブル内のデータを表示する必要があります。クラウドでアプリケーションをテストするには、 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=<account-name>;AccountKey=<account-key>" /> </ConfigurationSettings> </Role> </ServiceConfiguration>
アプリケーションを Azure サブスクリプションにデプロイします。 Azure にアプリケーションをデプロイする方法の詳細については、「 クラウド サービスを作成してデプロイする方法」を参照してください。
数分待ちます。 [クラウド エクスプローラー] で、上記で構成したストレージ アカウントを見つけて、その中のテーブルを
WADPerformanceCountersTable
見つけます。 テーブル データに SignalR カウンターが表示されます。 テーブルが表示されない場合は、Azure Storage の資格情報を再入力する必要がある場合があります。 [更新] ボタンを選択して Cloud エクスプローラーでテーブルを表示するか、開いているテーブル ウィンドウの [更新] ボタンを選択してテーブル内のデータを表示する必要がある場合があります。
このチュートリアルで使用される元のコンテンツの Martin Richard に感謝します。