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

时间:2009-02-05 02:33:09

标签: java asynchronous queue jms

我很难弄清楚如何构建我系统的最后一块。目前我正在运行一个Tomcat服务器,它有一个响应客户端请求的servlet。每个请求反过来将一个处理消息添加到异步队列(我可能会通过Spring或更可能是Amazon SQS使用JMS)。

事件的顺序如下:

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

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

我正在努力弄清楚如何妥善处理接收方。一方面,我可以创建一个简单的java程序,我从命令行启动它,选择队列中的每个项目并处理它。这样安全吗?让该程序作为Tomcat容器中的另一个线程运行更有意义吗?我不想连续地这样做,这意味着接收端应该能够一次处理多个对象 - 使用多个线程。我想让它一直24小时都在运行。

建立接收方有哪些选择?

4 个答案:

答案 0 :(得分:3)

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

它有什么不安全感?它很棒。

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

只有Tomcat有足够的空闲时间来处理后台处理。通常情况下, 这种情况 - 您有空闲时间进行此类处理。

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

最好是在“端口80”前端和单独的后端进程之间建立JMS队列。后端进程启动,连接到队列,获取并执行请求。后端进程可以(如果需要)是多线程的。

答案 1 :(得分:2)

如果您正在使用JMS,为什么要将任务放入数据库?

您可以在JMS中使用持久的队列。即使JMS代理已经死亡,这也会保留任务,直到它们被确认为止。您可以拥有冗余代理,以便在一个代理程序死亡时,第二个代理程序自动接管。这比使用单个数据库更可靠。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

我已经通过在app服务器中托管接收器来完成了这种事情,在我的情况下是weblogic,但是tomcat也能正常工作。不要轮询队列,使用基于事件的模型。这可以是手工编码的,也可以是消息驱动的Web服务。如果数据库更新是幂等的,您可以更新数据库并发送电子邮件,然后在队列上发出提交。有几个线程都从同一个队列中读取,这不是问题。

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