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

Google Cloud Storage + Node.js 多图片读取请求加载缓慢问题排查求助

Troubleshooting Slow Image API Requests (GCS + Node.js)

Hey there, let's break down what might be causing those slow image requests and walk through actionable fixes to get your service running smoothly for global users.

First: Address the Crashed ServiceImage Process

Looking at your PM2 process table, the ServiceImage process has restarted 13 times and only has 0 seconds of uptime. This is a critical red flag—every time the process crashes and restarts, Node.js has to reinitialize the app and re-establish connections to Google Cloud Storage (GCS). Requests hitting the service right after a restart will face massive delays while the app spins back up.

Start by checking the logs for this process to identify why it's crashing:

pm2 logs ServiceImage

Fixing these crashes should immediately resolve a large portion of your slow request issues.

Optimize Stream Handling in Your Code

Your current route code manually listens for data events to write to the response, which can lead to backpressure issues (when the response can't keep up with the GCS stream). This causes bottlenecks, especially under load. Instead, use Node.js's built-in pipe() method—it automatically handles backpressure and is far more efficient.

Update your route code:

router.get('/image/:imageId', async function (req, res) {
  try {
    const imageId = req.param('imageId');
    const imageStream = cloudController.getImageFromBucket('fotos_perfil', imageId);
    
    // Set proper headers
    res.setHeader('Content-Type', 'image/jpg');
    res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache images for 1 day

    // Use pipe to handle stream efficiently
    imageStream.pipe(res);
    
    imageStream.on('error', (error) => {
      if (!res.headersSent) {
        res.status(400).send('Erro lendo a imagem');
      }
      console.error('Image stream error:', error);
    });
  } catch (err) {
    res.status(500).send('Internal Server Error');
    console.error('Route error:', err);
  }
})

You can also simplify your controller code—createReadStream() returns a stream immediately, so you don't need to wrap it in a Promise:

function getImageFromBucket(bucket, imageId) {
  return storage.bucket(bucket).file(imageId).createReadStream();
}

Leverage fast-crc32c for GCS Performance

Google mentions fast-crc32c because GCS uses CRC32C checksums for data integrity. The GCS Node.js SDK will automatically use this faster native implementation if it's installed, replacing the slower pure-JS version. Just install it as a dependency:

npm install fast-crc32c

No extra configuration needed—once installed, the SDK will use it to speed up stream operations to/from GCS.

Add Caching & CDN for Global Users

Since images rarely change, adding proper cache headers (like the Cache-Control header in the updated code above) lets browsers and intermediate caches store images locally, reducing repeat requests to your server and GCS.

For global users, consider adding Google Cloud CDN in front of your GCS bucket or Node.js server. CDNs cache content in edge locations worldwide, cutting down load times for users far from your server.

Final Action Plan

  1. Fix ServiceImage crashes using PM2 logs to identify root causes.
  2. Refactor stream handling to use pipe() instead of manual data listeners.
  3. Install fast-crc32c to optimize GCS stream performance.
  4. Add cache headers to reduce unnecessary requests.
  5. Set up a CDN to serve images closer to global users.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:47:47