Metodtips och felsökningsguide för nodprogram i Azure App Service Windows

I den här artikeln får du lära dig metodtips och felsökningssteg för Windows Node.js-program som körs i Azure App Service (med iisnode).

Varning

Var försiktig när du använder felsökningssteg på produktionsplatsen. Rekommendationen är att felsöka din app på en installation som inte är produktionsbaserad, till exempel mellanlagringsplatsen och när problemet är åtgärdat byter du mellanlagringsplats med produktionsplatsen.

IISNODE-konfiguration

Den här schemafilen visar alla inställningar som du kan konfigurera för iisnode. Några av de inställningar som är användbara för ditt program:

nodeProcessCountPerApplication

Den här inställningen styr antalet nodprocesser som startas per IIS-program. Standardvärdet är 1. Du kan starta så många node.exes som antalet virtuella datorer vCPU genom att ändra värdet till 0. Det rekommenderade värdet är 0 för de flesta program så att du kan använda alla virtuella processorer på datorn. Node.exe är entrådad så en node.exe förbrukar högst 1 vCPU. Om du vill få ut maximal prestanda från nodprogrammet vill du använda alla vCPU:er.

nodeProcessCommandLine

Den här inställningen styr sökvägen till node.exe. Du kan ange det här värdet så att det pekar på din node.exe-version.

maxConcurrentRequestsPerProcess

Den här inställningen styr det maximala antalet samtidiga begäranden som skickas av iisnode till varje node.exe. I Azure App Service är standardvärdet Oändligt. Du kan konfigurera värdet beroende på hur många begäranden programmet tar emot och hur snabbt programmet bearbetar varje begäran.

maxNamedPipe Anslut ionRetry

Den här inställningen styr det maximala antalet gånger som iisnode försöker göra anslutningen på det namngivna röret för att skicka begäranden till node.exe. Den här inställningen i kombination med namedPipe Anslut ionRetryDelay avgör den totala tidsgränsen för varje begäran i iisnode. Standardvärdet är 200 i Azure App Service. Total timeout i sekunder = (maxNamedPipe Anslut ionRetry * namedPipe Anslut ionRetryDelay) / 1000

namedPipe Anslut ionRetryDelay

Den här inställningen styr hur lång tid (i ms) iisnode väntar mellan varje nytt försök för att skicka begäran till node.exe över det namngivna röret. Standardvärdet är 250 ms. Total timeout i sekunder = (maxNamedPipe Anslut ionRetry * namedPipe Anslut ionRetryDelay) / 1000

Som standard är den totala tidsgränsen i iisnode i Azure App Service 200 * 250 ms = 50 sekunder.

logDirectory

Den här inställningen styr katalogen där iisnode loggar stdout/stderr. Standardvärdet är iisnode, vilket är relativt till huvudskriptkatalogen (katalog där main server.js finns)

debuggerExtensionDll

Den här inställningen styr vilken version av node-inspector iisnode som används vid felsökning av nodprogrammet. För närvarande är iisnode-inspector-0.7.3.dll och iisnode-inspector.dll de enda två giltiga värdena för den här inställningen. Standardvärdet är iisnode-inspector-0.7.3.dll. Iisnode-inspector-0.7.3.dll-versionen använder node-inspector-0.7.3 och använder webb sockets. Aktivera webb sockets på din Azure-webbapp för att använda den här versionen.

flushResponse

Standardbeteendet för IIS är att det buffrar svarsdata upp till 4 MB före tömning, eller till slutet av svaret, beroende på vilket som kommer först. iisnode erbjuder en konfigurationsinställning som åsidosätter det här beteendet: om du vill rensa ett fragment av entitetstexten för svar så snart iisnode tar emot den från node.exe måste du ange attributet iisnode/@flushResponse i web.config till "true":

<configuration>
    <system.webServer>
        <!-- ... -->
        <iisnode flushResponse="true" />
    </system.webServer>
</configuration>

Aktivera tömning av varje fragment i svarsentitetstexten lägger till prestandakostnader som minskar systemets dataflöde med ~5 % (från och med v0.1.13). Det bästa sättet att begränsa den här inställningen endast till slutpunkter som kräver svarsströmning (till exempel med elementet <location> i web.config)

Dessutom måste du för strömmande program även ange responseBufferLimit för din iisnode-hanterare till 0.

<handlers>
    <add name="iisnode" path="app.js" verb="\*" modules="iisnode" responseBufferLimit="0"/>
</handlers>

watchedFiles

