Agent ma’lumotnomasi


ULASHISH

Agent obyekti

Node.js’dagi Agent klassi ulanishning barqarorligini boshqarish va HTTP/HTTPS mijoz so‘rovlari uchun qayta foydalanish uchun javobgardir. U ma’lum bir xost va port uchun kutilayotgan so‘rovlar navbatini saqlaydi va shu xost va portga har bir parvoz so‘rovi uchun bitta soket ulanishidan qayta foydalanadi.

Ikkita asosiy Agent ilovalari mavjud:

  • http.Agent - HTTP ulanishlarini boshqarish uchun
  • https.Agent - HTTPS ulanishlarini boshqarish uchun

Import qiluvchi agent

// Import HTTP module
const http = require('http');

// The default agent
const defaultAgent = http.globalAgent;

// Create a custom agent
const customAgent = new http.Agent({
  keepAlive: true,
  maxSockets: 25
});
Misolni ishga tushirish »

Agent xususiyatlari

Xususiyat Tavsif
agent.freeSockets keepAlive yoqilganda Agent tomonidan hozirda foydalanishni kutayotgan soketlarni o‘z ichiga olgan obyekt. To‘g‘ridan-to‘g‘ri o‘zgartirilmaydi.
agent.maxFreeSockets Erkin holatda ochiq qoladigan soketlarning maksimal sonini belgilaydi. keepAlive true ga o‘rnatilgan bo‘lsagina tegishli. Standart: 256.
agent.maxSockets Agent har bir kelib chiqishi uchun ochiq bo‘lishi mumkin bo‘lgan maksimal soketlar sonini belgilaydi. Standart: Infinity.
agent.maxTotalSockets Barcha manbalarda ochiq bo‘lishi mumkin bo‘lgan soketlarning maksimal sonini belgilaydi. Standart: Infinity.
agent.requests Soketlarga hali tayinlanmagan navbatdagi so‘rovlarni o‘z ichiga olgan obyekt. To‘g‘ridan-to‘g‘ri o‘zgartirilmaydi.
agent.sockets Agent tomonidan hozirda foydalanilayotgan soketlar massivlarini o‘z ichiga olgan obyekt. To‘g‘ridan-to‘g‘ri o‘zgartirilmaydi.


Agent usullari

Metod Tavsif
agent.createConnection(options[, callback]) HTTP so‘rovlari uchun ishlatiladigan soket/stream yaratadi. Odatiy bo‘lib, bu funksiya net.createConnection() dan foydalanadi, lekin uni bekor qilish mumkin.
agent.destroy() Agent tomonidan hozirda ishlatilayotgan har qanday soketlarni yo‘q qiladi.
agent.getName(options) Ulanishni qayta ishlatish mumkinligini aniqlash uchun so‘rov opsiyalari to‘plami uchun noyob nom oladi.
agent.keepSocketAlive(socket) socket so‘rovdan ajratilganda va Agent uni saqlab qolishi mumkin bo‘lganda chaqiriladi. Standart xatti-harakat — soketni freeSockets ro‘yxatiga qo‘shish.
agent.reuseSocket(socket, request) socket request ga biriktirilganda, jonli saqlash parametrlari tufayli davom ettirilgandan keyin chaqiriladi.

Standart agentdan foydalanish

Odatiy bo‘lib, HTTP/HTTPS mijoz so‘rovlari global agentdan foydalanadi ( http.globalAgent yoki https.globalAgent ):

const http = require('http');

// Make a request using the default agent
http.get('http://example.com', (res) => {
  console.log(`Status Code: ${res.statusCode}`);
  
  // Display global agent information
  const agent = http.globalAgent;
  console.log(`Current sockets: ${Object.keys(agent.sockets).length}`);
  console.log(`Free sockets: ${Object.keys(agent.freeSockets).length}`);
  console.log(`Queued requests: ${Object.keys(agent.requests).length}`);
  
  // Consume response data
  res.resume();
}).on('error', (err) => {
  console.error(`Error: ${err.message}`);
});
Misolni ishga tushirish »

Maxsus agent yaratish

Siz maxsus sozlamalarga ega maxsus agent yaratishingiz mumkin:

const http = require('http');

// Create a custom agent with keep-alive enabled
const keepAliveAgent = new http.Agent({
  keepAlive: true,           // Keep connections open for reuse
  keepAliveMsecs: 1000,      // Milliseconds to wait before sending TCP KeepAlive packet
  maxSockets: 10,            // Maximum number of sockets per host
  maxFreeSockets: 5,         // Maximum number of idle sockets when keepAlive is true
  timeout: 60000,            // Socket timeout in milliseconds
  scheduling: 'fifo'         // FIFO request scheduling (instead of LIFO)
});

// Make a request using the custom agent
const options = {
  hostname: 'example.com',
  path: '/',
  method: 'GET',
  agent: keepAliveAgent     // Use our custom agent
};

