Ilg‘or debug qilish


ULASHISH

Kengaytirilgan nosozliklarni tuzatishga kirish

Samarali debug Node.js dasturchilari uchun muhim mahoratdir.

console.log() asosiy debug uchun foydali bo‘lsa-da, ilg‘or texnikalar xotiraning oqishi, ishlashdagi qiyinchiliklar va poyga sharoitlari kabi murakkab muammolarni tashxislash imkonini beradi.

Ushbu qo‘llanma Node.js ilovalaringizdagi qiyin muammolarni hal qilishga yordam beradigan ilg‘or nosozliklarni tuzatish texnikasi va vositalarini qamrab oladi.

Murakkab nosozliklarni tuzatish vositalari quyidagi imkoniyatlarni taqdim etadi:

  • To‘xtash nuqtalarini o‘rnatish va kodni qadamma-qadam bajarish
  • Ishlash vaqtida o‘zgaruvchan qiymatlarni tekshirish
  • Xotira iste’molini vizualizatsiya qilish va qochqinlarni topish
  • Ishlashdagi qiyinchiliklarni aniqlash uchun protsessordan foydalanishni profillash
  • Asinxron chaqiruvlar stekini (call stack) tahlil qilish

Chrome DevTools yordamida debug

Node.js Chrome DevTools nosozliklarni tuzatish protokoli uchun o‘rnatilgan yordamni o‘z ichiga oladi, bu sizga Node.js ilovalaringizni debug qilish uchun kuchli Chrome DevTools interfeysidan foydalanish imkonini beradi.

Node.js-ni debug rejimida ishga tushirish

Ilovangizni debug rejimida ishga tushirishning bir necha yo‘li mavjud:

Standart debug rejimi

node --inspect app.js

Bu ilovangizni odatdagidek ishga tushiradi, lekin 9229-portda inspektorni yoqadi.

Ishga tushishda to‘xtash (break on start)

node --inspect-brk app.js

Bu kodning birinchi satrida bajarishni to‘xtatib turadi, bu esa bajarish boshlanishidan oldin to‘xtash nuqtalarini (breakpoint) o‘rnatish imkonini beradi.

Maxsus port

node --inspect=127.0.0.1:9222 app.js

Bu inspektor uchun maxsus portdan foydalanadi.

Nosozliklarni tuzatuvchiga ulanish

Node.js ilovasini tekshirish bayrog‘i bilan ishga tushirgandan so‘ng, unga bir necha usul bilan ulanishingiz mumkin:

  1. Chrome DevTools: Chrome brauzerini oching va chrome://inspect sahifasiga o‘ting.
    Node.js ilovangizni “Remote Target” ro‘yxatida ko‘rishingiz kerak.
    Ilovangizga ulangan DevToolsni ochish uchun “tekshirish” tugmasini bosing:
    Node.js uchun Chrome DevTools
  2. DevTools URL manzili: Terminalda ko‘rsatilgan URLni oching
    (odatda devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=127.0.0.1:9229/... kabi).

Nosozliklarni tuzatish uchun DevTools-dan foydalanish

Ulangandan so‘ng, Chrome DevTools’ning to‘liq quvvatidan foydalanishingiz mumkin:

  • Manbalar paneli: To‘xtash nuqtalarini o‘rnating, kodlar bo‘ylab qadam qo‘ying va o‘zgaruvchilarni ko‘ring
  • Call Stack: Joriy ijro stekini, jumladan, asinxron chaqiruvlar zanjirini ko‘rish
  • O‘zgaruvchilar doirasi: Har bir to‘xtash nuqtasida mahalliy va global o‘zgaruvchilarni tekshiring
  • Konsol: Joriy kontekstda ifodalarni baholang
  • Xotira paneli: Uyumli suratlarni oling va xotiradan foydalanishni tahlil qiling

Professional Maslahat: Xatolik yuz berganda avtomatik ravishda uzish uchun Manbalar panelining “Tushlangan istisnolarda pauza” funksiyasidan (egri chiziqlarli pauza tugmasi) foydalaning.



VS kodida debug

Visual Studio Code Node.js ilovalari uchun mukammal ichki debug imkoniyatlarini taqdim etadi.

VS kodida Node.js nosozliklarni tuzatishni sozlash

