Java EE应用程序的可伸缩性。你会怎么做?

时间:2009-03-12 15:56:19

标签: java java-ee concurrency scalability jms

我一直致力于金融行业的解决方案。该应用程序的主要功能是能够加载海量输入文件,消化它们,更新持久存储中的状态,并根据请求生成持久存储的提取。很简单。

输入文件是包含许多重复条目的行业标准格式的XML大(超过数百兆字节)消息。持久存储是关系数据库。该引擎已实现为可在J2EE应用程序服务器上部署的基于POJO(Spring Framework as back-bone)Java应用程序。

问题在于解决方案的可扩展性和性能。如果应用程序按顺序处理来自XML的条目,则解决方案的可伸缩性相当差。没有办法将多个应用程序实例用于处理单个文件。这就是我为输入XML文件的条目引入并行处理的原因。基本上,这个想法是从池中为工人分配处理单个条目。我决定使用JMS进行调度。加载文件的组件读取流并简单地提取单个条目并提供调度队列。队列的另一端有许多并发消费者。每个人都选择一个队列消息并处理该条目,并立即可以处理其他条目。这与Web容器中的servlet非常相似。我发现这种方法特别强大的是,只要共享队列,工作人员就可以驻留在部署在远程服务器上的应用程序的单独实例中。不幸的是,所有工作者都连接到维护持久性存储的同一个数据库,如果数据库服务器的功能不足以处理并发工作负载,这可能是一个瓶颈。

您对此架构有何看法?你有类似的设计应用吗?那你的设计选择是什么?

7 个答案:

答案 0 :(得分:3)

您还可以查看Hadoop,这是一个非常方便的Map / Reduce作业平台。最大的优势是,所有基础设施都是由Hadoop提供的,因此您只需应用新的硬件节点进行扩展。实施Map和Reduce作业应该只进行一次,之后,你可以为你的群集提供大量负载。

答案 1 :(得分:2)

我认为架构通常是健全的。如果数据库在处理来自worker的大量并发更新时遇到问题,您可以在应用程序的另一个“侧”引入第二个队列:当每个worker完成任务时,他们会将该任务的结果添加到队列。然后,单个工作进程会定期从第二个队列中获取结果对象,并在大批量操作中更新数据库?这会降低数据库并发性,并可能提高更新效率。

答案 2 :(得分:1)

另外,请看一下Terracota群集解决方案。

答案 3 :(得分:1)

对于并行处理,正如Mork0075所说,hadoop是一个很好的解决方案。实际上,许多公司都将它用于非常大的日志分析。还有一个有趣的项目Hive基于hadoop构建,用于数据仓库。

无论如何,我认为您当前的设计具有很强的可扩展性。至于您对所有工作人员访问数据库的担忧,您可以在工作人员和数据库之间放置另一个消息队列。工作人员将处理结果放入队列中,然后构建另一个程序来订阅队列并更新数据库。缺点是两个队列可能会使系统过于复杂。当然,您只需将另一个主题添加到现有MQ系统即可。这将使系统更简单。另一种方法是使用共享文件系统,例如NFS,每个工作者机器在共享文件服务器上安装相同的目录,并且每个工作者将其处理结果写入共享文件服务器上的单独文件。然后,您构建一个程序来检查新文件以更新数据库。在这种方法中,您会引入另一种复杂性:共享文件服你可以判断哪一个更简单。

答案 4 :(得分:1)

我最近花了一些业余时间来研究Spring Batch 2.0。这是基于Spring框架的Java批处理引擎的新版本。实现Spring Batch的人专注于此版本的并发和并行执行。我必须说它看起来很有前途!

答案 5 :(得分:0)

如果您已经在使用Spring / Java EE,那么将Spring Batch作为“并发架构”的解决方案是很自然的。

蝙蝠有两个好处:

  1. Spring Batch(从2.0开始)实现分区,这意味着框架将在单独的分区步骤(StepExecution)中为您分配数据,并将这些步骤的实际执行委派给多个线程或其他分布式系统(PartitionHandlers,例如TaskExecutorPartitionHandler或更分散的MessageChannelPartitionHandler等。)

  2. Spring有一个很好的OXM包来处理XML + Spring Batch有一个StaxEventItemReader从输入XML文档中提取与处理记录相对应的片段

  3. 试试Spring Batch。如果您有任何问题,请告诉我,我很乐意帮忙。

    EDIT:

    另请查看Scala/AKKA Actors和/或Scala parallel collections。如果您的任务适用于分片/分区/分发=> Actor模型的用途。

    如果您想考虑非JVM解决方案,请查看Erlang OTP =>简单而优雅。

答案 6 :(得分:0)

回答你的问题:

  

您对此架构有何看法?你有类似的设计应用吗?那你的设计选择是什么?

我认为这是一个很好的架构,你是对的,数据库是你的瓶颈。但是,设计足够灵活,您可以控制数据库的输入量。

我有跨节点的多线程工作。我不完全确定Haddoop或其他分布式处理系统会比你已经拥有的更多,因为你只需要对数据库进行I / O操作。

我已经使用JMS队列实现了一些simliar用于集中式日志记录,并且它运行良好,对代码的影响较小,然后将日志写入磁盘。我认为它适用于您的应用程序。