Node.js Advanced Debugging

மேம்பட்ட பிழைத்திருத்த நுட்பங்கள் மற்றும் கருவிகளைக் கற்றுக்கொள்ளுங்கள்

மேம்பட்ட பிழைத்திருத்தத்திற்கான அறிமுகம்

திறம்பட்ட பிழைத்திருத்தம் Node.js டெவலப்பர்களுக்கு ஒரு முக்கியமான திறனாகும்.

console.log() அடிப்படை பிழைத்திருத்தத்திற்கு பயனுள்ளதாக இருந்தாலும், நினைவக கசிவுகள், செயல்திறன் தடைகள் மற்றும் பந்தய நிலைமைகள் போன்ற சிக்கலான பிரச்சினைகளை கண்டறிய மேம்பட்ட நுட்பங்கள் உங்களை அனுமதிக்கின்றன.

இந்த டுடோரியல் உங்கள் Node.js பயன்பாடுகளில் சவாலான பிரச்சினைகளை தீர்க்க உதவும் மேம்பட்ட பிழைத்திருத்த நுட்பங்கள் மற்றும் கருவிகளை உள்ளடக்கியது.

மேம்பட்ட பிழைத்திருத்த கருவிகள் பின்வரும் திறன்களை வழங்குகின்றன:

பிரேக்பாயிண்ட்களை அமைத்தல்

குறியீட்டு செயல்பாட்டின் மூலம் படிப்படியாக செல்லவும்

மாறி மதிப்புகளை ஆய்வு செய்தல்

இயக்க நேரத்தில் மாறி மதிப்புகளை ஆய்வு செய்யவும்

நினைவக பயன்பாட்டை காட்சிப்படுத்துதல்

நினைவக நுகர்வை காட்சிப்படுத்தி கசிவுகளைக் கண்டறியவும்

CPU பயன்பாட்டை சுயவிவரப்படுத்துதல்

செயல்திறன் தடைகளை அடையாளம் காண CPU பயன்பாட்டை சுயவிவரப்படுத்தவும்

Chrome DevTools உடன் பிழைத்திருத்தம்

Node.js உங்கள் Node.js பயன்பாடுகளை பிழைத்திருத்த சக்திவாய்ந்த Chrome DevTools இடைமுகத்தைப் பயன்படுத்த உங்களை அனுமதிக்கும் Chrome DevTools பிழைத்திருத்த நெறிமுறைக்கான உள்ளமைக்கப்பட்ட ஆதரவை உள்ளடக்கியது.

பிழைத்திருத்த முறையில் Node.js ஐத் தொடங்குதல்

பிழைத்திருத்த முறையில் உங்கள் பயன்பாட்டைத் தொடங்க பல வழிகள் உள்ளன:

நிலையான பிழைத்திருத்த முறை

node --inspect app.js

இது உங்கள் பயன்பாட்டை சாதாரணமாக தொடங்குகிறது ஆனால் போர்ட் 9229 இல் இன்ஸ்பெக்டரை இயக்குகிறது.

தொடக்கத்தில் இடைநிறுத்து

node --inspect-brk app.js

இது குறியீட்டின் முதல் வரியில் செயல்பாட்டை இடைநிறுத்துகிறது, செயல்படுத்துவதற்கு முன் பிரேக்பாயிண்ட்களை அமைக்க உங்களை அனுமதிக்கிறது.

தனிப்பயன் போர்ட்

node --inspect=127.0.0.1:9222 app.js

இது இன்ஸ்பெக்டருக்கு ஒரு தனிப்பயன் போர்டைப் பயன்படுத்துகிறது.

பிழைத்திருத்தியுடன் இணைத்தல்

உங்கள் Node.js பயன்பாட்டை inspect கொடியுடன் தொடங்கிய பிறகு, நீங்கள் பல வழிகளில் இணையலாம்:

Chrome DevTools:

Chrome ஐத் திறந்து chrome://inspect க்குச் செல்லவும்.

உங்கள் Node.js பயன்பாடு "ரிமோட் டார்கெட்" கீழ் பட்டியலிடப்பட்டதை நீங்கள் காண வேண்டும்.

