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

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

就像我要让Actor1Actor2相互通信。开始使用这些参与者的切入点是什么? (例如: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() {

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

参考方案

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

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

不需要:线程任务在后台拆分时的逻辑。 (通常,典型的Web应用程序没有此功能),例如长而长的计算。
(并行)。
有:如果我们有顺序调用-当一个组件调用另一组件时,则
呼叫另一个,呼叫之间相互依赖:喜欢
控制器调用Component,Component将一些数据保存到某些List
(这是可变的,但已同步为Synchronized-list)。
没有足够的时间来由Akka actor来替换所有Spring Controller或根本不使用其他服务器(不是Tomcat)(没有那么多的经理/产品所有者可以让您这样做)

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

具有通过组件而不是调用常规方法(利用OPP的优点,实现接口,具有多个实现-但Actor通常final class)的大量消息(将消息包装到actor或从actor封装的类)。
将消息作为string也不是一个好的解决方案-因为很难调试。
在这样的系统中(例如MVC站点),通常没有太多要同步的东西(它已经很stateless了)。每个控制器/组件中都有0..2 mutable shared data。同步起来并不难(只需养成使所有常见和共享的东西都同步到类顶部的习惯(这样就可以识别/本地化状态)。有时您只需要synchronized collection或使用java Atomic包装器类型。

但是,何时将Actors用于现有应用程序。用例可能是这样的:

当我们进行长期的搜索时,它会涉及多个来源(例如线程工作者)。 MasterActor-> SiteSearchActor具有多个/拉数(就像针对计算PI here所描述的那样)。 MasterActor具有最终结果。 SiteSearchActor为多个客户端计算(在多个站点进行搜索)的位置。
或当我们有任何线程分叉时,从当前servlet的线程分叉中
当我们确定/确定我们的系统将被数百万个客户使用(即使使用简单的逻辑)时,我们应该事先考虑scalabilityperformance

演员的规模很好-我们可以将一件作品从一位演员委托给N位演员。
actors在使用线程时保护处理器类型(对于10000个客户端不需要10000个线程,在大多数情况下,足够有4个线程(与处理器核心数量相同))

但总的来说,我同意关于concurrencyparallelism的this文章。如果我有机会从头开始创建一个应用程序,那么我将使用不带Servlets容器的Akka,并在需要使用消息时关注消息(命令类)和OOP(一般Web应用程序中没有多少OOP)。无论如何,我应该说,但是没有人能以OOP的方式保留一些业务逻辑,而参与者只是沟通的粘合剂。例如,这比使用JMS更好/更简单。

但是就像我说的:

演员/ Akka擅长:

服务/控制器(而不是Servlet / SpringMVC的)
线程工作者喜欢逻辑
特别是对于从头开始的项目(当当前的基础结构不会使您难以应用actor时)。

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

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

如果我们对具有N个(角色,N远远小于1000)的AKKA / Servlet,具有相同的方案,则我们很可能会具有更好的性能(因为除了队列本身之外,没有人阻塞任何人,因此无需从一个线程切换到其他线程)到另一个)。

但是,即使对于基于Servlet(线程模型)的应用程序,如果它具有10000个客户端的系统,但具有100个客户端的系统,也可能会很好地工作。而且,如果我们有一个连接池(肯定有),它的作用与Actor的队列(收件箱)相同,则安排客户端访问某些服务。它可以提高K倍的性能(其中K比没有池的情况要多得多-让线程拼死地互相阻塞)。

问题是:

不将AKKA应用于现有的基于servlet的应用程序是否有充分的理由?

以此为理由:即使在服务器上拥有旧系统,
connection pool可以将性能提高到一个很好的水平。还有这个
级别,很可能足以将其应用于AKKA
现有的Servlet应用程序,例如尝试更改Servlet模型
(与AKKA之上的Controllers相比,这应该是不好的)。

这样思考是否有意义?

考虑连接拉是一种INBOX(例如AKKA中的)来调度
命令(连接)。

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

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

但是,当然,对于整个应用程序只有一个连接池是很糟糕的。如果与Actor进行比较,则每个actor都有自己的连接池(邮箱),并且每个actor可能负责接受HTTP请求。该模型肯定更好。

附言
在大多数情况下,Future足够好。如果您希望“安全性”将状态存储在状态中(最好与“将来”有所不同),则参与者是很好的。

更新:
Some people认为使用Actor根本不是一个好主意。好的是-纯函数方法或scalaz已经提供的某些功能(以及我想的Haskell)-但尚不适用于远程调用。

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…