const req = http.request(options, (res) => {
  console.log(`Status Code: ${res.statusCode}`);
  
  // Display custom agent information
  console.log(`Current sockets: ${Object.keys(keepAliveAgent.sockets).length}`);
  console.log(`Free sockets: ${Object.keys(keepAliveAgent.freeSockets).length}`);
  
  // Consume response data
  res.resume();
  
  // Make a second request to demonstrate socket reuse
  setTimeout(() => {
    console.log('Making second request to demonstrate socket reuse...');
    
    http.request(options, (res2) => {
      console.log(`Second request status: ${res2.statusCode}`);
      console.log(`Current sockets: ${Object.keys(keepAliveAgent.sockets).length}`);
      console.log(`Free sockets: ${Object.keys(keepAliveAgent.freeSockets).length}`);
      
      // Cleanup
      setTimeout(() => {
        keepAliveAgent.destroy();
        console.log('Agent destroyed');
      }, 1000);
      
      res2.resume();
    }).end();
  }, 2000);
});

req.on('error', (err) => {
  console.error(`Error: ${err.message}`);
});

req.end();
Misolni ishga tushirish »

HTTPS agenti

HTTPS so‘rovlari uchun qo‘shimcha SSL/TLS opsiyalari bilan HTTPSga xos agent yaratishingiz mumkin:

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

// Create a custom HTTPS agent with SSL options
const httpsAgent = new https.Agent({
  keepAlive: true,
  maxSockets: 10,
  // SSL/TLS options
  ca: fs.readFileSync('ca-cert.pem'),      // Certificate authority
  cert: fs.readFileSync('client-cert.pem'), // Client certificate
  key: fs.readFileSync('client-key.pem'),   // Client private key
  // Additional TLS options
  rejectUnauthorized: true,                // Verify server certificate
  secureProtocol: 'TLSv1_2_method',        // Use TLS v1.2
  ciphers: 'HIGH:!aNULL:!MD5',             // Set allowed ciphers
  honorCipherOrder: true                    // Honor cipher order
});

// Make a secure request using the HTTPS agent
const options = {
  hostname: 'secure-example.com',
  path: '/',
  method: 'GET',
  agent: httpsAgent
};

const req = https.request(options, (res) => {
  console.log(`Status Code: ${res.statusCode}`);
  
  // Display the TLS/SSL-specific information
  console.log(`TLS Protocol: ${res.socket.getProtocol()}`);
  console.log(`Cipher: ${res.socket.getCipher().name}`);
  console.log(`Server Certificate Valid: ${res.socket.authorized}`);
  
  // Consume response data
  res.resume();
  
  // Cleanup
  setTimeout(() => {
    httpsAgent.destroy();
    console.log('HTTPS Agent destroyed');
  }, 1000);
});

req.on('error', (err) => {
  console.error(`Error: ${err.message}`);
});

req.end();
Misolni ishga tushirish »

Ulanishni birlashtirishni o‘chirish

Agentni false ga o‘rnatish orqali ulanishlar pulini (connection pooling) o‘chirib qo‘yishingiz mumkin:

const http = require('http');

// Make a request with agent: false to disable connection pooling
const options = {
  hostname: 'example.com',
  path: '/',
  method: 'GET',
  agent: false  // Disable connection pooling
};

const req = http.request(options, (res) => {
  console.log(`Status Code: ${res.statusCode}`);
  console.log('Using a new connection (no agent)');
  
  // Consume response data
  res.resume();
});

req.on('error', (err) => {
  console.error(`Error: ${err.message}`);
});

req.end();
Misolni ishga tushirish »

Ulanishni birlashtirish misoli

Ushbu misol bir nechta so‘rovlar bilan ulanishni birlashtirishning ishlash afzalliklarini ko‘rsatadi:

const http = require('http');
const { performance } = require('perf_hooks');

// Function to make multiple requests with a given agent
async function makeMultipleRequests(useAgent, numRequests = 10) {
  // Define the target
  const hostname = 'example.com';
  const path = '/';
  
  // Choose agent
  const agent = useAgent ? new http.Agent({ keepAlive: true }) : false;
  
  console.log(`Making ${numRequests} requests with ${useAgent ? 'custom agent' : 'no agent'}`);
  const startTime = performance.now();
  
  // Make multiple requests
  for (let i = 0; i < numRequests; i++) {
    await new Promise((resolve, reject) => {
      const req = http.request({
        hostname,
        path,
        method: 'GET',
        agent
      }, (res) => {
        // Consume response data
        res.resume();
        res.on('end', () => {
          resolve();
        });
      });
      
      req.on('error', (err) => {
        console.error(`Request ${i + 1} error: ${err.message}`);
        reject(err);
      });
      
      req.end();
    }).catch(() => {}); // Catch to continue the loop even if a request fails
  }
  
  const endTime = performance.now();
  console.log(`Time taken: ${(endTime - startTime).toFixed(2)}ms`);
  
  // Cleanup
  if (useAgent && agent) {
    agent.destroy();
  }
  
  return endTime - startTime;
}