Node.js ilovangizni VS kodida tuzatishni bir necha usul bilan boshlashingiz mumkin:

  1. launch.json konfiguratsiyasi: VS Code qanday ishga tushishi yoki ilovangizga biriktirilishini aniqlash uchun .vscode/launch.json fayl yarating.
  2. Avtomatik biriktirish: --inspect bayrog‘i bilan boshlangan har qanday Node.js jarayonini avtomatik debug qilish uchun VS Code sozlamalarida avtomatik biriktirishni yoqing.
  3. JavaScript debug terminali: O‘sha terminaldan boshlangan har qanday Node.js jarayonini avtomatik debug qilish uchun VS Codedagi JavaScript debug terminalidan foydalaning.

Misol launch.json konfiguratsiyasi

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceFolder}/app.js",
      "skipFiles": ["<node_internals>/**"]
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Process",
      "port": 9229
    }
  ]
}

VS kodini tuzatish xususiyatlari

VS Code kuchli debug imkoniyatlarini taqdim etadi:

  • Ajratish nuqtalari: Kod muharriri bo‘shlig‘ini bosish orqali to‘xtash nuqtalarini o‘rnating, o‘chiring va yoqing.
  • Shartli to‘xtash nuqtalari: To‘xtash nuqtasi ishga tushishi uchun bajarilishi (true bo‘lishi) kerak bo‘lgan shartni belgilash uchun to‘xtash nuqtasi ustida sichqonchaning o‘ng tugmasini bosing.
  • Logpointlar: Kodning shu joyiga yetib kelinganda konsolga xabar chiqaradigan logpointlarni o‘rnatib, kodni o‘zgartirmasdan log yozishni qo‘shing.
  • Ifodalarni ko‘rish: Kod orqali o‘tayotganda o‘zgaruvchilar va ifodalarning qiymatini kuzatib boring.
  • Call Stack: Chaqiruvlar stekini, jumladan, asinxron freymlarni ko‘ring va boshqaring.

Eslatma: VS Code ham TypeScript fayllarini to‘g‘ridan-to‘g‘ri debug qilishi mumkin, manba Map’lari transpilyatsiya qilingan JavaScript o‘rniga asl TypeScript kodini tuzatish imkonini beradi.


Nosozliklarni tuzatish modulidan foydalanish

debug moduli yengil debug yordam dasturi bo‘lib, kodingizni console.log operatorlari bilan aralashtirmasdan Node.js ilovalaringizga shartli ro‘yxatga olishni qo‘shish imkonini beradi.

Debug modulini o‘rnatish

npm install debug

Debugning asosiy qo‘llanilishi

Nosozliklarni tuzatish moduli muhit o‘zgaruvchilari orqali yoqish yoki o‘chirish mumkin bo‘lgan nomlar oralig‘ida debug funksiyalarini yaratishga imkon beradi:

Misol: Debug modulidan foydalanish

// Create namespaced debuggers for different parts of your application
const debug = require('debug');

const debugServer = debug('app:server');
const debugDatabase = debug('app:database');
const debugAuth = debug('app:auth');

// Use the debuggers in your code
debugServer('Server starting on port %d', 8080);
debugDatabase('Connected to database: %s', 'mongodb://localhost');
debugAuth('User %s authenticated', 'john@example.com');

// By default, these debug messages won't appear in the output

Nosozliklarni tuzatish chiqishini yoqish

Nosozliklarni tuzatish natijasini ko‘rish uchun DEBUG muhit o‘zgaruvchisini vergul bilan ajratilgan nom maydoni naqshlari ro‘yxatiga o‘rnating:

Barcha nosozliklarni tuzatish chiqishini yoqing

DEBUG=app:* node app.js

Maxsus nom maydonlarini yoqing

DEBUG=app:server,app:auth node app.js

Hammasini yoqing, lekin ba’zilarini istisno qiling

DEBUG=app:*,-app:database node app.js

Nosozliklarni tuzatish chiqish xususiyatlari

  • Har bir nom maydoni osongina vizual identifikatsiya qilish uchun noyob rangga ega
  • Vaqt belgilari har bir xabar qachon qayd etilganligini ko‘rsatadi
  • console.log ga o‘xshash formatlangan chiqishni qo‘llab-quvvatlaydi
  • Xuddi shu nom maydonining oldingi jurnalidan millisekundlarda farqni ko‘rsatadi

Eng yaxshi amaliyot: Hozirda muammoni bartaraf etayotganingiz asosida debug natijalarini filtrlashni osonlashtirish uchun ilovangizning turli komponentlari uchun maxsus nom maydonlaridan foydalaning.


Xotiradagi qochqinlarni topish va tuzatish