En semikolonavgränsad lista över filer som övervakas för ändringar. Alla ändringar i en fil gör att programmet återanvänds. Varje post består av ett valfritt katalognamn samt ett obligatoriskt filnamn, som är relativt den katalog där huvudprogrammets startpunkt finns. Jokertecken tillåts endast i filnamnsdelen. Standardvärdet är *.js;iisnode.yml

recycleSignalEnabled

Standardvärdet är "false". Om det är aktiverat kan nodprogrammet ansluta till en namngiven pipe (miljövariabel IISNODE_CONTROL_PIPE) och skicka ett "papperskorgsmeddelande". Detta gör att w3wp återvinns korrekt.

idlePageOutTimePeriod

Standardvärdet är 0, vilket innebär att den här funktionen är inaktiverad. När värdet är större än 0 kommer iisnode att visa alla underordnade processer varje "idlePageOutTimePeriod" i millisekunder. Se dokumentationen för att förstå vad utsidessidan innebär. Den här inställningen är användbar för program som förbrukar mycket minne och som ibland vill ta bort minne till disk för att frigöra RAM-minne.

Varning

Var försiktig när du aktiverar följande konfigurationsinställningar för produktionsprogram. Rekommendationen är att inte aktivera dem i liveproduktionsprogram.

debugHeaderEnabled

Standardvärdet är "false". Om värdet är true lägger iisnode till ett HTTP-svarshuvud iisnode-debug för varje HTTP-svar som skickas iisnode-debug till rubrikens värde är en URL. Enskilda delar av diagnostikinformationen kan hämtas genom att titta på URL-fragmentet, men en visualisering är tillgänglig genom att öppna URL:en i en webbläsare.

loggingEnabled

Den här inställningen styr loggning av stdout och stderr efter iisnode. Iisnode samlar in stdout/stderr från nodprocesser som startas och skrivs till katalogen som anges i inställningen logDirectory. När detta är aktiverat skriver ditt program loggar till filsystemet och beroende på mängden loggning som görs av programmet kan det uppstå prestandakonsekvenser.

devErrorsEnabled

Standardvärdet är "false". När värdet är true visar iisnode HTTP-statuskoden och Win32-felkoden i webbläsaren. Win32-koden är användbar när du felsöker vissa typer av problem.

debuggingEnabled (aktivera inte på liveproduktionsplats)

Den här inställningen styr felsökningsfunktionen. Iisnode är integrerat med node-inspector. Genom att aktivera den här inställningen aktiverar du felsökning av nodprogrammet. När du aktiverar den här inställningen skapar iisnode nodkontrollfiler i katalogen "debuggerVirtualDir" i den första felsökningsbegäran till nodprogrammet. Du kan läsa in nodkontroll genom att skicka en begäran till http://yoursite/server.js/debug. Du kan styra felsöknings-URL-segmentet med inställningen "debuggerPathSegment". Som standard felsöker duPathSegment='debug'. Du kan till exempel ange debuggerPathSegment ett GUID så att det blir svårare att identifieras av andra.

Läs Felsöka Node.js-program i Windows för mer information om felsökning.

Scenarier och rekommendationer/felsökning

Mitt nodprogram gör överdrivna utgående anrop

Många program skulle vilja göra utgående anslutningar till en del av deras vanliga drift. När en begäran till exempel kommer in vill nodappen kontakta ett REST-API någon annanstans och hämta information för att bearbeta begäran. Du vill använda en keep-alive-agent när du gör http- eller https-anrop. Du kan använda agentkeepalive-modulen som din keep alive-agent när du gör dessa utgående anrop.

Modulen agentkeepalive säkerställer att socketar återanvänds på den virtuella Azure-webbappens virtuella dator. Om du skapar en ny socket för varje utgående begäran läggs extra kostnader till i ditt program. Om programmet återanvänder socketar för utgående begäranden ser du till att programmet inte överskrider de maxSockets som allokeras per virtuell dator. Rekommendationen för Azure App Service är att ange värdet agentKeepAlive maxSockets till totalt (4 instanser av node.exe * 32 maxSockets/instans) 128 sockets per virtuell dator.

Exempel på agentKeepALive-konfiguration :

let keepaliveAgent = new Agent({
    maxSockets: 32,
    maxFreeSockets: 10,
    timeout: 60000,
    freeSocketTimeout: 300000
});

Viktigt!

Det här exemplet förutsätter att du har 4 node.exe som körs på den virtuella datorn. Om du har ett annat antal node.exe som körs på den virtuella datorn måste du ändra inställningen maxSockets i enlighet med detta.