பயன்பாட்டுடன் இணைக்கப்பட்ட DevTools ஐத் திறக்க "inspect" ஐக் கிளிக் செய்யவும்:

Chrome DevTools for Node.js

Chrome DevTools for Node.js - பயன்பாட்டுடன் இணைக்கப்பட்ட DevTools இடைமுகம்

💡 தொழில்நுட்ப குறிப்பு:

Sources பேனலின் "Pause on caught exceptions" அம்சத்தை (வளைந்த கோடுகளுடன் கூடிய இடைநிறுத்தும் பொத்தான்) ஒரு பிழை ஏற்படும் போது தானாக உடைக்க பயன்படுத்தவும்.

VS Code இல் பிழைத்திருத்தம்

விசுவல் ஸ்டுடியோ கோட் Node.js பயன்பாடுகளுக்கு சிறந்த உள்ளமைக்கப்பட்ட பிழைத்திருத்த திறன்களை வழங்குகிறது.

VS Code இல் Node.js பிழைத்திருத்தத்தை அமைத்தல்

உங்கள் Node.js பயன்பாட்டை VS Code இல் பிழைத்திருத்த பல வழிகளில் தொடங்கலாம்:

launch.json கட்டமைப்பு

VS Code உங்கள் பயன்பாட்டை எவ்வாறு தொடங்க வேண்டும் அல்லது இணைக்க வேண்டும் என வரையறுக்க .vscode/launch.json கோப்பை உருவாக்கவும்

தானியங்கி-இணைப்பு

--inspect கொடியுடன் தொடங்கப்பட்ட எந்த Node.js செயல்முறையையும் தானாக பிழைத்திருத்த VS Code அமைப்புகளில் தானியங்கி-இணைப்பை இயக்கவும்

JavaScript பிழைத்திருத்த டெர்மினல்

அந்த டெர்மினலில் இருந்து தொடங்கப்பட்ட எந்த Node.js செயல்முறையையும் தானாக பிழைத்திருத்த VS Code இல் JavaScript பிழைத்திருத்த டெர்மினலைப் பயன்படுத்தவும்

launch.json கட்டமைப்பு எடுத்துக்காட்டு

