将 Akka 与现有 java 项目集成的示例
Posted
技术标签:
【中文标题】将 Akka 与现有 java 项目集成的示例【英文标题】:Example of integration Akka with existing java project 【发布时间】:2013-05-11 20:00:01 【问题描述】:如果我已有使用 spring
和 servlet
容器的现有 java
Web 应用程序。将 Akka 集成到其中的正确方法是什么?
就像我要让Actor1
和Actor2
相互通信一样。开始使用这些演员的切入点是什么? (比如:1. 把它放在那里 2. 改变配置 3. 获取对actor的引用)
我找到了http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html 但他没有给我胶水。只是想获得集成的真实示例。
有一些简单的集成示例吗?
编辑: 应用程序进行一些搜索,从外部获取一些数据,将信息存储到文件中。
应用程序很大。一些组件/对象可以离开自己的生命,即出于客户端的直接请求,它可以做一些并行的事情。就像一些具有可变状态的单例对象一样。
问题是我不知道我可以在哪里申请演员,我正在调查它。但是我已经在这里和那里有很多同步块。
而且,我相信,这已经是演员可能被应用的一种迹象。 (因为我不确定,可能我忘了放一些同步的,当然也没有集成测试)
关于配置,我只是不确定我是否应该配置一些 application.conf 以让 Actrors/Akka 住在那里(因为文档本身描述了它)。
我看到了什么:
@Component("someManager")
public class SomeManager
List<Some> something; // mutable state, that why I use locks here.
// methods: add(), delete(), update()
我可以做到SomeManagerActor
SomeManager
使用自 controller
。因此,拥有控制器 Actor 会很好吗?我想收到反馈到(onReceive
() 方法)。
这有点争议...这也是我需要一些示例的原因。
我相信我可以通过摆脱所有synchronized/whait/notify
的东西,将责任转移给参与者,使用消息作为他们之间/之间的沟通方式来改进应用程序。
或者像this,它可能是写入属性文件的参与者:
编辑:
例如,现在我发现:为了让 Actor1 向 Actor2 发送消息,我使用了一个技巧:
// somewhere in existing code
public void initActors()
ActorSystem system = ActorSystem.create(example");
// initializing
final ActorRef actor1 = system.actorOf(Props.create(Actor1.class), "actor1");
Actor1 有一个方法preStart()
,只要我得到它的引用就会启动它(上图)。并向 Actor2 发送消息:
@Override
public void preStart()
但我不确定为什么要初始化两个演员来做他们的 工作。
【问题讨论】:
如果您说出您的应用程序是什么以及为什么需要 akka,这将有所帮助。我不明白为什么 Web 应用程序需要 akka,因为您已经拥有消息和异步方法 (Java EE6)。 【参考方案1】:回答我的问题。只是为了分享我的想法,我想出了什么。
如果我们已经有基于 Servlets/Spring MVC 的现有工作 Web 应用程序,似乎通常没有充分的理由切换到 Actors
/AKKA
(或将参与者引入现有系统只是为了破解它)如果在我们的应用程序中:
在这个简单的系统中使用 Actors 有什么问题:
通过组件而不是调用通用方法(利用 OPP 的优势,实现接口,有多个实现——但 Actors 通常是final class
)。
将消息作为 string
,也不是一个好的解决方案 - 因为它很难调试。
在这样的系统中(比如 MVC 站点),通常没有那么多东西需要同步(已经相当stateless
)。每个控制器/组件中有 0..2 个mutable shared data
。同步并不难(只需养成将所有常见和共享的同步放在类顶部的习惯(以便状态可识别/本地化)。有时您只需要 synchronized collection
或使用 java Atomic
包装器输入。
当 Actor 可能用于现有应用程序时。用例可能是这样的:
当我们进行长期搜索时,它会经过多个来源(一种线程工作者)。有几个/拉MasterActor
-> SiteSearchActor
(就像它被描述为计算PI
here)。 MasterActor 有最终结果。 SiteSearchActor 为多个客户计算(在多个网站上进行搜索)的位置。
或者当我们有任何线程分叉时,在当前的 servlet 之外
当我们确定/发现我们的系统将被数百万客户使用时(即使是简单的逻辑),我们应该提前考虑scalability
和performance
(
演员规模大 - 我们可以将一项工作从一名演员委托给 N 人。
参与者在处理线程时保护处理器类型(对于 10000 个客户端,不需要 10000 个线程,在大多数情况下足够有 4 个线程(假设与处理器核心数量相同))
但总的来说,我同意this 关于concurrency
和parallelism
的文章。如果我有机会从头开始制作应用程序,我会使用 Akka 没有 Servlets 容器 并且 以某种方式关心消息(命令类)和 OOP当需要使用它时(在一般的网络应用程序中没有那么多OOP
。无论如何我应该说。但没有人阻止以OOP
的方式保留一些业务逻辑,演员只是一种沟通粘合剂)。例如,这比使用 JMS 更好/更简单。
但就像我说的:
Actor / Akka 适合:
-
服务/控制器(而不是 Servlet/SpringMVC 的)
像逻辑一样的线程工作者
特别是对于从头开始的项目(当当前的基础设施不妨碍您应用 actor one 时)。
我现在唯一的问题是performance comparison
。假设我们知道:
在一个 JVM 中拥有 10000 个线程,具有同步和共享锁 我们的 MVC 控制器/服务中的可变数据可能非常糟糕 从性能的角度。因为有很多可能的锁, 并发线程(hared 的竞争对手或竞争对手 资源)彼此。
如果我们对具有 N 的 AKKA/Servlet 有相同的场景(参与者,其中 N 比 小于 多于 1000),我们很可能会有更好的性能(因为没有人阻止任何人,除了队列本身,无需从一个线程切换到另一个)。
但是,即使有一个具有 10000 个客户端的基于 Servlet(线程模型)应用程序的系统,具有 100 个客户端它也可能工作得很好。如果我们有一个连接池(当然我们有),它与 Actor 的队列(收件箱)做同样的工作,调度客户端访问某些服务。它可以在 K 次内提高我们的性能(如果我们没有池,K 会更多 - 让线程拼命地相互阻塞)。
问题是:
对于现有的基于 servlet 的应用程序不应用 AKKA 是否有充分的理由?
这是一个论据:即使在服务器上有一个旧系统,与
connection pool
可以将性能提高到一个很好的水平。和这个 水平,很可能,可能足够好,以便不将 AKKA 应用于 现有的 Servlet 应用程序,例如尝试更改 Servlet 模型 (与 AKKA 之上的控制器相比,这应该很糟糕)。
这样想有意义吗?
考虑连接拉取是一种收件箱(就像在 AKKA 中一样)调度 命令(连接)。
即使 Servlets 模型不好(处理由来自连接池的连接创建的剩余(活动)线程中的锁)。
连接池可能已经足够好了,在将 Akka 与基于 servlet 的东西进行比较时,它被遗忘了。我们仍然可以调整我们的应用程序,更改连接池中的 MAX-CONNECTION。通常,我们会尽最大努力使应用程序无状态,因此,在大多数情况下,我们不会同步任何内容。
当然,对于整个应用程序只有一个连接池是不好的。如果与 Actor 相比,每个 Actor 都有自己的连接池(邮箱),并且每个 Actor 可能负责接受 HTTP 请求。那个模型肯定更好。
附: 在大多数情况下,Futures 就足够了。如果您希望“安全”地在其中存储状态,则 Actor 是很好的(这与 Future 基本上不同)。
更新:
Some people 相信使用 Actors 是个坏主意。好的是 - 纯函数方法或 scalaz 已经提供的东西(我猜还有 Haskell
) - 但还不适用于远程调用。
【讨论】:
【参考方案2】:我也遇到过类似的问题。
我同意将 AKKA 添加到具有少量用户的简单网络应用程序中几乎没有什么好处。
但我认为将 AKKA 附加到现有的 spring mvc 应用程序并不难。如果您的项目需要扩展,您可以将 @Service 层包装到参与者中。 因此,@Controllers 不需要在演员内部。
这是一个关于将 spring 与 akka 合并的演示文稿: https://www.youtube.com/watch?v=fALUf9BmqYE
演示文稿的源代码: https://github.com/jsuereth/spring-akka-sample/tree/master/src/main/java/org/springframework/samples/travel
【讨论】:
以上是关于将 Akka 与现有 java 项目集成的示例的主要内容,如果未能解决你的问题,请参考以下文章
将 Akka 与 Spring 和 OSGI 集成(未找到密钥“akka”的配置设置)
大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目(示例代