Panduan praktik terbaik dan pemecahan masalah untuk aplikasi simpul di Azure App Service Windows

Dalam artikel ini, Anda akan mempelajari praktik terbaik dan langkah-langkah pemecahan masalah untuk Aplikasi Node.js Windows yang berjalan di Azure App Service (dengan iisnode).

Peringatan

Berhati-hatilah saat menggunakan langkah-langkah pemecahan masalah di situs produksi Anda. Rekomendasi adalah untuk memecahkan masalah aplikasi Anda pada penyiapan nonproduksi misalnya slot staging Anda dan ketika masalahnya diperbaiki, tukar slot staging Anda dengan slot produksi Anda.

Konfigurasi IISNODE

File skema ini memperlihatkan semua pengaturan yang dapat Anda konfigurasi untuk iisnode. Beberapa pengaturan yang berguna untuk aplikasi Anda:

nodeProcessCountPerApplication

Pengaturan ini mengontrol jumlah proses simpul yang diluncurkan per aplikasi IIS. Nilai default adalah 1. Anda dapat meluncurkan node.exe sebanyak jumlah VM vCPU Anda dengan mengubah nilai menjadi 0. Nilai yang disarankan adalah 0 untuk sebagian besar aplikasi sehingga Anda dapat menggunakan semua vCPU pada mesin Anda. Node.exe memiliki untaian tunggal sehingga satu node.exe akan menggunakan maksimum 1 vCPU. Untuk mendapatkan performa maksimum dari aplikasi node Anda, Anda ingin menggunakan semua vCPU.

nodeProcessCommandLine

Pengaturan ini mengontrol jalur ke node.exe. Anda dapat mengatur nilai ini untuk menunjuk ke versi node.exe Anda.

maxConcurrentRequestsPerProcess

Pengaturan ini mengontrol jumlah maksimum permintaan bersamaan yang dikirim oleh iisnode ke setiap node.exe. Di Azure App Service, nilai default-nya adalah Tak terbatas. Anda dapat mengonfigurasi nilai tergantung pada berapa banyak permintaan yang diterima aplikasi Anda dan seberapa cepat aplikasi Anda memproses setiap permintaan.

maxNamedPipeConnectionRetry