// Run the comparison
async function runComparison() {
  console.log('Testing HTTP request performance with and without Agent');
  console.log('----------------------------------------------------');
  
  // With no agent (no connection pooling)
  const timeWithoutAgent = await makeMultipleRequests(false);
  
  console.log(''); // Separator
  
  // With agent (connection pooling)
  const timeWithAgent = await makeMultipleRequests(true);
  
  console.log(''); // Separator
  console.log('Results:');
  console.log(`Without agent: ${timeWithoutAgent.toFixed(2)}ms`);
  console.log(`With agent: ${timeWithAgent.toFixed(2)}ms`);
  console.log(`Difference: ${(timeWithoutAgent - timeWithAgent).toFixed(2)}ms`);
  console.log(`Performance improvement: ${(100 * (timeWithoutAgent - timeWithAgent) / timeWithoutAgent).toFixed(2)}%`);
}

// Run the comparison
runComparison().catch(console.error);
Misolni ishga tushirish »

Proksi-agent yaratish

Proksi-agent yaratish uchun Agent sinfini kengaytirishingiz mumkin:

const http = require('http');
const net = require('net');
const { URL } = require('url');

// A simple HTTP proxy agent implementation
class HttpProxyAgent extends http.Agent {
  constructor(proxyUri, options = {}) {
    super(options);
    this.proxyUri = new URL(proxyUri);
  }
  
  // Override createConnection to connect through the proxy
  createConnection(options, callback) {
    // Connect to the proxy server
    const proxySocket = net.connect({
      host: this.proxyUri.hostname,
      port: this.proxyUri.port || 80,
    }, () => {
      // Create the HTTP CONNECT request to the target through the proxy
      proxySocket.write(
        `CONNECT ${options.host}:${options.port} HTTP/1.1\r\n` +
        `Host: ${options.host}:${options.port}\r\n` +
        `Proxy-Connection: keep-alive\r\n` +
        // Add proxy authentication if provided
        (this.proxyUri.username && this.proxyUri.password
          ? `Proxy-Authorization: Basic ${Buffer.from(
              `${this.proxyUri.username}:${this.proxyUri.password}`
            ).toString('base64')}\r\n`
          : '') +
        '\r\n'
      );
      
      // Data handler for proxy response
      let proxyResponse = '';
      const onData = (chunk) => {
        proxyResponse += chunk.toString();
        
        // Check if we've received the full proxy response
        if (proxyResponse.includes('\r\n\r\n')) {
          // Parse status line
          const statusLine = proxyResponse.split('\r\n')[0];
          const statusCode = parseInt(statusLine.split(' ')[1], 10);
          
          // If the proxy connection was successful
          if (statusCode === 200) {
            // Remove data listener, we don't need it anymore
            proxySocket.removeListener('data', onData);
            
            // Callback with the socket
            callback(null, proxySocket);
          } else {
            // Proxy connection failed
            proxySocket.destroy();
            callback(new Error(`Proxy connection failed: ${statusLine}`));
          }
        }
      };
      
      proxySocket.on('data', onData);
    });
    
    // Handle socket errors
    proxySocket.on('error', (err) => {
      callback(err);
    });
    
    return proxySocket;
  }
}

// Example usage of the proxy agent
const proxyAgent = new HttpProxyAgent('http://proxy.example.com:8080', {
  keepAlive: true
});

// Make a request through the proxy
const options = {
  hostname: 'target-site.com',
  path: '/',
  method: 'GET',
  agent: proxyAgent
};

const req = http.request(options, (res) => {
  console.log(`Status Code: ${res.statusCode}`);
  
  // Consume response data
  res.resume();
  
  // Cleanup
  setTimeout(() => {
    proxyAgent.destroy();
    console.log('Proxy Agent destroyed');
  }, 1000);
});

req.on('error', (err) => {
  console.error(`Error: ${err.message}`);
});

req.end();
Misolni ishga tushirish »

Eng yaxshi amaliyotlar

  1. KeepAlive-dan foydalaning: Bitta serverga bir nechta so‘rovlar yuborishda unumdorlikni oshirish uchun doimiy ulanishlar uchun keepAlive-ni yoqing.
  2. MaxSockets ni o‘rnating: Maqsadli server yoki o‘z tizimingiz resurslarining haddan tashqari ko‘payishini oldini olish uchun maxSockets cheklang.
  3. Tozalash: Resurslarni bo‘shatish uchun agent kerak bo‘lmaganda agent.destroy() metodini chaqiring.
  4. Maxsus agentlardan foydalanish: Turli ulanish talablari yoki maqsadli serverlar uchun turli agent misollarini yarating.
  5. Agent sog‘lig‘ini kuzatib boring: Ulanish muammolarini aniqlash uchun faol va bo‘sh soketlar sonini kuzating.
  6. Xavfsizlik: HTTPS agentlari uchun har doim tegishli SSL/TLS parametrlarini sozlang va xavfsizlik sozlamalarini yangilab turing.
  7. Xatolarni qayta ishlash: HTTP so‘rovlarida yuzaga kelishi mumkin bo‘lgan xatolarni har doim ko‘rib chiqing.

W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!