基于Spring Cloud Stream RabbitMQ的分区和并发处理

时间:2019-06-11 20:57:54

标签: java spring rabbitmq spring-cloud-stream spring-rabbitmq

我正在为一个应用程序制作原型,该应用程序从客户那里接收长期运行的作业,他们可以通过网络暂停和恢复。每个作业包含成千上万个元素,将以每分钟一定的速率处理。 x个小时后,该作业无效,因此可以终止包含剩余元素的整个作业。

示例场景-

Customer A uploads job 1 with 10000 elements

Customer A uploads job 2 with 5000 elements   

Customer A uploads job 3 with 8000 elements 

Customer B uploads job 4 with 50000 elements 

Customer B uploads job 5 with 1000 elements 

Customer C uploads job 6 with 200000 elements 

可以选择每个作业以不同的吞吐量级别运行,例如每分钟最多10、20或30个元素。客户可以暂停和恢复每个作业。

我正在评估Spring Cloud Stream RabbitMQ以开发核心作业处理引擎。

  

构造这种结构以便使每个作业同时分区和处理的最佳方法是什么?

     

我应该考虑为每个工作创建动态的消费者,还是按工作ID创建一个消费者调查消息?

在现实世界的系统中,可能有数百个并发作业,且累积元素数百万。

我将欣赏一个最小的工作代码段和配置,可用于进一步开发。

1 个答案:

答案 0 :(得分:0)

我现在无法创建代码段,但这就是我实现此代码的方式(并且过去已经实现了类似的方案):

  1. 拥有一项服务(简称为requester),该服务以选定的速率填充队列,并带有您指定的所有暂停/恢复/超时选项。
  2. 假设所有作业的元素都以相同的方式处理,则将它们全部放入一个带有标识客户的标头的队列中。
  3. 拥有一个可伸缩的微服务(叫它processor),以尽可能快的速度从队列中拉出(因此队列应始终几乎为空),并将结果与客户标题。
  4. 拥有一个可伸缩的微服务(叫它responder)来监听结果队列,并对结果做任何您需要的事情(保存到db,通知客户,记录等)。

这种设置可确保费率由requester控制,而processor由客户根据您的规范以及所有其他服务(responderconst uri='some url' const uri2='some url2' const Discord = require('discord.js') const client = new Discord.Client() const cheerio = require('cheerio'); const rp = require('request-promise'); var a_href //repeat this for every 2 hours setInterval(async function run() { const options = { uri, resolveWithFullResponse: true, transform: (body) => { return cheerio.load(body); }} try{ const $ = await rp(options); //get the first href from a h3 element $('.table h3 > a').attr('href') $(".table").each(function(){ a_href = $(this).find('h3 > a').attr('href'); }); }catch(e){ console.log(e); }}, 7100000); client.on('ready', () => { var generalChannel = client.channels.get("593113450398613537") setInterval (function () { generalChannel.send(a_href) }, 7200000); }) ),根据它产生的负载进行缩放。