Menggunakan penghitung kinerja SignalR dalam Peran Web Azure
Oleh Lukas Latham
Peringatan
Dokumentasi ini bukan untuk versi terbaru SignalR. Lihatlah ASP.NET Core SignalR.
Penghitung kinerja SignalR digunakan untuk memantau performa aplikasi Anda dalam Peran Web Azure. Penghitung diambil oleh Microsoft Azure Diagnostics. Anda menginstal penghitung kinerja SignalR di Azure dengan signalr.exe, alat yang sama yang digunakan untuk aplikasi mandiri atau lokal. Karena peran Azure bersifat sementara, Anda mengonfigurasi aplikasi untuk menginstal dan mendaftarkan penghitung kinerja SignalR saat startup.
Prasyarat
- Visual Studio 2015 atau 2017
- Microsoft Azure SDK untuk Visual Studio Note: Mulai ulang komputer Anda setelah menginstal SDK.
- Langganan Microsoft Azure: Untuk mendaftar akun uji coba Azure gratis, lihat Uji Coba Gratis Azure.
Membuat aplikasi Peran Web Azure yang mengekspos penghitung kinerja SignalR
Buka Visual Studio.
Di Visual Studio, pilih File>Baru>Proyek.
Dalam kotak dialog Proyek Baru, pilih kategori Visual C#>Cloud di sebelah kiri, lalu pilih templat Azure Cloud Service. Beri nama aplikasi SignalRPerfCounters dan pilih OK.
Catatan
Jika Anda tidak melihat kategori templat Cloud atau templat Azure Cloud Service , Anda perlu menginstal beban kerja pengembangan Azure untuk Visual Studio 2017. Pilih tautan Buka Penginstal Visual Studio di sisi kiri bawah dialog Proyek Baru untuk membuka Alat Penginstal Visual Studio. Pilih beban kerja pengembangan Azure, lalu pilih Ubah untuk mulai menginstal beban kerja.
Dalam dialog Layanan Cloud Microsoft Azure Baru, pilih ASP.NET Peran Web dan pilih > tombol untuk menambahkan peran ke proyek. Pilih OK.
Dalam dialog New ASP.NET Web Application - WebRole1, pilih templat MVC, lalu pilih OK.
Di Penjelajah Solusi, buka file diagnostics.wadcfgx di bawah WebRole1.
Ganti konten file dengan konfigurasi berikut dan simpan file:
<?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>
Buka Konsol Manajer Paket dari Pengelola Paket NuGet Alat>. Masukkan perintah berikut untuk menginstal versi terbaru SignalR dan paket utilitas SignalR:
install-package microsoft.aspnet.signalr install-package microsoft.aspnet.signalr.utils
Konfigurasikan aplikasi untuk menginstal penghitung kinerja SignalR ke dalam instans peran saat dimulai atau didaur ulang. Di Penjelajah Solusi, klik kanan pada proyek WebRole1 dan pilih Tambahkan>Folder Baru. Beri nama folder baru Startup.
Salin file signalr.exe (ditambahkan dengan paket Microsoft.AspNet.SignalR.Utils) dari <folder> proyek/SignalRPerfCounters/packages/Microsoft.AspNet.SignalR.Utils.<versi>/alat ke folder Startup yang Anda buat di langkah sebelumnya.
Di Penjelajah Solusi, klik kanan folder Startup dan pilih Tambahkan>Item yang Sudah Ada. Dalam dialog yang muncul, pilih signalr.exe dan pilih Tambahkan.
Klik kanan pada folder Startup yang Anda buat. Pilih Tambahkan>Item Baru. Pilih simpul Umum , pilih File Teks, dan beri nama item baru SignalRPerfCounterInstall.cmd. File perintah ini akan menginstal penghitung kinerja SignalR ke dalam peran web.
Saat Visual Studio membuat file SignalRPerfCounterInstall.cmd , file tersebut akan terbuka secara otomatis di jendela utama. Ganti konten file dengan skrip berikut, lalu simpan dan tutup file. Skrip ini menjalankan signalr.exe, yang menambahkan penghitung kinerja SignalR ke instans peran.
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
Pilih file signalr.exe di Penjelajah Solusi. Di Properti file, atur Salin ke Direktori Output ke Salin Selalu.
Ulangi langkah sebelumnya untuk file SignalRPerfCounterInstall.cmd .
Klik kanan pada file SignalRPerfCounterInstall.cmd dan pilih Buka Dengan. Dalam dialog yang muncul, pilih Editor Biner dan pilih OK.
Di editor biner, pilih byte terkemuka dalam file dan hapus. Simpan dan tutup file.
Buka ServiceDefinition.csdef dan tambahkan tugas startup yang menjalankan file SignalrPerfCounterInstall.cmd saat layanan dimulai:
<?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>
Buka
Views/Shared/_Layout.cshtml
dan hapus skrip bundel jQuery dari akhir file.<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>
Tambahkan klien JavaScript yang terus memanggil
increment
metode di server. BukaViews/Home/Index.cshtml
dan ganti konten dengan kode berikut:@{ 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>
Buat folder baru di proyek WebRole1 bernama Hubs. Klik kanan folder Hub di Penjelajah Solusi dan pilih Tambahkan>Item Baru. Dalam kotak dialog Tambahkan Item Baru, pilih kategori Web>SignalR, lalu pilih templat item Kelas SignalR Hub (v2). Beri nama hub baru MyHub.cs dan pilih Tambahkan.
MyHub.cs akan terbuka secara otomatis di jendela utama. Ganti konten dengan kode berikut, lalu simpan dan tutup file:
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 adalah alat pengujian kepadatan koneksi yang disediakan dengan basis kode SignalR. Karena Crank memerlukan koneksi persisten, Anda menambahkannya ke situs Anda untuk digunakan saat pengujian. Tambahkan folder baru ke proyek WebRole1 yang disebut PersistentConnections. Klik kanan folder ini dan pilih Tambahkan>Kelas. Beri nama file kelas baru MyPersistentConnections.cs dan pilih Tambahkan.
Visual Studio akan membuka file MyPersistentConnections.cs di jendela utama. Ganti konten dengan kode berikut, lalu simpan dan tutup file:
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
Menggunakan kelas , objek SignalR dimulai saat OWIN dimulai. Buka atau buat Startup.cs dan ganti konten dengan kode berikut: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"); } } }
Dalam kode di atas,
OwinStartup
atribut menandai kelas ini untuk memulai OWIN. Metode iniConfiguration
memulai SignalR.Uji aplikasi Anda di Microsoft Azure Emulator dengan menekan F5.
Catatan
Jika Anda menemukan FileLoadException di MapSignalR, ubah pengalihan pengikatan di web.config menjadi berikut:
<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>
Tunggu sekitar satu menit. Buka jendela alat Cloud Explorer di Visual Studio (Lihat>Cloud Explorer) dan perluas jalur .
(Local)/Storage Accounts/(Development)/Tables
Klik dua kali WADPerformanceCountersTable. Anda akan melihat penghitung SignalR dalam data tabel. Jika Anda tidak melihat tabel, Anda mungkin perlu memasukkan kembali kredensial Azure Storage Anda. Anda mungkin perlu memilih tombol Refresh untuk melihat tabel di Cloud Explorer atau memilih tombol Refresh di jendela tabel terbuka untuk melihat data dalam tabel.Untuk menguji aplikasi Anda di cloud, perbarui file ServiceConfiguration.Cloud.cscfg dan atur
Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
ke akun Azure Storage yang valid string koneksi.<?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>
Sebarkan aplikasi ke langganan Azure Anda. Untuk detail tentang cara menyebarkan aplikasi ke Azure, lihat Cara Membuat dan Menyebarkan Layanan Cloud.
Tunggu beberapa saat. Di Cloud Explorer, temukan akun penyimpanan yang Anda konfigurasi di atas dan temukan tabel di
WADPerformanceCountersTable
dalamnya. Anda akan melihat penghitung SignalR dalam data tabel. Jika Anda tidak melihat tabel, Anda mungkin perlu memasukkan kembali kredensial Azure Storage Anda. Anda mungkin perlu memilih tombol Refresh untuk melihat tabel di Cloud Explorer atau memilih tombol Refresh di jendela tabel terbuka untuk melihat data dalam tabel.
Terima kasih khusus kepada Martin Richard untuk konten asli yang digunakan dalam tutorial ini.