18

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

就像我将要拥有Actor1Actor2那样相互交流。开始使用这些演员的切入点是什么?(例如:1. 放在那里 2. 更改配置 3. 获取参与者的引用)

我找到了http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html但他没有给我胶水。只是想获得集成的真实示例。

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

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

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

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

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

关于配置,我只是不确定是否应该配置一些 application.conf 让 Actors/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东西,将责任转移给演员,使用消息作为他们之间/之间的沟通方式来改进应用程序。

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

编辑:

例如,现在我发现:为了让 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() {

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

4

2 回答 2

29

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

如果我们已经有基于 Servlets/Spring MVC 的现有工作 Web 应用程序,那么如果在我们的应用程序中,我们通常没有充分的理由切换到Actors/ AKKA(或将参与者引入现有系统只是为了破解它):

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

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

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

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

  • 在这样的系统中(比如 MVC 站点),通常没有那么多东西需要同步(已经相当了stateless)。mutable shared data每个控制器/组件中有 0..2个。同步并不难(只需养成将所有常见和共享的同步放在类顶部的习惯(以便状态可识别/本地化)。有时您只需要synchronized collection或使用 javaAtomic包装器类型。

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

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

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

但就像我说的:

演员 / Akka 适合:

  1. 服务/控制器(而不是 Servlet/SpringMVC 的)
  2. 线程工作者喜欢逻辑
  3. 特别是对于一个从头开始的项目(当当前的基础设施不妨碍你应用参与者一时)。

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

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

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

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

问题是:

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

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

这样想有意义吗?

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

即使Servlets 模型不好(处理由来自连接池的连接创建的剩余(活动)线程中的锁)。

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

但是当然,整个应用程序只有一个连接池是不好的。如果与 Actor 相比,每个 Actor 都有自己的连接池(邮箱),并且每个 Actor 可能负责接受 HTTP 请求。那个模型肯定更好。

PS 在大多数情况下,Future已经足够好了。如果您希望“安全”将状态存储在其中(这与 Future 基本上不同),则 Actor 很好。

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

于 2013-05-21T16:13:43.570 回答
3

我遇到了类似的问题。

我同意将 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

于 2014-12-05T22:17:14.230 回答