You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu服务器下网站在线人数模拟Bot内存优化方案咨询

Efficient Alternatives to Puppeteer for Simulating Site Online Users

Great question—spinning up full Chromium pages for each bot is total overkill when all you need is to maintain WebSocket or long-poll connections. That's exactly why you're seeing such heavy memory usage (60-120MB per page). Let's walk through far more efficient solutions, ordered by how much they'll reduce your resource footprint:


1. Direct WebSocket/Long-Poll Clients (Best for Memory)

Skip the browser entirely. Most sites using WebSocket or long-poll don't need a full browser environment—they just need valid connections that follow their protocol rules. This approach cuts memory usage to a few MB per bot (sometimes less).

How to Implement:

  1. Inspect the target site's protocol: Use your browser's DevTools (Network tab, filter by "WS" or "Fetch/XHR") to find:

    • The WebSocket endpoint URL (looks like wss://example.com/ws)
    • Required request headers (User-Agent, Cookies, Origin, etc.)
    • Any initial messages (like joining a room or sending an auth token)
    • Heartbeat mechanisms (many sites send periodic "ping" messages to keep connections alive)
  2. Use a lightweight WebSocket library: The ws package is perfect for this. Here's a sample implementation:

const WebSocket = require('ws');

async function runWebSocketBots(botsCount = 10, runTimeSeconds = 60) {
  const bots = [];
  const wsEndpoint = 'wss://www.example.page/your-ws-endpoint'; // Replace with actual URL
  const connectionHeaders = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/114.0.0.0 Safari/537.36',
    'Cookie': 'session-id=your-session-cookie' // Add if site requires auth
  };

  console.log(`Launching ${botsCount} WebSocket bots...`);

  for (let i = 1; i <= botsCount; i++) {
    const bot = new WebSocket(wsEndpoint, { headers: connectionHeaders });

    bot.on('open', () => {
      console.log(`Bot ${i} connected`);
      // Send any required initial message (e.g., join a chat room)
      // bot.send(JSON.stringify({ action: 'joinRoom', room: 'main' }));
    });

    bot.on('message', (data) => {
      const message = JSON.parse(data.toString());
      // Handle heartbeats if the site uses them
      if (message.type === 'ping') {
        bot.send(JSON.stringify({ type: 'pong' }));
      }
    });

    bot.on('error', (err) => console.error(`Bot ${i} error:`, err));
    bots.push(bot);
  }

  // Cleanup after run time
  setTimeout(() => {
    console.log('\nShutting down all bots...');
    bots.forEach(bot => bot.close());
    console.log('Finished');
  }, runTimeSeconds * 1000);
}

runWebSocketBots();

For long-poll sites, use the native http/https modules to repeatedly send requests and keep the connection open—same idea, just no WebSocket handshake.


2. Optimize Your Existing Puppeteer Setup

If you need to stick with Puppeteer (e.g., the site has complex JS that can't be replicated easily), you can slash memory usage by disabling unnecessary browser features:

Optimized Puppeteer Code:

const puppeteer = require('puppeteer');

async function runOptimizedPuppeteerBots(botsCount = 10, runTimeSeconds = 60) {
  let timeLeft = runTimeSeconds * 1000;
  console.log('Starting optimized Chromium instance...');

  const browser = await puppeteer.launch({
    args: [
      '--disable-gpu',
      '--no-sandbox',
      '--headless=new', // Newer, more efficient headless mode
      '--disable-dev-shm-usage',
      '--disable-images', // Cut out image loading entirely
      '--disable-features=VizDisplayCompositor', // Disable unnecessary rendering
      '--disable-web-security',
      '--single-process' // Experimental: runs everything in one process (reduces overhead)
    ]
  });

  for (let i = 1; i <= botsCount; i++) {
    const page = await browser.newPage();
    
    // Block all non-essential requests
    await page.setRequestInterception(true);
    page.on('request', req => {
      const allowedTypes = ['document', 'websocket'];
      if (allowedTypes.includes(req.resourceType())) {
        req.continue();
      } else {
        req.abort();
      }
    });

    await page.setViewport({ width: 800, height: 600 }); // Smaller viewport = less memory
    await page.goto('https://www.example.page/');
    console.log(`Page ${i} created`);
  }

  // Countdown timer
  const interval = setInterval(() => {
    process.stdout.write(`\rTime Left: ${timeLeft / 1000}s`);
    timeLeft -= 1000;
    if (timeLeft <= 0) {
      clearInterval(interval);
      browser.close();
      console.log('\nFinished');
    }
  }, 1000);
}

runOptimizedPuppeteerBots();

This should reduce memory per page by 30-60% compared to your original setup.


3. Switch to Playwright (Better Memory Management)

Playwright (from Microsoft) is a modern alternative to Puppeteer with better memory efficiency, especially for multi-page scenarios. The API is almost identical to Puppeteer, so switching is straightforward.

Sample Playwright Code:

const { chromium } = require('playwright');

async function runPlaywrightBots(botsCount = 10, runTimeSeconds = 60) {
  let timeLeft = runTimeSeconds * 1000;
  console.log('Starting Playwright instance...');

  const browser = await chromium.launch({
    headless: true,
    args: [
      '--no-sandbox',
      '--disable-dev-shm-usage',
      '--disable-images'
    ]
  });

  for (let i = 1; i <= botsCount; i++) {
    const page = await browser.newPage();
    await page.route('**/*', route => {
      const type = route.request().resourceType();
      if (type === 'document' || type === 'websocket') {
        route.continue();
      } else {
        route.abort();
      }
    });
    await page.goto('https://www.example.page/');
    console.log(`Bot ${i} ready`);
  }

  const interval = setInterval(() => {
    process.stdout.write(`\rTime Left: ${timeLeft / 1000}s`);
    timeLeft -= 1000;
    if (timeLeft <= 0) {
      clearInterval(interval);
      browser.close();
      console.log('\nFinished');
    }
  }, 1000);
}

runPlaywrightBots();

Playwright typically uses 20-30% less memory than Puppeteer for the same number of pages.


Final Recommendations

  • Use direct WebSocket clients if you can reverse-engineer the site's protocol—this is the most cost-effective option by far.
  • Optimize Puppeteer if you need browser-level JS execution but want to cut costs.
  • Switch to Playwright if you're starting fresh or already use Microsoft's tooling.

内容的提问来源于stack exchange,提问作者ArtemSky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:25:28