Node.js ilovalaridagi xotira oqishlari ishlashning pasayishiga va natijada ishdan chiqishga olib kelishi mumkin.

Xotiraning oqishini aniqlash va tuzatish juda muhim nosozliklarni tuzatish qobiliyatidir.

Node.js-da xotira oqishining umumiy sabablari

  • Global o‘zgaruvchilar: Global miqyosda saqlanadigan va hech qachon tozalanmaydigan obyektlar
  • Yopishlar: Katta obyektlar yoki o‘zgaruvchilarga havolalarni saqlaydigan funksiyalar
  • Tadbir tinglovchilari: Qo‘shilgan, lekin hech qachon olib tashlanmaydigan tinglovchilar
  • Keshlar: Chegarasiz o‘sadigan xotiradagi keshlar
  • Taymerlar: tozalanmagan taymerlar (setTimeout/setInterval)
  • Promiselar: Ishlamaydigan Promiselar yoki hech qachon hal bo‘lmaydigan Promiselar zanjiri

Xotira oqishini aniqlash

Bir nechta yondashuvlar xotira oqishini aniqlashga yordam beradi:

1. Xotiradan foydalanishni kuzatib boring

// Monitor memory usage
function logMemoryUsage() {
  const memoryUsage = process.memoryUsage();
  console.log('Memory usage:');
  console.log(`RSS: ${Math.round(memoryUsage.rss / 1024 / 1024)} MB`);
  console.log(`Heap Total: ${Math.round(memoryUsage.heapTotal / 1024 / 1024)} MB`);
  console.log(`Heap Used: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)} MB`);
}

// Log memory usage every 30 seconds
setInterval(logMemoryUsage, 30000);
Misolni ishga tushirish »

2. Chrome DevTools yordamida yig‘ma suratlarni oling

Snapshotlar xotirani taqsimlashning batafsil ko‘rinishini taqdim etadi:

  1. Ilovangizni node --inspect app.js bilan boshlang
  2. Chrome DevTools bilan ulaning
  3. Xotira yorlig‘iga o‘ting
  4. Turli nuqtalarda to‘plangan suratlarni oling
  5. Soni yoki hajmi ortib borayotgan obyektlarni topish uchun suratlarni solishtiring

3. Xotirani profillash vositalaridan foydalaning

  • clinic doctor : Ilovangizdagi xotira muammolarini aniqlang
  • clinic heap : Uyma xotiradan foydalanishni tasavvur qiling
  • memwatch-next : Xotira oqishini aniqlash uchun kutubxona

Misol: Node.js serverida xotira o‘qish

Node.js serverida umumiy xotira o‘qish namunasini ko‘rsatuvchi misol:

const http = require('http');

// This object will store data for each request (memory leak!)
const requestData = {};

const server = http.createServer((req, res) => {
  // Generate a unique request ID
  const requestId = Date.now() + Math.random().toString(36).substring(2, 15);

  // Store data in the global object (THIS IS THE MEMORY LEAK)
  requestData[requestId] = {
    url: req.url,
    method: req.method,
    headers: req.headers,
    timestamp: Date.now(),
    // Create a large object to make the leak more obvious
    payload: Buffer.alloc(1024 * 1024) // Allocate 1MB per request
  };

  // Log memory usage after each request
  const memoryUsage = process.memoryUsage();
  console.log(`Memory usage after request ${requestId}:`);
  console.log(`- Heap Used: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)} MB`);
  console.log(`- Request count: ${Object.keys(requestData).length}`);

  res.end('Request processed');
});

server.listen(8080);
Misolni ishga tushirish »

Xotira oqishini tuzatish

Yuqoridagi misolda xotira oqishini qanday tuzatish mumkin:

const http = require('http');

// This object will store data for each request
const requestData = {};

const server = http.createServer((req, res) => {
  const requestId = Date.now() + Math.random().toString(36).substring(2, 15);


  // Store data in the global object
  requestData[requestId] = {
    url: req.url,
    method: req.method,
    timestamp: Date.now()
  };

  // Clean up after the response is sent (FIX FOR THE MEMORY LEAK)
  res.on('finish', () => {
    delete requestData[requestId];
    console.log(`Cleaned up request ${requestId}`);
  });

  res.end('Request processed');
});

server.listen(8080);
Misolni ishga tushirish »

Muhim: Voqealar tinglovchilari, taymerlar va keshlangan obyektlar kabi resurslar uchun har doim to‘g‘ri tozalash tartib-qoidalarini bajaring.