{
  "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 Code TypeScript கோப்புகளை நேரடியாக பிழைத்திருத்த முடியும், மூல வரைபடங்கள் மொழிபெயர்க்கப்பட்ட JavaScript குறியீட்டை விட அசல் TypeScript குறியீட்டை பிழைத்திருத்த இயக்குகின்றன.

Debug தொகுதியைப் பயன்படுத்துதல்

debug தொகுதி என்பது ஒரு இலகுவான பிழைத்திருத்த பயன்பாடாகும், இது உங்கள் Node.js பயன்பாடுகளில் console.log அறிக்கைகளுடன் உங்கள் குறியீட்டை குழப்பாமல் நிபந்தனை லாக்கிங்கைச் சேர்ப்பதற்கு உங்களை அனுமதிக்கிறது.

Debug தொகுதியை நிறுவுதல்

npm install debug

Debug இன் அடிப்படை பயன்பாடு

debug தொகுதி சூழல் மாறிகள் மூலம் இயக்கப்படும் அல்லது முடக்கப்படும் பெயர்வெளி debug செயல்பாடுகளை உருவாக்க உங்களை அனுமதிக்கிறது:

// உங்கள் பயன்பாட்டின் வெவ்வேறு பகுதிகளுக்கு பெயர்வெளி debuggers உருவாக்கவும்
const debug = require('debug');

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

// உங்கள் குறியீட்டில் debuggers பயன்படுத்தவும்
debugServer('Server starting on port %d', 8080);
debugDatabase('Connected to database: %s', 'mongodb://localhost');
debugAuth('User %s authenticated', 'john@example.com');

// இயல்புநிலையாக, இந்த debug செய்திகள் வெளியீட்டில் தோன்றாது

Debug வெளியீட்டை இயக்குதல்

debug வெளியீட்டைக் காண, DEBUG சூழல் மாறியை காற்புள்ளி-பிரிக்கப்பட்ட பெயர்வெளி வடிவங்களின் பட்டியலாக அமைக்கவும்:

அனைத்து Debug வெளியீட்டையும் இயக்கவும்

DEBUG=app:* node app.js

குறிப்பிட்ட பெயர்வெளிகளை இயக்கவும்

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

அனைத்தையும் இயக்கவும் ஆனால் சிலவற்றை விலக்கவும்

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

🚀 சிறந்த நடைமுறை:

தற்போது நீங்கள் பழுதுபார்க்கும் விஷயத்தின் அடிப்படையில் debug வெளியீட்டை வடிகட்ட எளிதாக்க உங்கள் பயன்பாட்டின் வெவ்வேறு கூறுகளுக்கு குறிப்பிட்ட பெயர்வெளிகளைப் பயன்படுத்தவும்.

நினைவக கசிவுகளைக் கண்டறிதல் மற்றும் சரிசெய்தல்

Node.js பயன்பாடுகளில் நினைவக கசிவுகள் செயல்திறன் சீரழிவு மற்றும் இறுதி விபத்துக்களை ஏற்படுத்தும்.

நினைவக கசிவுகளைக் கண்டறிந்து சரிசெய்வது ஒரு முக்கியமான பிழைத்திருத்த திறமையாகும்.

Node.js இல் நினைவக கசிவுகளின் பொதுவான காரணங்கள்

உலகளாவிய மாறிகள்

ஒருபோதும் சுத்தம் செய்யப்படாத உலகளாவிய நோக்கத்தில் சேமிக்கப்பட்ட பொருள்கள்

மூடல்கள்

பெரிய பொருள்கள் அல்லது மாறிகளுக்கான குறிப்புகளை பராமரிக்கும் செயல்பாடுகள்

நிகழ்வு கேட்பவர்கள்

சேர்க்கப்பட்ட ஆனால் ஒருபோதும் அகற்றப்படாத கேட்பவர்கள்

கேச்கள்

வரம்புகள் இல்லாமல் வளரும் நினைவக கேச்கள்

நினைவக கசிவுகளைக் கண்டறிதல்

நினைவக கசிவுகளைக் கண்டறிய பல அணுகுமுறைகள் உதவும்:

1. நினைவக பயன்பாட்டைக் கண்காணிக்கவும்

// நினைவக பயன்பாட்டைக் கண்காணிக்கவும்
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`);
}

// ஒவ்வொரு 30 வினாடிகளுக்கும் நினைவக பயன்பாட்டை பதிவு செய்யவும்
setInterval(logMemoryUsage, 30000);

எடுத்துக்காட்டு: Node.js சேவையகத்தில் நினைவக கசிவு

இங்கே ஒரு Node.js சேவையகத்தில் ஒரு பொதுவான நினைவக கசிவு முறையைக் காட்டும் ஒரு எடுத்துக்காட்டு உள்ளது:

const http = require('http');

// இந்த பொருள் ஒவ்வொரு கோரிக்கைக்கும் தரவை சேமிக்கும் (நினைவக கசிவு!)
const requestData = {};

const server = http.createServer((req, res) => {
  // ஒரு தனித்துவமான கோரிக்கை ID ஐ உருவாக்கவும்
  const requestId = Date.now() + Math.random().toString(36).substring(2, 15);

  // உலகளாவிய பொருளில் தரவை சேமிக்கவும் (இது நினைவக கசிவு!)
  requestData[requestId] = {
    url: req.url,
    method: req.method,
    headers: req.headers,
    timestamp: Date.now(),
    // கசிவை மிகவும் வெளிப்படையாக்க ஒரு பெரிய பொருளை உருவாக்கவும்
    payload: Buffer.alloc(1024 * 1024) // கோரிக்கைக்கு 1MB ஒதுக்கவும்
  };

  // ஒவ்வொரு கோரிக்கைக்கும் பிறகு நினைவக பயன்பாட்டை பதிவு செய்யவும்
  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);

நினைவக கசிவை சரிசெய்தல்

மேலே உள்ள எடுத்துக்காட்டில் நினைவக கசிவை எவ்வாறு சரிசெய்வது என்பது இங்கே:

const http = require('http');

// இந்த பொருள் ஒவ்வொரு கோரிக்கைக்கும் தரவை சேமிக்கும்
const requestData = {};

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

  // உலகளாவிய பொருளில் தரவை சேமிக்கவும்
  requestData[requestId] = {
    url: req.url,
    method: req.method,
    timestamp: Date.now()
  };

  // பதில் அனுப்பப்பட்ட பிறகு சுத்தம் செய்யவும் (நினைவக கசிவுக்கான தீர்வு)
  res.on('finish', () => {
    delete requestData[requestId];
    console.log(`Cleaned up request ${requestId}`);
  });

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

server.listen(8080);

⚠️ முக்கியமானது:

நிகழ்வு கேட்பவர்கள், டைமர்கள் மற்றும் கேச் செய்யப்பட்ட பொருள்கள் போன்ற வளங்களுக்கு எப்போதும் சரியான சுத்தம் செய்யும் வழிகளைச் செயல்படுத்தவும்.

கேச் செய்யப்பட்ட பொருள்களுக்கு பலவீனமான குறிப்புகளைப் பயன்படுத்துவதைக் கவனியுங்கள் அல்லது நேர அடிப்படையிலான காலாவதியை செயல்படுத்தவும்.

CPU சுயவிவரப்படுத்தல் மற்றும் செயல்திறன்

CPU சுயவிவரப்படுத்தல் உங்கள் Node.js பயன்பாட்டில் செயல்திறன் தடைகளை அடையாளம் காண உதவுகிறது, எந்த செயல்பாடுகள் அதிக CPU நேரத்தை நுகர்கின்றன என்பதைக் காட்டுகிறது.

CPU சுயவிவரப்படுத்தல் முறைகள்

1. உள்ளமைக்கப்பட்ட Node.js சுயவிவரப்படுத்தி

Node.js CPU சுயவிவரங்களை உருவாக்க பயன்படுத்தக்கூடிய ஒரு உள்ளமைக்கப்பட்ட V8 சுயவிவரப்படுத்தியை உள்ளடக்கியது:

# CPU சுயவிவரத்தை உருவாக்கவும்
node --prof app.js

# உருவாக்கப்பட்ட பதிவு கோப்பை ஒரு வாசிக்கக்கூடிய வடிவமைப்பிற்கு மாற்றவும்
node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt

எடுத்துக்காட்டு: CPU தடைகளை அடையாளம் காணுதல்

இந்த எடுத்துக்காட்டு திறனற்ற குறியீட்டு முறைகளை அடையாளம் காண எவ்வாறு நிரூபிக்கிறது:

// திறனற்ற சுழல்நிலை Fibonacci செயல்பாடு
function inefficientFibonacci(n) {
  if (n <= 1) return n;
  return inefficientFibonacci(n - 1) + inefficientFibonacci(n - 2);
}

// மிகவும் திறன்மிக்க மீள் செயல்பாட்டு Fibonacci செயல்பாடு
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;
}

// செயல்திறனை ஒப்பிடுக
function comparePerformance(n) {
  console.log(`Calculating Fibonacci(${n})`);

  // திறனற்ற பதிப்பை நேரம் கணக்கிடவும்
  const inefficientStart = process.hrtime.bigint();
  const inefficientResult = inefficientFibonacci(n);
  const inefficientEnd = process.hrtime.bigint();
  const inefficientTime = Number(inefficientEnd - inefficientStart) / 1_000_000; // in ms

  // திறன்மிக்க பதிப்பை நேரம் கணக்கிடவும்
  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`);
}