Pengaturan ini mengontrol berapa kali maksimum iisnode mencoba untuk membuat koneksi pada pipa yang dinamai untuk mengirim permintaan ke node.exe. Pengaturan ini dikombinasikan dengan namedPipeConnectionRetryDelay akan menentukan batas waktu total setiap permintaan dalam iisnode. Nilai default-nya adalah 200 di Azure App Service. Total Batas waktu dalam detik = (maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000

namedPipeConnectionRetryDelay

Pengaturan ini mengontrol jumlah waktu (dalam ms) iisnode menunggu di antara setiap coba lagi untuk mengirim permintaan ke node.exe melalui pipa yang dinamai. Nilai default-nya adalah 250 ms. Total Batas waktu dalam detik = (maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000

Secara default, total batas waktu dalam iisnode di Azure App Service adalah 200 * 250 ms = 50 detik.

logDirectory

Pengaturan ini mengontrol direktori tempat iisnode mencatat stdout/stderr. Nilai default adalah iisnode yang relatif terhadap direktori skrip utama (direktori di mana server.js utama berada)

debuggerExtensionDll

Pengaturan ini mengontrol versi iisnode node-inspector apa yang digunakan saat penelusuran kesalahan aplikasi simpul Anda. Saat ini, iisnode-inspector-0.7.3.dll dan iisnode-inspector.dll adalah hanya dua nilai yang valid untuk pengaturan ini. Nilai default-nya adalah iisnode-inspector-0.7.3.dll. Versi iisnode-inspector-0.7.3.dll menggunakan node-inspector-0.7.3 dan menggunakan soket web. Aktifkan soket web di webapp Azure Anda untuk menggunakan versi ini.

flushResponse

Perilaku default IIS adalah bahwa ia melakukan buffer data respons hingga 4 MB sebelum pembersihan atau hingga akhir respons, mana saja yang lebih dulu. iisnode menawarkan pengaturan konfigurasi untuk mengambil alih perilaku ini: untuk membersihkan fragmen isi entitas respons segera setelah iisnode menerimanya dari node.exe, Anda perlu mengatur atribut iisnode/@flushResponse dalam web.config menjadi 'true':

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

Mengaktifkan pembersihan setiap fragmen dari badan entitas respons akan menambah overhead performa yang mengurangi throughput sistem sebesar ~5% (mulai dari v0.1.13). Yang terbaik untuk mencakup pengaturan ini hanya untuk titik akhir yang memerlukan streaming respons (misalnya, <location> menggunakan elemen dalam web.config)

Selain itu, untuk aplikasi streaming, Anda juga harus mengatur responseBufferLimit dari penangan iisnode Anda ke 0.

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

watchedFiles

Daftar file yang dipisahkan oleh titik koma yang diawasi untuk perubahan. Setiap perubahan pada file menyebabkan aplikasi didaur ulang. Setiap entri terdiri dari nama direktori opsional serta nama file yang diperlukan yang relatif terhadap direktori tempat titik masuk aplikasi utama berada. Kartu bebas hanya diperbolehkan di bagian nama file saja. Nilai defaultnya adalah *.js;iisnode.yml

recycleSignalEnabled

Nilai defaultnya adalah false. Jika diaktifkan, aplikasi simpul Anda dapat terhubung ke pipa yang dinamai (variabel lingkungan IISNODE_CONTROL_PIPE) dan mengirim pesan "daur ulang". Hal ini menyebabkan w3wp mendaur ulang dengan anggun.

idlePageOutTimePeriod

Nilai default adalah 0 yang berarti fitur ini dinonaktifkan. Ketika diatur ke beberapa nilai yang lebih besar dari 0, iisnode akan melakukan page out semua proses turunannya setiap ‘idlePageOutTimePeriod’ dalam milidetik. Lihat dokumentasi untuk memahami apa artinya page out. Pengaturan ini berguna untuk aplikasi yang menggunakan banyak memori dan ingin sesekali melakukan page out memori ke disk untuk mengosongkan RAM.

Peringatan

Berhati-hatilah saat mengaktifkan pengaturan konfigurasi berikut pada aplikasi produksi. Rekomendasinya adalah untuk tidak mengaktifkannya pada aplikasi produksi langsung.

debugHeaderEnabled

Nilai defaultnya adalah false. Jika disetel ke true, iisnode akan menambahkan header respons HTTP iisnode-debug ke setiap respons HTTP ia mengirimkan iisnode-debug nilai header adalah URL. Potongan individu dari informasi diagnostik dapat diperoleh dengan melihat fragmen URL, namun visualisasi tersedia dengan membuka URL di browser.

loggingEnabled

Pengaturan ini mengontrol pengelogan stdout dan stderr oleh iisnode. Iisnode mengambil stdout/stderr dari proses simpul yang diluncurkannya dan menuliskannya ke direktori yang ditentukan dalam pengaturan ‘logDirectory’. Setelah ini diaktifkan, aplikasi Anda akan menulis log ke sistem file dan tergantung pada jumlah pengelogan yang dilakukan oleh aplikasi, mungkin ada implikasi terhadap performa.

devErrorsEnabled

Nilai defaultnya adalah false. Ketika diatur ke true, iisnode menampilkan kode status HTTP dan kode galat Win32 di browser Anda. Kode win32 sangat membantu dalam penelusuran kesalahan jenis masalah tertentu.

debuggingEnabled (jangan aktifkan di situs produksi langsung)

Pengaturan ini mengontrol fitur penelusuran kesalahan. Iisnode terintegrasi dengan node-inspector. Dengan mengaktifkan pengaturan ini, Anda mengaktifkan penelusuran kesalahan aplikasi simpul Anda. Setelah mengaktifkan pengaturan ini, iisnode membuat file node-inspector di direktori 'debuggerVirtualDir' pada permintaan debug pertama ke aplikasi simpul Anda. Anda dapat memuat node-inspector dengan mengirim permintaan ke http://yoursite/server.js/debug. Anda dapat mengontrol segmen URL debug dengan pengaturan ‘debuggerPathSegment’. Secara default, debuggerPathSegment=’debug’. Anda dapat mengatur debuggerPathSegment ke GUID, misalnya, sehingga lebih sulit untuk ditemukan oleh orang lain.

Baca Debug aplikasi node.js pada Windows untuk detail lebih lanjut tentang penelusuran kesalahan.

Skenario dan rekomendasi/pemecahan masalah

Aplikasi simpul saya melakukan panggilan keluar yang berlebihan

Banyak aplikasi ingin membuat koneksi keluar sebagai bagian dari operasi reguler mereka. Misalnya, ketika permintaan masuk, aplikasi simpul Anda ingin menghubungi REST API di tempat lain dan mendapatkan beberapa informasi untuk memproses permintaan. Anda ingin menggunakan agen tetap aktif saat melakukan panggilan http atau https. Anda dapat menggunakan modul agentkeepalive sebagai agen tetap aktif Anda saat melakukan panggilan keluar ini.

Modul agentkeepalive memastikan bahwa soket digunakan kembali pada VM webapp Azure Anda. Membuat soket baru pada setiap permintaan keluar akan menambahkan overhead ke aplikasi Anda. Meminta aplikasi Anda menggunakan kembali soket untuk permintaan keluar memastikan bahwa aplikasi Anda tidak melebihi maxSocket yang dialokasikan per VM. Rekomendasi pada Azure App Service adalah untuk mengatur nilai maxSockets agentKeepAlive ke total (4 instans node.exe * 32 maxSocket/instans) 128 soket per VM.

Contoh konfigurasi agentKeepALive:

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

Penting

Contoh ini mengasumsikan Anda memiliki 4 node.exe yang berjalan pada VM Anda. Jika Anda memiliki jumlah node.exe yang berbeda yang berjalan di VM, Anda harus mengubah pengaturan maxSockets yang sesuai.

Aplikasi simpul saya menggunakan CPU terlalu banyak

Anda mungkin menerima rekomendasi dari Azure App Service di portal Anda tentang konsumsi cpu yang tinggi. Anda juga dapat mengatur monitor untuk menonton metrik tertentu. Saat memeriksa penggunaan CPU di Dasbor portal Microsoft Azure, periksa nilai MAKS untuk CPU sehingga Anda tidak melewati nilai puncak. Jika Anda yakin aplikasi Anda menggunakan CPU terlalu banyak dan Anda tidak dapat menjelaskan mengapa, Anda dapat memprofilkan aplikasi simpul Anda untuk mencari tahu.

Pemrofilkan aplikasi node Anda di Azure App Service dengan V8-Profiler

Misalnya, Anda memiliki aplikasi halo dunia yang ingin Anda profil sebagai berikut:

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

Buka situs Konsol Debug https://yoursite.scm.azurewebsites.net/DebugConsole

Masuk ke direktori site/wwwroot Anda. Anda melihat perintah seperti yang diperlihatkan dalam contoh berikut:

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

Jalankan perintah npm install v8-profiler.

Perintah ini menginstal v8-profiler di bawah direktori simpul_modul dan semua dependensinya. Sekarang, edit server.js Anda untuk membuat profil aplikasi Anda.

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

Kode sebelumnya memprofilkan fungsi WriteConsoleLog dan kemudian menulis output profil ke file ‘profile.cpuprofile’ di bawah situs Anda wwwroot. Kirim permintaan ke aplikasi Anda. Anda melihat file ‘profile.cpuprofile’ yang dibuat di bawah situs Anda wwwroot.

Screenshot that shows the profile.cpuprofile file.

Unduh file ini dan buka dengan Alat Chrome F12. Tekan F12 di Chrome, lalu pilih tab Profil. Pilih tombol Muat. Pilih file profile.cpuprofile yang Anda unduh. Klik profil yang baru saja Anda muat.

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

Anda dapat melihat bahwa 95% dari waktu itu digunakan oleh fungsi WriteConsoleLog. Output-nya juga menunjukkan nomor baris yang tepat dan file sumber yang menyebabkan masalah.

Aplikasi simpul saya menggunakan memori terlalu banyak

Jika aplikasi Anda menggunakan memori terlalu banyak, Anda akan melihat pemberitahuan dari Azure App Service di portal Anda tentang penggunaan memori yang tinggi. Anda dapat mengatur monitor untuk mengawasi metrik tertentu. Saat memeriksa penggunaan memori di Dasbor portal Microsoft Azure, pastikan untuk memeriksa nilai MAKS untuk memori sehingga Anda tidak melewati nilai puncak.

Deteksi kebocoran dan Heap Diff untuk Node.js

Anda dapat menggunakan node-memwatch untuk membantu Anda mengidentifikasi kebocoran memori. Anda dapat menginstal memwatch seperti v8-profiler dan mengedit kode Anda untuk mengambil dan membandingkan perbedaan heap untuk mengidentifikasi kebocoran memori di aplikasi Anda.

Node.exe saya mati secara acak

Ada beberapa alasan mengapa node.exe mati secara acak:

  1. Aplikasi Anda mengeluarkan pengecualian yang tidak tertangkap – Periksa file d:\home\LogFiles\Application\logging-errors.txt untuk detail tentang pengecualian yang dikeluarkan. File ini memiliki jejak tumpukan untuk membantu melakukan debug dan memperbaiki aplikasi Anda.
  2. Aplikasi Anda menggunakan memori terlalu banyak yang memengaruhi proses lain untuk memulai. Jika total memori VM mendekati 100%, node.exe Anda bisa dimatikan oleh manajer proses. Manajer proses mematikan beberapa proses untuk membiarkan proses lain mendapatkan kesempatan untuk melakukan beberapa pekerjaan. Untuk memperbaiki masalah ini, profilkan aplikasi Anda untuk kebocoran memori. Jika aplikasi Anda membutuhkan memori dalam jumlah besar, tingkatkan ke VM yang lebih besar (yang meningkatkan RAM yang tersedia untuk VM).

Aplikasi simpul saya tidak mulai berjalan

Jika aplikasi Anda menampilkan Kesalahan 500 saat dimulai, mungkin ada beberapa alasan:

  1. Node.exe tidak berada di lokasi yang tepat. Periksa pengaturan nodeProcessCommandLine.
  2. File skrip utama tidak berada di lokasi yang tepat. Periksa web.config dan pastikan nama file skrip utama di bagian penangan cocok dengan file skrip utama.
  3. Konfigurasi Web.config salah – periksa nama/nilai pengaturan.
  4. Mulai Dingin – Aplikasi Anda membutuhkan waktu terlalu lama untuk memulai. Jika aplikasi Anda membutuhkan waktu lebih lama dari (maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000 detik, iisnode akan menampilkan pesan kesalahan 500. Tingkatkan nilai pengaturan ini agar sesuai dengan waktu mulai aplikasi Anda untuk mencegah iisnode kehabisan waktu dan menampilkan kesalahan 500.

Aplikasi simpul saya mengalami crash

Aplikasi Anda mengeluarkan pengecualian yang tidak tertangkap – Periksa file d:\\home\\LogFiles\\Application\\logging-errors.txt untuk detail tentang pengecualian yang dikeluarkan. File ini memiliki jejak tumpukan untuk membantu mendiagnosis dan memperbaiki aplikasi Anda.

Aplikasi simpul saya membutuhkan terlalu banyak waktu untuk mulai berjalan (Mulai Dingin)

Penyebab umum untuk waktu mulai aplikasi yang lama adalah jumlah file yang banyak dalam simpul_modul. Aplikasi mencoba memuat sebagian besar file ini saat memulai. Secara default, karena file Anda disimpan di berbagi jaringan di Azure App Service, memuat banyak file dapat memakan waktu. Beberapa solusi untuk membuat proses ini lebih cepat adalah:

  1. Cobalah untuk melakukan pemuatan lambat pada simpul_modul Anda dan tidak memuat semua modul saat aplikasi dimulai. Untuk melakukan Pemuatan Lambat pada modul, panggilan untuk require(‘module’) harus dibuat ketika Anda benar-benar membutuhkan modul di dalam fungsi sebelum eksekusi pertama kode modul.
  2. Azure App Service menawarkan fitur yang disebut cache lokal. Fitur ini menyalin isi Anda dari berbagi jaringan ke disk lokal pada VM. Karena file berada di lokal, waktu muat simpul_modul jauh lebih cepat.

status dan substatus http IISNODE

cnodeconstantsFile sumber mencantumkan semua kombinasi status/substatus yang mungkin dapat ditampilkan oleh iisnode karena kesalahan.

Aktifkan FREB untuk aplikasi Anda untuk melihat kode galat win32 (pastikan Anda mengaktifkan FREB hanya di situs nonproduksi karena alasan performa).

Status Http Substatus Http Kemungkinan Alasan?
500 1000 Ada beberapa masalah mengirimkan permintaan ke IISNODE – Periksa apakah node.exe dimulai. Node.exe bisa saja mengalami crash ketika memulai. Periksa konfigurasi web.config Anda untuk kesalahan.
500 1001 - Win32Error 0x2 - Aplikasi tidak menanggapi URL. Periksa aturan penulisan ulang URL atau periksa apakah aplikasi ekspres Anda telah menentukan rute yang benar. - Win32Error 0x6d – pipa yang dinamai sedang sibuk – Node.exe tidak menerima permintaan karena pipa sedang sibuk. Periksa penggunaan cpu tinggi. - Kesalahan lain – periksa apakah node.exe mengalami crash.
500 1002 Node.exe mengalami crash – periksa d:\home\LogFiles\logging-errors.txt untuk jejak tumpukan.
500 1003 Masalah konfigurasi pipa – Konfigurasi pipa yang dinamai salah.
500 1004-1018 Timbul beberapa kesalahan saat mengirim permintaan atau memproses respons ke/dari node.exe. Periksa apakah node.exe mengalami crash. periksa d:\home\LogFiles\logging-errors.txt untuk jejak tumpukan.
503 1000 Tidak cukup memori untuk mengalokasikan lebih banyak koneksi pipa yang dinamai. Periksa mengapa aplikasi Anda menggunakan begitu banyak memori. Periksa nilai pengaturan maxConcurrentRequestsPerProcess. Jika tidak terbatas dan Anda memiliki banyak permintaan, tingkatkan nilai ini untuk mencegah kesalahan ini.
503 1001 Permintaan tidak dapat dikirim ke node.exe karena aplikasi sedang didaur ulang. Setelah aplikasi didaur ulang, permintaan harus dilayani secara normal.
503 1002 Periksa kode galat win32 untuk alasan yang sebenarnya – Permintaan tidak dapat dikirim ke node.exe.
503 1003 Pipa yang dinamai terlalu Sibuk – Verifikasi apakah node.exe menggunakan CPU yang berlebihan

NODE.exe memiliki pengaturan yang disebut NODE_PENDING_PIPE_INSTANCES. Pada Azure App Service, nilai ini diatur ke 5000. Artinya node.exe bisa menerima 5000 permintaan sekaligus pada pipa yang dinamai. Nilai ini harusnya cukup baik untuk sebagian besar aplikasi node yang berjalan di Azure App Service. Anda tidak boleh melihat 503.1003 di Azure App Service karena nilai tinggi untuk NODE_PENDING_PIPE_INSTANCES

Sumber daya lainnya

Ikuti tautan ini untuk mempelajari selengkapnya tentang aplikasi node.js di Azure App Service.