Mitt nodprogram förbrukar för mycket CPU

Du kan få en rekommendation från Azure App Service på portalen om hög cpu-förbrukning. Du kan också konfigurera övervakare för att hålla utkik efter vissa mått. När du kontrollerar CPU-användningen på Instrumentpanelen för Azure-portalen kontrollerar du MAX-värdena för CPU så att du inte missar toppvärdena. Om du tror att ditt program förbrukar för mycket processorkraft och du inte kan förklara varför kan du profilera nodprogrammet för att ta reda på det.

Profilera nodprogrammet i Azure App Service med V8-Profiler

Anta till exempel att du har en Hello World-app som du vill profilera på följande sätt:

const http = require('http');
function WriteConsoleLog() {
    for(let i=0;i<99999;++i) {
        console.log('hello world');
    }
}

function HandleRequest() {
    WriteConsoleLog();
}

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    HandleRequest();
    res.end('Hello world!');
}).listen(process.env.PORT);

Gå till webbplatsen för felsökningskonsolen https://yoursite.scm.azurewebsites.net/DebugConsole

Gå till katalogen site/wwwroot. Du ser en kommandotolk enligt följande exempel:

Screenshot that shows your site/wwwroot directory and command prompt.

Kör kommandot npm install v8-profiler.

Det här kommandot installerar v8-profiler under node_modules katalog och alla dess beroenden. Redigera nu server.js för att profilera ditt program.

const http = require('http');
const profiler = require('v8-profiler');
const fs = require('fs');

function WriteConsoleLog() {
    for(let i=0;i<99999;++i) {
        console.log('hello world');
    }
}

function HandleRequest() {
    profiler.startProfiling('HandleRequest');
    WriteConsoleLog();
    fs.writeFileSync('profile.cpuprofile', JSON.stringify(profiler.stopProfiling('HandleRequest')));
}

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    HandleRequest();
    res.end('Hello world!');
}).listen(process.env.PORT);

Föregående kod profilerar funktionen WriteConsoleLog och skriver sedan profilutdata till filen profile.cpuprofile under webbplatsen wwwroot. Skicka en begäran till ditt program. Du ser en "profile.cpuprofile"-fil som skapats under webbplatsen wwwroot.

Screenshot that shows the profile.cpuprofile file.

Ladda ned den här filen och öppna den med Chrome F12 Tools. Tryck på F12 i Chrome och välj sedan fliken Profiler . Välj knappen Läs in . Välj din profile.cpuprofile-fil som du laddade ned. Klicka på den profil som du just läste in.

Screenshot that shows the profile.cpuprofile file that you loaded.

Du kan se att 95 % av tiden förbrukades av funktionen WriteConsoleLog. Utdata visar också de exakta radnummer och källfiler som orsakade problemet.

Mitt nodprogram förbrukar för mycket minne

Om programmet förbrukar för mycket minne visas ett meddelande från Azure App Service på portalen om hög minnesförbrukning. Du kan konfigurera övervakare för att hålla utkik efter vissa mått. När du kontrollerar minnesanvändningen på Instrumentpanelen i Azure-portalen kontrollerar du MAX-värdena för minne så att du inte missar toppvärdena.

Läckageidentifiering och Heap Diff för Node.js

Du kan använda node-memwatch för att identifiera minnesläckor. Du kan installera memwatch precis som v8-profilerare och redigera koden för att samla in och diff-heaps för att identifiera minnesläckorna i ditt program.

Mina node.exes avlivas slumpmässigt

Det finns några orsaker till varför node.exe stängs av slumpmässigt:

  1. Programmet genererar ohanterade undantag – Kontrollera filen d:\home\LogFiles\Application\logging-errors.txt för information om undantaget som genereras. Den här filen har stackspårningen som hjälper dig att felsöka och åtgärda ditt program.
  2. Programmet förbrukar för mycket minne, vilket påverkar andra processer från att komma igång. Om det totala virtuella datorminnet är nära 100 %, kan din node.exes avlivas av processhanteraren. Processhanteraren dödar vissa processer så att andra processer kan få en chans att utföra lite arbete. Åtgärda problemet genom att profilera programmet för minnesläckor. Om programmet kräver stora mängder minne skalar du upp till en större virtuell dator (vilket ökar det RAM-minne som är tillgängligt för den virtuella datorn).

Nodprogrammet startar inte

