您现在的位置是:网站首页 > 网络性能优化文章详情

网络性能优化

网络性能优化的核心目标

网络性能优化的核心目标是减少延迟、提高吞吐量、降低资源消耗。在Node.js环境中,这涉及到从代码层面到架构层面的多方面调整。一个典型的例子是减少不必要的I/O操作,比如使用内存缓存代替频繁的数据库查询:

const cache = new Map();

async function getCachedData(key) {
  if (cache.has(key)) {
    return cache.get(key);
  }
  const data = await fetchDataFromDB(key);
  cache.set(key, data);
  return data;
}

HTTP/2的优势与应用

HTTP/2的多路复用特性可以显著提升网络性能。在Node.js中启用HTTP/2非常简单:

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

const server = http2.createSecureServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt')
});

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  stream.end('<h1>Hello HTTP/2!</h1>');
});

server.listen(443);

连接池管理策略

数据库连接池的合理配置对性能影响巨大。以下是一个PostgreSQL连接池的优化示例:

const { Pool } = require('pg');

const pool = new Pool({
  user: 'dbuser',
  host: 'database.server.com',
  database: 'mydb',
  password: 'secretpassword',
  port: 5432,
  max: 20, // 最大连接数
  idleTimeoutMillis: 30000, // 空闲连接超时
  connectionTimeoutMillis: 2000 // 连接超时
});

async function query(text, params) {
  const start = Date.now();
  const res = await pool.query(text, params);
  const duration = Date.now() - start;
  console.log('Executed query', { text, duration, rows: res.rowCount });
  return res;
}

压缩技术的实现

Node.js内置支持多种压缩算法。以下是使用Brotli压缩的示例:

const zlib = require('zlib');
const http = require('http');
const fs = require('fs');

http.createServer((req, res) => {
  const raw = fs.createReadStream('index.html');
  const acceptEncoding = req.headers['accept-encoding'] || '';
  
  res.setHeader('Vary', 'Accept-Encoding');
  
  if (acceptEncoding.includes('br')) {
    res.setHeader('Content-Encoding', 'br');
    raw.pipe(zlib.createBrotliCompress()).pipe(res);
  } else if (acceptEncoding.includes('gzip')) {
    res.setHeader('Content-Encoding', 'gzip');
    raw.pipe(zlib.createGzip()).pipe(res);
  } else {
    raw.pipe(res);
  }
}).listen(3000);

负载均衡配置

使用cluster模块实现多进程负载均衡:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);
  
  // Fork workers
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);
  
  console.log(`Worker ${process.pid} started`);
}

缓存策略的深度优化

实现多级缓存策略可以大幅提升性能:

const NodeCache = require('node-cache');
const myCache = new NodeCache({ stdTTL: 100, checkperiod: 120 });

async function getProductDetails(productId) {
  const cacheKey = `product_${productId}`;
  let product = myCache.get(cacheKey);
  
  if (!product) {
    product = await fetchFromDatabase(productId);
    
    // 设置缓存,并添加过期回调
    myCache.set(cacheKey, product, 3600, (key, value) => {
      console.log(`Cache expired for ${key}`);
      // 可以在这里实现写回逻辑
    });
  }
  
  return product;
}

流式处理的优势

处理大文件时流式API可以显著降低内存使用:

const fs = require('fs');
const zlib = require('zlib');
const { pipeline } = require('stream');

// 传统方式(内存消耗大)
// fs.readFile('largefile.txt', (err, data) => {
//   if (err) throw err;
//   const compressed = zlib.gzipSync(data);
//   fs.writeFile('largefile.txt.gz', compressed);
// });

// 流式处理
pipeline(
  fs.createReadStream('largefile.txt'),
  zlib.createGzip(),
  fs.createWriteStream('largefile.txt.gz'),
  (err) => {
    if (err) {
      console.error('Pipeline failed', err);
    } else {
      console.log('Pipeline succeeded');
    }
  }
);

DNS查询优化

Node.js中的DNS缓存策略:

const dns = require('dns');
const { promisify } = require('util');
const resolve4 = promisify(dns.resolve4);

// 自定义缓存实现
const dnsCache = new Map();

async function cachedDnsLookup(hostname) {
  if (dnsCache.has(hostname)) {
    return dnsCache.get(hostname);
  }
  
  const addresses = await resolve4(hostname);
  dnsCache.set(hostname, addresses);
  
  // 设置5分钟缓存
  setTimeout(() => {
    dnsCache.delete(hostname);
  }, 300000);
  
  return addresses;
}

请求批处理技术

合并多个小请求可以显著减少网络开销:

class BatchProcessor {
  constructor() {
    this.queue = [];
    this.timeout = null;
    this.batchSize = 10;
    this.timeoutMs = 50;
  }
  
  addRequest(request) {
    return new Promise((resolve) => {
      this.queue.push({ request, resolve });
      
      if (this.queue.length >= this.batchSize) {
        this.processBatch();
      } else if (!this.timeout) {
        this.timeout = setTimeout(() => this.processBatch(), this.timeoutMs);
      }
    });
  }
  
  async processBatch() {
    if (this.timeout) {
      clearTimeout(this.timeout);
      this.timeout = null;
    }
    
    const currentBatch = this.queue.splice(0, this.batchSize);
    if (currentBatch.length === 0) return;
    
    const batchResults = await processMultipleRequests(
      currentBatch.map(item => item.request)
    );
    
    currentBatch.forEach((item, index) => {
      item.resolve(batchResults[index]);
    });
  }
}

性能监控与分析

使用Performance Hooks进行细粒度性能监控:

const { PerformanceObserver, performance } = require('perf_hooks');

const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration}ms`);
  });
});
obs.observe({ entryTypes: ['measure'] });

// 标记重要操作的时间点
performance.mark('A');
// 执行一些操作
performance.mark('B');
performance.measure('A to B', 'A', 'B');

现代JavaScript特性优化

利用现代JS特性提升执行效率:

// 使用Map代替普通对象作为字典
const cache = new Map();

// 使用WeakMap存储私有数据
const privateData = new WeakMap();

class MyClass {
  constructor() {
    privateData.set(this, {
      secret: 42
    });
  }
  
  getSecret() {
    return privateData.get(this).secret;
  }
}

// 使用BigInt处理大整数
const bigNumber = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1);

事件循环优化技巧

合理利用事件循环各阶段:

// 将CPU密集型任务拆分到多个tick中
function processChunk(chunk, callback) {
  // 处理一小块数据
  // ...
  
  if (moreToProcess) {
    // 使用setImmediate将剩余工作放到下一个事件循环迭代
    setImmediate(() => processChunk(nextChunk, callback));
  } else {
    callback();
  }
}

// 优先使用setImmediate而不是process.nextTick
// 避免I/O饥饿
setImmediate(() => {
  console.log('This runs in the check phase');
});

内存管理最佳实践

避免内存泄漏的常见模式:

// 正确的事件监听器管理
class EventEmitterExample {
  constructor() {
    this.listeners = new Set();
  }
  
  addListener(fn) {
    this.listeners.add(fn);
    return () => this.listeners.delete(fn);
  }
  
  emit(data) {
    for (const listener of this.listeners) {
      listener(data);
    }
  }
}

// 使用WeakRef避免保持不必要的引用
const weakRef = new WeakRef(largeObject);
// 当需要时检查对象是否还存在
const deref = weakRef.deref();
if (deref) {
  // 对象仍然存在
}

上一篇: DNS解析

下一篇: RESTful API设计

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步