将 Akka 与现有 java 项目集成的示例

2022-09-02 20:37:47

如果我已有使用和容器的现有 Web 应用程序。将Akka集成到其中的正确方法是什么?javaspringservlet

就像我将要拥有的那样,它们彼此沟通。开始使用这些参与者的切入点是什么?(例如:1.把它放在那里 2.更改配置 3.获取对actor的引用)Actor1Actor2

我发现 http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html 但他没有为我提供胶水。只是想获得集成的真实示例。

有没有一些简单的集成示例?

编辑:应用程序进行一些搜索,从外部获取一些数据,将信息存储到文件中。

该应用程序非常大。有些组件/对象可以离开自己的生命,即脱离了客户端的直接请求,它可以做一些并行的事情。就像一些具有可变状态的单例对象一样。

问题是我不知道我在哪里可以应用Actor,我正在调查它。但是我已经在这里和那里有很多同步块。

而且,我相信,这已经是一种迹象,表明演员可能会被应用。(因为我不确定,也许我忘了放一些同步,当然也没有集成测试)

关于配置,我只是不确定我是否应该配置一些appplication.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从 使用。因此,拥有控制器Actor也会很好吗?我想接收反馈到(()方法)。controlleronReceive

这是有争议的...这就是我需要一些例子的另一个原因。

我相信我可以通过摆脱所有的东西,将责任转移给参与者,使用消息作为与他们之间沟通的一种方式来改善应用程序。synchronized/whait/notify

或者像这样,它可能是写入属性文件的参与者

编辑:

例如,现在我发现:为了让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 有一个方法,一旦我得到对它的引用,它就会启动(上图)。它向Actor2发送消息:preStart()