// ஒப்பீட்டை இயக்கவும்
comparePerformance(30);

அசிங்க்ரோனஸ் குறியீட்டை பிழைத்திருத்துதல்

அசிங்க்ரோனஸ் குறியீடு அதன் நேரியல்-அல்லாத செயல்பாட்டு ஓட்டம் மற்றும் சிக்கலான பிழை பரப்பு காரணமாக பிழைத்திருத்த சவாலாக இருக்கலாம்.

Async பிழைத்திருத்தத்தில் பொதுவான சவால்கள்

இழந்த பிழை சூழல்

கால்பேக்குகளில் வீசப்பட்ட பிழைகள் அவற்றின் ஸ்டாக் ட்ரேஸை இழக்கக்கூடும்

கால்பேக் நரகம்

உள்ளமைக்கப்பட்ட கால்பேக்குகள் செயல்பாட்டு ஓட்டத்தைக் கண்டறிய கடினமாக்குகின்றன

வாக்குறுதி சங்கிலிகள்

பிழைகள் சரியாகப் பிடிக்கப்படாவிட்டால் விழுங்கப்படக்கூடும்

பந்தய நிலைமைகள்

மீண்டும் உருவாக்க கடினமான நேரம்-சார்ந்த பிழைகள்

Async பிழைத்திருத்த நுட்பங்கள்

