我们正在设计一个大型的分布式事件驱动系统,用于跨事务数据库的实时数据复制。 来自源系统的数据(消息)在到达目的地之前经历了一系列转换和路由逻辑。 这些转换是多进程和多线程的操作,包括可以同时执行的较小的无状态步骤和任务。 相反,没有跨进程的共享状态,状态转换保留在数据库中,每个进程都直接从数据库中提取其工作队列。
基于此,我们需要一种在Java + Spring平台上支持分布式事件处理,路由和并发的技术,其中考虑的三个选项是MessageBroker(RabbitMQ),Spring Integration和Akka。
RabitMQ: MQ是首选,因为它是消息传递/事件处理的传统且经过验证的解决方案。 RabbitMQ,因为它是流行的轻量级开源选项,并获得了我们已经使用过的供应商的商业支持。 RabbitMQ给我留下了深刻的印象,它易于使用,精简但仍支持高级分发和消息传递功能。 它对我们而言唯一缺少的是在Oracle中保留消息的能力。
即使RabbitMQ是开放源代码(免费),但对于企业而言,它还是有相当大的成本因素。 由于MQ是中间件堆栈中的一个附加组件,因此它需要专门的人员来进行管理和维护以及产品的商业支持。 同样,MesageBroker的设置和配置也有其自身的复杂性,并且涉及跨团队的协调。
MQ主要是EAI产品,并提供跨平台(多语言,多协议)支持。 当仅用作异步并发和并行解决方案时,它们可能会过于庞大和昂贵。
Spring集成: Spring有一些模块可提供可扩展的异步执行。 Spring TaskExecutor通过轻量级线程池选项提供异步处理。 Spring Batch允许通过Job Launcher和Job Repository进行分布式异步处理。 Spring Integration通过提供EAI功能,消息传递,路由和中介功能进一步扩展了它。
尽管所有三个Spring模块都具有某些必需的功能,但很难将所有内容组合在一起。 像这个用户一样,我期望Spring Integration将具有类似RMI的远程处理功能。
Akka Java: Akka是一个工具箱和运行时,用于在JVM上构建高度并发,分布式和容错的事件驱动的应用程序。 它具有Java API,因此我决定尝试一下。
Akka很容易上手,我发现Activator很有帮助。 Akka基于Actor模型,该模型是在没有共享对象和阻塞的情况下实现并发的消息传递范例。 在Akka中,不是直接调用对象,而是构造了一条消息,并通过actor引用将其发送到该对象(称为actor )。 这种设计大大简化了
并发管理。
但是,简单性并不意味着可以在不更改代码的情况下将传统的基于锁的并发程序(线程/同步)转换为Akka。 人们需要通过定义较小的任务,消息和它们之间的通信来设计其Actor系统。 Akka的概念和Actor Model范例有一个学习曲线。 考虑到并发和并行性的复杂性,它相对较小。
Akka提供了正确的抽象级别,您不必担心共享状态的线程和同步,但是您具有完全的灵活性和控制权来编写自定义并发解决方案。
除了简单性,我还认为Akka的真正功能是远程处理及其将角色分布在多个节点上以实现高可伸缩性的能力。 Akka的位置透明性和容错性使扩展和分发应用程序变得容易,而无需更改代码。
我能够轻松地为我的多进程和多线程用例构建一个PoC。 我仍然需要解决Actor中的Spring注入问题。
请注意,由于Scala的类型系统,Akka的Java代码具有大量的类型转换,因此实现对象可变性可能很棘手。 我很想将现有的JPA实体(可变)重用为消息,以减少数据库调用。
此外,Akka社区面向Scala,并且Akka Java上的资料较少。
尽管如此,Akka Java在这三种中似乎是更便宜,更快和更高效的选择。
翻译自: https://www.javacodegeeks.com/2014/05/akka-java-for-large-scale-event-processing.html