首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在节点js中运行6/8小时或更长时间的api请求?

如何在节点js中运行6/8小时或更长时间的api请求?
EN

Stack Overflow用户
提问于 2022-04-21 07:18:58
回答 2查看 325关注 0票数 0

我必须通过api2cart API从shopify中提取大量数据。我需要拉2/3年前的数据,这需要几个小时的时间,因为我们只能拉250个项目的要求。对于每个响应,它为接下来的250个数据拉扯提供了一个键,等等。

在我的后端中,我通过fs提取数据并将其保存在csv文件中,然后再次为接下来的250项调用api。它在我的本地机器上运行得很好。这个过程一直持续到所有的数据都被获取为止。我可以拉出数年的数据,大约需要2-3个小时才能得到大约100 K/150 k的数据。

然后,我建立了一个NestJS微服务,并部署在一个数字海洋服务器。但是当我请求API很长一段时间后,服务器会给我504个网关超时错误。

不能使用setTimeout,因为这个过程没有限制。有什么方法可以让数据持续几个小时或几天吗?

如何在没有504网关超时错误的情况下提取数小时的数据?

EN

回答 2

Stack Overflow用户

发布于 2022-04-21 13:25:36

运行很长时间的请求通常容易出错。连接重置可能导致重新启动整个进程。尽管这不会解决你用数字海洋描述的地下问题,但我认为值得你考虑另一种解决方案。我建议将繁重的、长期运行的任务分成多个小任务,并使用队列系统。

Nestjs提供了一个非常好的文档,使用队列和公牛包。

我添加了一个基本示例,提供了两个解决方案:

队列消费者

shopify.consumer.ts

代码语言:javascript
复制
import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('shopify')
export class ShopifyConsumer {
  constructor(
    private shopifyService: ShopifyService
  ) {}

  @Process('fetch')
  async transcode(job: Job<unknown>) {
    await this.shopifyService.fetch(job.requestKey);
  }
}

选项a)立即生成所有请求,并让队列处理它们:

shopify.service.ts

代码语言:javascript
复制
import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class ShopifyService {
  constructor(
    @InjectQueue('shopify') private shopifyQueue: Queue
  ) {}
    
  generateJobs(requestKeys: string[]) {
    for (const requestKey of requestKeys) {
      await this.shopifyQueue.add('fetch', { 
        requestKey
      });
    }
  }

  fetch(requestKey: string) {
    // Fetch data
    const res = await fetch('...')
  }
}

选项b)在每个响应之后生成一个新的队列作业

shopify.service.ts

代码语言:javascript
复制
import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class ShopifyService {
  constructor(
    @InjectQueue('shopify') private shopifyQueue: Queue
  ) {}

  fetch(requestKey: string) {
    // Fetch data
    const res = await fetch('...')
    
    // Add next job to queue if more chunks are available
    if (res.nextRequestKey) {
      await this.shopifyQueue.add('fetch', { 
        requestKey: res.nextRequestKey
      })
    }
  }
}
票数 0
EN

Stack Overflow用户

发布于 2022-04-21 16:00:30

队列和Bull在NestJS中很好地工作,我会推荐它们用于这些长调用。它非常有用,因为您还可以重试调用,并为失败的作业添加超时(以帮助处理417个错误)。

代码语言:javascript
复制
import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class ShopifyService {
  constructor(
    @InjectQueue('shopify') private shopifyQueue: Queue
  ) {}
    
  async generateJobs(requestKeys: string[]) {

    await this.shopifyQueue.addBulk('${QUEUE_NAME}.${JOB_NAME}', { 
      ...jobData //what is needed to make API call
    },
    {
      attempts: 5,
      backoff: 5000,
      //Will try 5 times with backoff
    });
  }
}
    ```
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71950373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档