Kuchsiz havolalardan foydalanish yoki keshlangan elementlar uchun vaqtga asoslangan amal qilish muddatini qo‘llashni o‘ylab ko‘ring.


CPU profili va ishlashi

Protsessor profilini yaratish Node.js ilovangizda qaysi funksiyalar CPU vaqtini eng ko‘p sarflayotganini ko‘rsatish orqali unumdorlikdagi qiyinchiliklarni aniqlashga yordam beradi.

CPU profilini yaratish usullari

1. O‘rnatilgan Node.js Profiler

Node.js protsessor profillarini yaratish uchun foydalanishingiz mumkin bo‘lgan o‘rnatilgan V8 profilini o‘z ichiga oladi:

O‘rnatilgan V8 Profilerdan foydalanish

# Generate CPU profile
node --prof app.js

# Convert the generated log file to a readable format
node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt

Qayta ishlangan mahsulot dasturning umumiy bajarilish vaqtining ulushi bo‘yicha tartiblangan ilovangizda vaqt qayerga sarflanganligini ko‘rsatadi.

2. Chrome DevTools CPU Profiler

  1. Ilovangizni node --inspect app.js bilan boshlang
  2. Chrome DevTools bilan ulaning
  3. Ishlash yorlig‘iga o‘ting
  4. Yozib olish-ni bosing
  5. Profil qilmoqchi bo‘lgan amallarni bajaring
  6. Yozishni to‘xtating
  7. Olov jadvalini tahlil qiling

3. Uchinchi tomon profilini yaratish vositalari

  • clinic flame : CPU profilini yaratish uchun olov grafiklarini yarating
  • 0x : Flamegraf yaratish vositasi
  • v8-profiler : V8 protsessor profillarini dasturiy ravishda yig‘ing

Misol: CPU muammolarini aniqlash

Ushbu misol samarasiz kod naqshlarini qanday aniqlashni ko‘rsatadi:

// Inefficient recursive Fibonacci function
function inefficientFibonacci(n) {
  if (n <= 1) return n;
  return inefficientFibonacci(n - 1) + inefficientFibonacci(n - 2);
}

// More efficient iterative Fibonacci function
function efficientFibonacci(n) {
  if (n <= 1) return n;

  let a = 0, b = 1, temp;
  for (let i = 2; i <= n; i++) {
    temp = a + b;
    a = b;
    b = temp;
  }

  return b;
}

// Compare the performance
function comparePerformance(n) {
  console.log(`Calculating Fibonacci(${n})`);

  // Time the inefficient version
  const inefficientStart = process.hrtime.bigint();
  const inefficientResult = inefficientFibonacci(n);
  const inefficientEnd = process.hrtime.bigint();
  const inefficientTime = Number(inefficientEnd - inefficientStart) / 1_000_000; // in ms

  // Time the efficient version
  const efficientStart = process.hrtime.bigint();
  const efficientResult = efficientFibonacci(n);
  const efficientEnd = process.hrtime.bigint();
  const efficientTime = Number(efficientEnd - efficientStart) / 1_000_000; // in ms

  console.log(`Inefficient: ${inefficientResult} (${inefficientTime.toFixed(2)} ms)`);
  console.log(`Efficient: ${efficientResult} (${efficientTime.toFixed(2)} ms)`);
  console.log(`Speedup: ${Math.round(inefficientTime / efficientTime)}x`);
}

// Run the comparison
comparePerformance(30);
Misolni ishga tushirish »

CPU intensiv kodini optimallashtirish

CPU intensiv Node.js kodini optimallashtirishning umumiy usullari quyidagilarni o‘z ichiga oladi:

  • Rekursiyadan saqlaning: Yaxshiroq ishlash uchun iterativ yondashuvlardan foydalaning
  • Memoizatsiya: Qimmatbaho funksiya chaqiruvlarining kesh natijalari
  • Worker thread’larga yuklash: Protsessorni ko‘p talab qiladigan ishni alohida oqimlarga o‘tkazing
  • Native modullardan foydalaning: Ishlash uchun juda muhim kod uchun C++ qo‘shimchalarini ko‘rib chiqing.
  • Voqealar davrini blokirovka qilishdan saqlaning: Katta vazifalarni kichikroq qismlarga bo‘ling

Asinxron kodni tuzatish

Asinxron kod chiziqli bo‘lmagan bajarilish oqimi va murakkab xatolar tarqalishi tufayli debug qilish qiyin bo‘lishi mumkin.

