Usando contadores de desempenho do Signalr em uma função Web do Azure

Por Luke Latham

Warning

Esta documentação não é para a versão mais recente do Signalr. Dê uma olhada ASP.NET Core signalr.

Os contadores de desempenho do signalr são usados para monitorar o desempenho do aplicativo em uma função Web do Azure. Os contadores são capturados por Diagnóstico do Microsoft Azure. Você instala contadores de desempenho do Signalr no Azure com signalr.exe, a mesma ferramenta usada para aplicativos autônomos ou locais. Como as funções do Azure são transitórias, você configura um aplicativo para instalar e registrar contadores de desempenho do Signalr na inicialização.

Pré-requisitos

Criando um aplicativo de função Web do Azure que expõe contadores de desempenho do Signalr

  1. Abra o Visual Studio.

  2. No Visual Studio, selecione Arquivo > Novo > Projeto.

  3. Na caixa de diálogo novo projeto , selecione a categoria nuvem do Visual C# > Cloud à esquerda e, em seguida, selecione o modelo serviço de nuvem do Azure . Nomeie o aplicativo SignalRPerfCounters e selecione OK.

    Novo aplicativo de nuvem

    Note

    Se você não vir a categoria de modelo de nuvem ou o modelo de serviço de nuvem do Azure , precisará instalar a carga de trabalho de desenvolvimento do azure para o Visual Studio 2017. Escolha o link abrir instalador do Visual Studio no lado inferior esquerdo da caixa de diálogo novo projeto para abrir o instalador do Visual Studio. Selecione a carga de trabalho de desenvolvimento do Azure e, em seguida, escolha Modificar para iniciar a instalação da carga de trabalho.

    Carga de trabalho de desenvolvimento do Azure no Instalador do Visual Studio

  4. Na caixa de diálogo novo serviço de nuvem Microsoft Azure , selecione função Web ASP.net e selecione o botão > para adicionar a função ao projeto. Selecione OK.

    Adicionar função Web ASP.NET

  5. Na caixa de diálogo novo aplicativo Web ASP.net-WebRole1 , selecione o modelo MVC e, em seguida, selecione OK.

    Adicionar MVC e API Web

  6. Em Gerenciador de soluções, abra o arquivo Diagnostics. wadcfgx em WebRole1.

    Gerenciador de Soluções Diagnostics. wadcfgx

  7. Substitua o conteúdo do arquivo pela configuração a seguir e salve o arquivo:

    <?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. Abra o console do Gerenciador de pacotes em ferramentas > Gerenciador de pacotes NuGet. Insira os seguintes comandos para instalar a versão mais recente do Signalr e o pacote de utilitários do Signalr:

    install-package microsoft.aspnet.signalr
    install-package microsoft.aspnet.signalr.utils
    
  9. Configure o aplicativo para instalar os contadores de desempenho do Signalr na instância de função quando ele for iniciado ou reciclado. Em Gerenciador de soluções, clique com o botão direito do mouse no projeto WebRole1 e selecione Adicionar > nova pasta. Nomeie a nova pasta de inicialização.

    Adicionar pasta de inicialização

  10. Copie o arquivo de signalr.exe (adicionado com o pacote Microsoft. AspNet. Signalr. utils ) de <project folder> /SignalRPerfCounters/Packages/Microsoft.AspNet.SignalR.utils. <version> /Tools para a pasta de inicialização que você criou na etapa anterior.

  11. Em Gerenciador de soluções, clique com o botão direito do mouse na pasta de inicialização e selecione Adicionar > Item existente. Na caixa de diálogo exibida, selecione signalr.exe e selecione Adicionar.

    Adicionar signalr.exe ao projeto

  12. Clique com o botão direito do mouse na pasta de inicialização que você criou. Selecione Adicionar > novo item. Selecione o nó geral , selecione arquivo de textoe nomeie o novo item SignalRPerfCounterInstall. cmd. Esse arquivo de comando instalará os contadores de desempenho do Signalr na função Web.

    Criar arquivo em lotes de instalação do contador de desempenho do Signalr

  13. Quando o Visual Studio cria o arquivo SignalRPerfCounterInstall. cmd , ele será aberto automaticamente na janela principal. Substitua o conteúdo do arquivo pelo script a seguir e, em seguida, salve e feche o arquivo. Esse script executa signalr.exe, que adiciona os contadores de desempenho do signalr à instância de função.

    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. Selecione o arquivo de signalr.exe em Gerenciador de soluções. Nas Propriedadesdo arquivo, defina copiar para diretório de saída como copiar sempre.

    Defina copiar para diretório de saída como copiar sempre

  15. Repita a etapa anterior para o arquivo SignalRPerfCounterInstall. cmd .

  16. Clique com o botão direito do mouse no arquivo SignalRPerfCounterInstall. cmd e selecione abrir com. Na caixa de diálogo exibida, selecione Editor de binários e selecione OK.

    Abrir com editor binário

  17. No editor binário, selecione qualquer byte à esquerda no arquivo e exclua-os. Salve e feche o arquivo.

    Excluir bytes à esquerda

  18. Abra o Service Definition. csdef e adicione uma tarefa de inicialização que execute o arquivo SignalrPerfCounterInstall. cmd quando o serviço for iniciado:

    <?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. Abra Views/Shared/_Layout.cshtml e remova o script de pacote jQuery do final do arquivo.

    <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. Adicione um cliente JavaScript que chama continuamente o increment método no servidor. Abra Views/Home/Index.cshtml e substitua o conteúdo pelo código a seguir:

    @{
        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. Crie uma nova pasta no projeto WebRole1 chamado hubs. Clique com o botão direito do mouse na pasta hubs em Gerenciador de soluções e selecione Adicionar > novo item. Na caixa de diálogo Adicionar novo item , selecione a categoria signalr da Web > SignalR e, em seguida, selecione o modelo de item classe do Hub do signalr (v2) . Nomeie o novo MyHub.cs de Hub e selecione Adicionar.

    Adicionando a classe de Hub do Signalr à pasta hubs na caixa de diálogo Adicionar novo item

  22. O MyHub.cs será aberto automaticamente na janela principal. Substitua o conteúdo pelo código a seguir e, em seguida, salve e feche o arquivo:

    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 é uma ferramenta de teste de densidade de conexão fornecida com a base de código do signalr. Como o pedais requer uma conexão persistente, você adiciona uma ao seu site para uso durante o teste. Adicione uma nova pasta ao projeto WebRole1 chamado PersistentConnections. Clique com o botão direito do mouse nessa pasta e selecione Adicionar > classe. Nomeie o novo arquivo de classe MyPersistentConnections.cs e selecione Adicionar.

  24. O Visual Studio abrirá o arquivo MyPersistentConnections.cs na janela principal. Substitua o conteúdo pelo código a seguir e, em seguida, salve e feche o arquivo:

    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. Usando a Startup classe, os objetos signalr começam quando o OWIN é iniciado. Abra ou crie Startup.cs e substitua o conteúdo pelo código a seguir:

    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");
            }
        }
    }
    

    No código acima, o OwinStartup atributo marca essa classe para iniciar OWIN. O Configuration método inicia o signalr.

  26. Teste seu aplicativo no emulador de Microsoft Azure pressionando F5.

    Note

    Se você encontrar um FileLoadException em MapSignalR, altere os redirecionamentos de associação em web.config para o seguinte:

    <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. Aguarde cerca de um minuto. Abra a janela de ferramentas do Cloud Explorer no Visual Studio (Exibir > Cloud Explorer) e expanda o caminho (Local)/Storage Accounts/(Development)/Tables . Clique duas vezes em WADPerformanceCountersTable. Você deve ver os contadores do Signalr nos dados da tabela. Se você não vir a tabela, talvez seja necessário inserir novamente suas credenciais de armazenamento do Azure. Talvez seja necessário selecionar o botão Atualizar para ver a tabela no Cloud Explorer ou selecionar o botão Atualizar na janela Abrir tabela para ver os dados na tabela.

    Selecionando a tabela de contadores de desempenho WAD no Visual Studio Cloud Explorer

    Mostrando os contadores coletados na tabela de contadores de desempenho WAD

  28. Para testar seu aplicativo na nuvem, atualize o arquivo . Cloud. cscfg e defina Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString como uma cadeia de conexão de conta de armazenamento do Azure válida.

    <?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. Implante o aplicativo em sua assinatura do Azure. Para obter detalhes sobre como implantar um aplicativo no Azure, consulte como criar e implantar um serviço de nuvem.

  30. Aguarde alguns minutos. No Cloud Explorer, localize a conta de armazenamento configurada acima e localize a WADPerformanceCountersTable tabela nela. Você deve ver os contadores do Signalr nos dados da tabela. Se você não vir a tabela, talvez seja necessário inserir novamente suas credenciais de armazenamento do Azure. Talvez seja necessário selecionar o botão Atualizar para ver a tabela no Cloud Explorer ou selecionar o botão Atualizar na janela Abrir tabela para ver os dados na tabela.

Obrigado especial a Martin Richard pelo conteúdo original usado neste tutorial.