我正在寻找在Java中实现Web服务(让我们称之为A)接受作业请求,然后将这些请求发送到另一个Web服务(第三方服务让我们称之为B)。这里没什么复杂的。从B到A的响应是同步的(返回作业ID),然后当作业完成时,B向A发送异步消息,通知它作业已完成(作业到B可能需要X时间)。 B一次只能接受20个工作,但A应该能够从多个客户接受尽可能多的工作。所以A需要一个排队系统,只能向B发送不超过20个工作。当B完成一项工作并通知A时,A可以将另一份工作发送给B.
我可以在状态为NEW的数据库中保存进入A的作业,然后每隔5分钟运行一个进程,收集新作业,如果< 20个作业由B处理,则发送作业。由B处理的作业将具有状态处理,然后当B将作业结束发送到A时,它将状态设置为DONE。只是
我可以使用JMS或像Camel这样的路由引擎,或者是否有人可以提供其他框架来提供帮助。我无法找到任何维护队列的东西,只能发送最多的X个作业。 A队列可能有数百个等待处理的作业,但只有在完成另一个作业时才向B发送另一个作业。
答案 0 :(得分:1)
就你的任务如此具体而言,我不确定在任何框架中都有“开箱即用”的解决方案。
你是对的:队列适合你。在这种情况下,我不确定并发消费者是否正常,因为您需要“屏障”。
作为'障碍'解决方案,我建议有一些AtomicInteger
,当你发送作业增加它并将值发送到某个组件停止你的消费者,如果'障碍' '是有限的。
当作业完成后,如果'障碍'低于限制,则递减AtomicInteger
和开始消费者。
不确定,如果Camel允许启动/停止端点,但Spring Integration依赖于Lifecycle
消息传递端点。
答案 1 :(得分:1)
除非您需要持续处理尚未提交进行处理的作业,否则我认为您只需要两个blocking queues。
您的网络线程使用新作业填充“传入作业队列”。单个工作线程一次从该队列中获取一个作业。然后尝试将令牌元素放入“作业待完成队列”。如果该队列中的条目少于20个,则它将立即成功,然后将作业提交给您的服务B.
从B接收异步回调的线程将从“作业挂起完成队列”中删除令牌元素。 如果队列中已有20个条目,则尝试提交新作业的线程将被阻止,直到回调线程删除令牌元素为止。
答案 2 :(得分:0)
你可以用Camel完美地完成它。对我来说最简单的方法是:添加一个JMS队列,接受来自A的调用并将它们添加到队列(路由1)。添加一个包含20个消费者的JMS监听器,将任务发送到B(路由2)并将B的响应转发给A返回