Javascript 高CPU利用率导致弹性豆茎环境退化

Javascript 高CPU利用率导致弹性豆茎环境退化,javascript,node.js,amazon-web-services,amazon-elastic-beanstalk,cpu-usage,Javascript,Node.js,Amazon Web Services,Amazon Elastic Beanstalk,Cpu Usage,我正在尝试将一些谷歌广告帐户同步到我的系统中 此过程从google ads帐户中提取2017-01-01至最后日期的数据 查询单个日期,在for循环中处理它以生成适当的对象 插入到数据库中 还尝试了负载平衡器。但有一种情况下会发生降级 代码 查询谷歌广告数据 var difference = dateDiffInDays(new Date(2017, 0, 1), new Date()); // getting last N days days = LastNDays(difference +

我正在尝试将一些谷歌广告帐户同步到我的系统中

此过程从google ads帐户中提取2017-01-01至最后日期的数据

查询单个日期,在for循环中处理它以生成适当的对象

插入到数据库中

还尝试了负载平衡器。但有一种情况下会发生降级

代码

查询谷歌广告数据

var difference = dateDiffInDays(new Date(2017, 0, 1), new Date());

// getting last N days
days = LastNDays(difference + 1) 

// making array of date ranges
var result = days.chunk(20); 

// querying google ads data 
    for (var value of result) {
        const list = await customer.report({
            entity: 'keyword_view',
            attributes: adAttributes,
            segments: ['segments.date'],
            from_date: value[0],
            to_date: value[value.length - 1]
        })
        await saveKeywordsData(list, value[value.length - 1])
    }
async function saveKeywordsData(list, cronUntill) {
        let metricsArray = []
        for await (let element of list) {
            let metrics = element.metrics
            metrics.criterion_id = element.ad_group_criterion.criterion_id
            metrics.keyword = element.ad_group_criterion.keyword.text
            metrics.accId = accId
            metrics.agencyId = agencyId
            metrics.accountMId = accountMId
            metrics.date = element.segments.date
            metrics.dateTime = new Date(element.segments.date)
            metrics.createdAt = new Date()
            metricsArray.push(metrics);
        }

        // metricsArray length may be more than 5000 for each loop 
        await chunkInsertion(metricsArray, 'keywords')
        return 1;
    };
我认为问题在于以下功能

因为上述查询的输出大于5000或6000(对于单个日期,此处调用日期为2017-01-01)

因此,在一段时间内连续处理5000多个数据时,cpu利用率会很高

功能保存关键字数据

var difference = dateDiffInDays(new Date(2017, 0, 1), new Date());

// getting last N days
days = LastNDays(difference + 1) 

// making array of date ranges
var result = days.chunk(20); 

// querying google ads data 
    for (var value of result) {
        const list = await customer.report({
            entity: 'keyword_view',
            attributes: adAttributes,
            segments: ['segments.date'],
            from_date: value[0],
            to_date: value[value.length - 1]
        })
        await saveKeywordsData(list, value[value.length - 1])
    }
async function saveKeywordsData(list, cronUntill) {
        let metricsArray = []
        for await (let element of list) {
            let metrics = element.metrics
            metrics.criterion_id = element.ad_group_criterion.criterion_id
            metrics.keyword = element.ad_group_criterion.keyword.text
            metrics.accId = accId
            metrics.agencyId = agencyId
            metrics.accountMId = accountMId
            metrics.date = element.segments.date
            metrics.dateTime = new Date(element.segments.date)
            metrics.createdAt = new Date()
            metricsArray.push(metrics);
        }

        // metricsArray length may be more than 5000 for each loop 
        await chunkInsertion(metricsArray, 'keywords')
        return 1;
    };
功能块插入

    async function chunkInsertion(metricsArray, type) {
    let model
    if (type == 'ads')
        model = app.models.googleAdsInsights
    else
        model = app.models.googleAdsAuctionInsights
    var data = metricsArray.chunk(50);
    for (let item of data) {
        await model.create(item)
    }
    return 1
}
根据评论

我只能提供如何使用worker环境的一般描述。具体实施细节是根据具体情况而定的

用于执行长时间运行的任务。对于您的用例来说,这可能是一个很好的解决方案,因为您可以将web环境与那些提升CPU的繁重处理工作分离

在这种情况下,web环境将负责启动作业并收集结果。它不会执行实际的处理,而实际的处理将由专用的工作环境来处理

工作环境公开了一个SQS队列。这与提供网站url的web环境不同。从worker env中,您只获得SQS队列端点。端点用于将作业提交给工作者。您的辅助应用程序将从队列接收作业,并独立于web环境执行查询

处理结果的方法有很多种。一种方法是工作人员将结果写入,例如DynamoDB。在这种情况下,web环境会不时地查询数据库以查看结果是否可用。另一种方法是让你的web应用公开一个专用的url端点,该端点将由工作人员调用以表示作业完成

这就是通常将web环境与长时间运行的cpu或内存密集型任务分离的方式。但这需要更改您的应用程序的工作方式,并开发要部署在EB worker环境中的worker应用程序。

根据评论

我只能提供如何使用worker环境的一般描述。具体实施细节是根据具体情况而定的

用于执行长时间运行的任务。对于您的用例来说,这可能是一个很好的解决方案,因为您可以将web环境与那些提升CPU的繁重处理工作分离

在这种情况下,web环境将负责启动作业并收集结果。它不会执行实际的处理,而实际的处理将由专用的工作环境来处理

工作环境公开了一个SQS队列。这与提供网站url的web环境不同。从worker env中,您只获得SQS队列端点。端点用于将作业提交给工作者。您的辅助应用程序将从队列接收作业,并独立于web环境执行查询

处理结果的方法有很多种。一种方法是工作人员将结果写入,例如DynamoDB。在这种情况下,web环境会不时地查询数据库以查看结果是否可用。另一种方法是让你的web应用公开一个专用的url端点,该端点将由工作人员调用以表示作业完成


这就是通常将web环境与长时间运行的cpu或内存密集型任务分离的方式。但这需要更改您的应用程序的工作方式,以及在EB worker环境中部署worker应用程序的开发。

能否将这些繁重的处理应用程序卸载到专用worker环境中?让我检查一下这种方法。您的意思是,将web服务器环境更改为workker环境?您可以为应用程序的网站部分保留web服务器环境。Worker env将用于处理那些长时间运行的垂荡查询。这需要对您的体系结构进行一些更改,因为web和工作环境需要交互。如果您经常运行如此繁重的查询,那么可能更容易移动到更好的实例并首先检查这是否有帮助?我认为这是为了解决这个问题。@Marcin您能解释一下如何做吗?您能将这些繁重的处理应用程序卸载到专用的工作环境中吗?让我检查一下这个方法。您的意思是,将web服务器环境更改为workker环境?您可以为应用程序的网站部分保留web服务器环境。Worker env将用于处理那些长时间运行的垂荡查询。这需要对您的体系结构进行一些更改,因为web和工作环境需要交互。如果您经常运行如此繁重的查询,那么可能更容易移动到更好的实例并首先检查这是否有帮助?我认为这是为了解决这个问题。@Marcin您能解释一下如何做吗?