在Java中连续处理异步队列的最佳方法是什么?

在Java中连续处理异步队列的最佳方法是什么?,java,asynchronous,queue,jms,Java,Asynchronous,Queue,Jms,我很难想出如何设计我的系统的最后一部分。目前,我正在运行一个Tomcat服务器,它有一个响应客户机请求的servlet。每个请求依次向异步队列添加一条处理消息(我可能会通过Spring或更可能的AmazonSQS使用JMS) 事件顺序如下: 发送端: 1.接受客户请求 2.使用唯一ID将一些数据添加到与此请求相关的数据库中 3.将表示此请求的消息对象添加到消息队列 接收方: 1.从队列中提取新的消息对象 2.打开对象并根据msg对象中包含的信息从网站获取一些信息 3.发送电子邮件警报 4.使用此

我很难想出如何设计我的系统的最后一部分。目前,我正在运行一个Tomcat服务器,它有一个响应客户机请求的servlet。每个请求依次向异步队列添加一条处理消息(我可能会通过Spring或更可能的AmazonSQS使用JMS)

事件顺序如下:

发送端:
1.接受客户请求
2.使用唯一ID将一些数据添加到与此请求相关的数据库中
3.将表示此请求的消息对象添加到消息队列

接收方:
1.从队列中提取新的消息对象
2.打开对象并根据msg对象中包含的信息从网站获取一些信息
3.发送电子邮件警报
4.使用此请求的操作已完成的信息更新我的DB行(相同的唯一ID)

我很难弄清楚如何正确地对待对方。一方面,我可能可以创建一个简单的java程序,从命令行开始,选择队列中的每个项目并对其进行处理。安全吗?让该程序作为Tomcat容器中的另一个线程运行是否更有意义?我不想串行地执行此操作,这意味着接收端应该能够一次处理多个对象——使用多个线程。我想让它一直运行,一天24小时


构建接收方的一些选项是什么?

我通过将接收方托管在应用程序服务器(我的例子是weblogic)中来实现这一点,但tomcat也可以正常工作。不要轮询队列,请使用基于事件的模型。这可以是手工编码的,也可以是消息驱动的web服务。如果数据库更新是幂等的,则可以更新数据库并发送电子邮件,然后在队列上发出提交。让多个线程都从同一队列读取不是问题


我使用过各种JMS解决方案,包括tibco、activemq(在apache将其纳入之前)和joram。Joram是更可靠的开源解决方案,但现在它是apache的一部分,这一点可能已经改变了。

如果您已经在使用Spring,请查看。它允许您创建POJO消息驱动bean。这可以从现有应用程序容器(WAR文件)中使用,也可以作为单独的进程使用

“一方面,我可能可以创建一个简单的java程序,从命令行启动该程序,选择队列中的每个项目并对其进行处理。这样安全吗?”

它有什么不安全之处?它工作得很好

“将该程序作为Tomcat容器中的另一个线程运行是否更有意义?”

只有在Tomcat有大量空闲时间处理后台处理的情况下。通常情况下,就是这样——你有空闲时间做这种处理

然而,线程并不是最优的。线程共享公共I/O资源,后台线程可能会降低前端的速度


更好的方法是在“端口80”前端和单独的后端进程之间有一个JMS队列。后端进程启动、连接到队列、获取并执行请求。后端进程可以(如有必要)是多线程的。

如果您使用的是JMS,为什么要将任务放在数据库中


您可以在JMS中使用持久队列。这将保留任务,即使JMS代理死亡,直到它们被确认。您可以有多余的代理,这样,如果一个代理死亡,第二个代理将自动接管。这可能比使用单个数据库更可靠。

因为我将从目标网站检索一些信息,并将其放在数据库中的行旁边。然后,客户机需要在稍后的某个时间点检索此信息。我实际上并没有使用db作为冗余,而是用于存储数据以供以后检索。在这种情况下,消费者是连续轮询队列还是以某种方式得到通知?我非常确定DefaultMessageListenerContainer轮询。它的好处在于它对您隐藏了轮询/通知问题。您只需实现一个jms MessageListener,然后做您需要做的任何工作,以防有人对我最终要做的事情感兴趣。我使用了Amazon的SQS,有一个java客户端(利用spring框架)轮询队列。当它发现一个消息时,它会处理它并返回等待状态。我可能会添加石英线程,现在我只是启动了多个进程。我面临着类似的问题。我想知道Java客户机是如何实现的。我希望它不会在消息的无限while循环和池中运行?您能解释如何实现基于事件的模型吗?请看一看标题为“异步接收消息”的部分