Async debug’dagi umumiy muammolar

  • Yo‘qotilgan xato konteksti: Callback-larda yuborilgan xatolar stek izini yo‘qotishi mumkin
  • Callback hell: O‘rnatilgan callback funksiyasilar ijro jarayonini kuzatishni qiyinlashtiradi
  • Promise zanjirlari: Agar noto‘g‘ri ushlanmasa, xatolar yutib yuborilishi mumkin
  • Poyga shartlari: Qayta ishlab chiqarish qiyin bo‘lgan vaqtga bog‘liq xatolar
  • Ko‘rib chiqilmagan rad etishlar: Tutqich ishlovchilarsiz rad etiladigan Promiselar

Async debug usullari

1. Try/Catch bilan Async/Await-dan foydalaning

Async/await an’anaviy try/catch bloklaridan foydalanish imkonini berib, asinxron kodni debug qilishni osonlashtiradi:

// Hard to debug
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => processData(data))
  .catch(error => console.error('Error:', error));

// Easier to debug
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return processData(data);
  } catch (error) {
    console.error('Error:', error);
    throw error; // Re-throw for upper layers to handle
  }
}

2. Async kodida uzilish nuqtalarini o‘rnating

Chrome DevTools yoki VS Code-da debug paytida siz asinxronizatsiya funksiyalari ichida to‘xtash nuqtalarini o‘rnatishingiz va callback funksiyasilarni Promise qilishingiz mumkin.

Nosozliklarni tuzatuvchi ushbu nuqtalarda bajarishni to‘xtatib qo‘yadi, bu sizga joriy holatni tekshirish imkonini beradi.

3. Async Stack Traces funksiyasini yoqing

Zamonaviy tuzatuvchilar asinxron operatsiyalarning to‘liq zanjirini ko‘rsatadigan asinxron stek izlarini olishi va ko‘rsatishi mumkin:

  • Chrome DevTools-da Call Stack panelida "Async" ni yoqing
  • VS kodida bu sukut bo‘yicha yoqilgan

Misol: Asinxron kodini tuzatish

Asenk nosozliklarni tuzatish usullarini ko‘rsatadigan misol:

const util = require('util');
const fs = require('fs');

// Convert callbacks to promises
const readFile = util.promisify(fs.readFile);

// Function with a nested chain of async operations
async function processUserData(userId) {
  try {
    console.log(`Processing data for user ${userId}...`);
    
    // Fetch user data
    const userData = await fetchUserData(userId);
    console.log(`User data retrieved: ${userData.name}`);

    // Get user posts
    const posts = await getUserPosts(userId);
    console.log(`Retrieved ${posts.length} posts for user`);

    // Process posts (this will cause an error for userId = 3)
    const processedPosts = posts.map(post => {
      return {
        id: post.id,
        title: post.title.toUpperCase(),
        contentLength: post.content.length, // Will fail if content is undefined
      };
    });
    return { user: userData, posts: processedPosts };
   } catch (error) {
    console.error('Error processing user data:', error);
    throw error;
  }
}

// Simulated API call
function fetchUserData(userId) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (userId <= 0) {
        reject(new Error('Invalid user ID'));
      } else {
        resolve({ id: userId, name: `User ${userId}` });
      }
    }, 500);
  });
}

// Simulated database query
function getUserPosts(userId) {
  return new Promise((resolve) => {
    setTimeout(() => {
      // Bug: post with undefined content for userId 3
      if (userId === 3) {
        resolve([
          { id: 1, title: 'First Post', content: 'Content' },
          { id: 2, title: 'Second Post', content: undefined }
        ]);
      } else {
        resolve([
          { id: 1, title: 'First Post', content: 'Content' },
          { id: 2, title: 'Second Post', content: 'More content' }
        ]);
      }
    }, 300);
  });
}

// Usage
processUserData(3).catch(err => console.log('Caught at top level:', err.message));
Misolni ishga tushirish »

Asinxron kodni tuzatish bo‘yicha maslahatlar:

  • Ko‘proq chiziqli, tuzatiladigan kod uchun async/wait dan foydalaning
  • Asinxron chegaralari bo‘ylab operatsiyalarni kuzatish uchun korrelyatsiya identifikatorlarini qo‘shing
  • unhandledRejection va uncaughtException voqealarini tinglang
  • Muayyan nuqtalarda stek izlarini qayd qilish uchun console.trace() dan foydalaning
  • Ichki Node.js debug jurnallarini ko‘rish uchun NODE_DEBUG=* o‘rnating



W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!