Om programmet returnerar 500 Fel när det startar kan det finnas några orsaker:

  1. Node.exe finns inte på rätt plats. Kontrollera inställningen nodeProcessCommandLine.
  2. Huvudskriptfilen finns inte på rätt plats. Kontrollera web.config och kontrollera att namnet på huvudskriptfilen i hanteringsavsnittet matchar huvudskriptfilen.
  3. Web.config-konfigurationen är inte korrekt – kontrollera inställningarnas namn/värden.
  4. Kallstart – Det tar för lång tid att starta programmet. Om programmet tar längre tid än (maxNamedPipe Anslut ionRetry * namedPipe Anslut ionRetryDelay) /1000 sekunder returnerar iisnode ett 500-fel. Öka värdena för de här inställningarna så att de matchar programmets starttid för att förhindra att iisnode överskrider tidsgränsen och returnerar 500-felet.

Mitt nodprogram kraschade

Programmet genererar ohanterade undantag – Kontrollera d:\\home\\LogFiles\\Application\\logging-errors.txt om det finns information om undantaget som genereras i filen. Den här filen har stackspårningen som hjälper dig att diagnostisera och åtgärda ditt program.

Mitt nodprogram tar för lång tid att starta (kall start)

Den vanligaste orsaken till långa starttider för program är ett stort antal filer i node_modules. Programmet försöker läsa in de flesta av dessa filer när du startar. Eftersom filerna lagras på nätverksresursen i Azure App Service kan det som standard ta tid att läsa in många filer. Några lösningar för att göra den här processen snabbare är:

  1. Försök att läsa in node_modules och läs inte in alla moduler vid programstart. För Lazy Load-moduler ska anropet till require('module') göras när du faktiskt behöver modulen i funktionen före den första körningen av modulkoden.
  2. Azure App Service erbjuder en funktion som kallas lokal cache. Den här funktionen kopierar ditt innehåll från nätverksresursen till den lokala disken på den virtuella datorn. Eftersom filerna är lokala är inläsningstiden för node_modules mycket snabbare.

Http-status och understatus för IISNODE

Källfilen cnodeconstants visar alla möjliga kombinationer av status/understatus som iisnode kan returnera på grund av ett fel.

Aktivera FREB för ditt program för att se win32-felkoden (se till att du endast aktiverar FREB på icke-produktionsplatser av prestandaskäl).

Http-status Http-understatus Möjlig orsak?
500 1000 Det gick inte att skicka begäran till IISNODE – kontrollera om node.exe startades. Node.exe kan ha kraschat när du startade. Kontrollera om det finns fel i konfigurationen av web.config.
500 1001 – Win32Error 0x2 – Appen svarar inte på URL:en. Kontrollera reglerna för URL-omskrivning eller kontrollera om expressappen har rätt vägar definierade. – Win32Error 0x6d – namngiven pipe is busy – Node.exe accepterar inte begäranden eftersom röret är upptaget. Kontrollera hög cpu-användning. – Andra fel – kontrollera om node.exe kraschade.
500 1002 Node.exe kraschade – kontrollera d:\home\LogFiles\logging-errors.txt för stackspårning.
500 1003 Problem med rörkonfiguration – Den namngivna rörkonfigurationen är felaktig.
500 1004-1018 Det uppstod ett fel när begäran skickades eller bearbetades till/från node.exe. Kontrollera om node.exe kraschade. kontrollera d:\home\LogFiles\logging-errors.txt för stackspårning.
503 1000 Det finns inte tillräckligt med minne för att allokera fler namngivna röranslutningar. Kontrollera varför din app förbrukar så mycket minne. Kontrollera inställningsvärdet maxConcurrentRequestsPerProcess. Om det inte är oändligt och du har många begäranden kan du öka det här värdet för att förhindra det här felet.
503 1001 Det gick inte att skicka begäran till node.exe eftersom programmet återanvänds. När programmet har återvinns ska begäranden hanteras normalt.
503 1002 Kontrollera win32-felkoden av faktisk anledning – Begäran kunde inte skickas till en node.exe.
503 1003 Namngivet rör är för upptaget – Kontrollera om node.exe förbrukar för mycket PROCESSOR

NODE.exe har en inställning som heter NODE_PENDING_PIPE_INSTANCES. I Azure App Service är det här värdet inställt på 5 000. Det innebär att node.exe kan acceptera 5 000 begäranden åt gången i det namngivna röret. Det här värdet bör vara tillräckligt bra för de flesta nodprogram som körs i Azure App Service. Du bör inte se 503.1003 i Azure App Service på grund av det höga värdet för NODE_PENDING_PIPE_INSTANCES

Fler resurser

Följ de här länkarna om du vill veta mer om Node.js-program i Azure App Service.