@Override
public void preStart() {

但我不确定为什么要初始化两个参与者来完成他们的工作。


答案 1

回答我的问题。只是为了分享我的想法,我想出了什么。

如果我们已经有基于Servlets / Spring MVC的现有工作Web应用程序,那么在我们的应用程序中,如果我们:ActorsAKKA

  • 没有:任务在后台拆分时线程工作线程逻辑。(通常,典型的Web应用程序没有这个),就像长长的计算一样。(并行性)。
  • 有:如果我们有顺序调用 - 当一个组件调用另一个组件时,那么调用另一个组件,其中调用相互依赖:就像控制器调用组件一样,组件将一些数据保存到某个列表中(这是可变的,但同步为Sync-list)。
  • 没有空闲时间用Akka actor或使用不同的服务器(不是Tomcat)替换所有Spring Controller(没有那么多经理/产品所有者会允许你这样做)

在这个简单的系统中有Actor有什么问题:

  • 有大量的消息(将命令包装到/来自actor的类)来自组件而不是调用通用方法(使用OPP的优点,实现接口,具有多个实现 - 但Actor通常是)。final class

  • 将消息作为 ,也不是一个好的解决方案 - 因为它很难调试。string

  • 在这样的系统(如MVC站点)中,通常没有那么多东西需要同步(它已经相当了)。每个控制器/组件中有 0..2。这并不难同步(只要养成一个习惯,把同步所有常见和共享的东西放在类的顶部(这样状态是可识别的/本地化的)。有时你只需要或使用java包装器类型。statelessmutable shared datasynchronized collectionAtomic

当 Actor 可能用于现有应用程序时。用例可能是这样的:

  • 当我们有长期的搜索时,它会通过几个来源(一种线程工作者)。具有几个/拉->(就像这里描述的计算一样)。MasterActor有最终结果。其中 SiteSearchActor 为多个客户端计算(在多个站点上进行搜索)。MasterActorSiteSearchActorPI
  • 或者当我们有任何线程分叉时,从当前的servlet中取出
  • 当我们确定/发现我们的系统将被数百万客户使用(即使使用简单的逻辑)时,我们应该提前考虑和scalabilityperformance (
    • 演员规模好 - 我们可以将一个演员的一个作品委托给N个。
    • actor在使用线程时保护处理器类型(10000个客户端不需要10000个线程,在大多数情况下,足够有4个线程(与处理器核心的数量相同))

但总的来说,我同意篇关于 和 .如果我有机会从头开始创建一个应用程序,我会使用没有Servlets容器的Akka,并在需要使用时以某种方式关心消息(命令类)和OOP(在一般的Web应用程序中没有那么多)。无论如何,我应该说。但是没有人阻止保持一些业务逻辑的方式,参与者只是一个沟通粘合剂)。这比使用JMS更好/更简单。concurrencyparallelismOOPOOP

但就像我说的:

演员 / 阿卡适合:

  1. 服务/控制器(而不是Servlet/SpringMVC)
  2. 像逻辑一样的线程工作线程
  3. 特别是对于一个从头开始的项目(当当前的基础设施不会让你遇到应用actor的障碍时)。

我现在唯一的问题是.假设我们知道:performance comparison

从性能角度来看,在一个JVM中具有10000个线程,并在我们的MVC控制器/服务中同步和锁定共享可变数据,这可能是非常糟糕的。由于有许多可能的锁,因此线程彼此并发(hared 资源的竞争对手或竞争对手)。

如果我们对带有N的AKKA / Servlets(actor,其中N远小于1000)有相同的场景,我们很可能会有更好的性能(因为除了队列本身之外,没有人阻止任何人,不需要从一个线程切换到另一个线程)。

但是,即使系统具有10000个客户端(用于基于Servlet的(线程模型)应用程序,具有100个客户端,它也可能运行良好。如果我们有一个连接池(当然我们有),它执行与Actor的队列(收件箱)相同的工作,安排客户端访问某些服务。它可以在K次中提高我们的性能(如果我们没有池 -- 让线程拼命地相互阻塞),K 值会高得多)。

问题是:

不将 AKKA 应用于现有的基于 servlet 的应用程序是否是一个很好的理由?

采取这是一个论点:即使在服务器上有一个旧系统,with 也可以将性能提高到一个很好的水平。这个级别很可能足够好,以便不将AKKA应用于现有的Servlet应用程序,比如尝试更改Servlet模型(与AKKA之上的控制器相比,这应该很糟糕)。connection pool

这样想有意义吗?

考虑连接拉取是一种收件箱(如AKKA)调度命令(连接)。

即使 Servlets 模型很糟糕(在通过来自连接池的连接创建的 rest(active) 线程中处理锁)。

使用连接池可能已经足够好了,在将Akka与基于servlet的东西进行比较时,这被遗忘了。我们仍然可以调整我们的应用程序,更改连接池中的 MAX 连接。通常,我们会尽最大努力使应用程序无状态,因此,在大多数情况下,我们不会同步任何内容。

但是,当然,对于整个应用程序只有一个连接池是不好的。如果与执行组件进行比较,则每个执行组件都有自己的连接池(邮箱),并且每个执行组件可能负责接受 HTTP 请求。这种模式当然更好。

附言:在大多数情况下,Futures已经足够好了。如果你想让“安全”在其中存储状态,那么演员是好的(这与未来基本上不同)。

更新:有些人认为使用Actor是一个坏主意。好的是 - 纯函数方法或scalaz已经提供的东西(以及我猜的) - 但还不适用于远程调用。Haskell


答案 2

我遇到了类似的问题。

我同意将AKKA添加到具有少量用户的简单Web应用程序中几乎没有什么好处。

但我不认为将AKKA附加到现有的弹簧mvc应用程序很难。如果您的项目需要扩展,您可以将@Service图层包装到Actor中。因此,@Controllers不需要是演员内部。

以下是关于将春天与akka合并的演示文稿:https://www.youtube.com/watch?v=fALUf9BmqYE

演示文稿的源代码:https://github.com/jsuereth/spring-akka-sample/tree/master/src/main/java/org/springframework/samples/travel


推荐