1. Try/Catch உடன் Async/Await ஐப் பயன்படுத்தவும்

Async/await பாரம்பரிய try/catch தொகுதிகளைப் பயன்படுத்த உங்களை அனுமதிப்பதன் மூலம் அசிங்க்ரோனஸ் குறியீட்டை பிழைத்திருத்த எளிதாக்குகிறது:

// பிழைத்திருத்த கடினம்
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => processData(data))
  .catch(error => console.error('Error:', error));

// பிழைத்திருத்த எளிதானது
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; // கையாள மேல் அடுக்குகளுக்கு மீண்டும் வீசவும்
  }
}

எடுத்துக்காட்டு: Async குறியீட்டை பிழைத்திருத்துதல்

இங்கே async பிழைத்திருத்த நுட்பங்களை நிரூபிக்கும் ஒரு எடுத்துக்காட்டு உள்ளது:

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

// கால்பேக்குகளை வாக்குறுதிகளாக மாற்றவும்
const readFile = util.promisify(fs.readFile);

// உள்ளமைக்கப்பட்ட async செயல்பாடுகளின் சங்கிலியுடன் செயல்பாடு
async function processUserData(userId) {
  try {
    console.log(`Processing data for user ${userId}...`);
    
    // பயனர் தரவைப் பெறவும்
    const userData = await fetchUserData(userId);
    console.log(`User data retrieved: ${userData.name}`);

    // பயனர் இடுகைகளைப் பெறவும்
    const posts = await getUserPosts(userId);
    console.log(`Retrieved ${posts.length} posts for user`);

    // இடுகைகளை செயலாக்கவும் (இது userId = 3 க்கு ஒரு பிழையை ஏற்படுத்தும்)
    const processedPosts = posts.map(post => {
      return {
        id: post.id,
        title: post.title.toUpperCase(),
        contentLength: post.content.length, // content வரையறுக்கப்படவில்லை என்றால் தோல்வியடையும்
      };
    });
    return { user: userData, posts: processedPosts };
   } catch (error) {
    console.error('Error processing user data:', error);
    throw error;
  }
}

// உருவகப்படுத்தப்பட்ட API அழைப்பு
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);
  });
}

// உருவகப்படுத்தப்பட்ட தரவுத்தள வினா
function getUserPosts(userId) {
  return new Promise((resolve) => {
    setTimeout(() => {
      // பிழை: 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);
  });
}

// பயன்பாடு
processUserData(3).catch(err => console.log('Caught at top level:', err.message));

பயிற்சி

______ தொகுதி Node.js இல் பிழைத்திருத்தத்தில் உதவுகிறது.

console
✗ தவறு! console தொகுதி அடிப்படை லாக்கிங்கிற்கு பயனுள்ளதாக இருக்கிறது, ஆனால் debug தொகுதி போன்ற மேம்பட்ட பிழைத்திருத்த அம்சங்களை வழங்காது
util
✗ தவறு! util தொகுதி பயன்பாட்டு செயல்பாடுகளை வழங்குகிறது, ஆனால் இது குறிப்பாக பிழைத்திருத்தத்திற்காக வடிவமைக்கப்படவில்லை
debug
✓ சரி! debug தொகுதி நிபந்தனை லாக்கிங்கைச் சேர்ப்பதன் மூலம் Node.js இல் பிழைத்திருத்தத்தில் உதவுகிறது, இது உங்கள் குறியீட்டை console.log அறிக்கைகளுடன் குழப்பாமல் பெயர்வெளி debug செயல்பாடுகளை உருவாக்க உங்களை அனுமதிக்கிறது
error
✗ தவறு! error தொகுதி ஒரு நிலையான Node.js தொகுதி அல்ல, மேலும் debug தொகுதி போன்ற பிழைத்திருத்த அம்சங்களை வழங்காது