Akka与现有java项目的集成示例 [英] Example of integration Akka with existing java project

查看:104
本文介绍了Akka与现有java项目的集成示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我已经有使用 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)
公共类SomeManager {
List< Some>东西; //可变状态,这就是我在这里使用锁的原因。
//方法:add(),delete(),update()
}

我可以使它 SomeManagerActor



SomeManager 用于控制器。因此,拥有控制器Actor会很好吗?我希望收到反馈( onReceive ()方法)。



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



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



或者喜欢这个可能是写入属性文件的 actor



编辑:



例如,我现在发现:发送Actor1发给Actor2的消息我使用了一个技巧:

  //现有代码中的某处
public void initActors(){

ActorSystem system = ActorSystem.create(example);

//初始化
final ActorRef actor1 = system.actorOf(Props.create( Actor1.class),actor1);

}

Actor1有一个方法 preStart( )一旦我引用它就开始了(上图)。并且它向Actor2发送消息:

  @Override 
public void preStart(){




但是我不确定为什么要初始化两个演员来做他们的$ b $是好的b work。



解决方案

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



如果我们已经有基于Servlets / Spring MVC的现有工作Web应用程序,似乎通常没有好处如果在我们的应用程序中,请切换到 Actors / AKKA (或将演员引入现有系统只是为了破解它)我们:




  • 没有: 线程工作者逻辑,当任务是分裂在背景上。 (通常是典型的网络应用程序没有这个),比如长期计算..
    并行)。

  • 有:如果我们有顺序调用 - 当一个组件调用另一个组件时,那个
    调用另一个组件,其中调用彼此依赖:像
    控制器调用Component,Component将一些数据保存到某些组件列出
    (可变,但同步为Synchronized-list)。

  • 没有空闲时间来替换Akka演员的所有Spring控制器或完全使用不同的服务器(不是Tomcat)(没有那么多经理/产品所有者允许你这样做)



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




  • 吨消息(包含命令到/来自actor的命令的类)来自组件而不是调用常规方法(使用OPP的优点,实现接口,有几个实现 - 但Actors通常 final class )。


  • 将消息作为字符串,也不是好解决方案 - 因为它很难调试。


  • 在这样的系统(如mvc网站)中,通常没有太多的东西可以同步(它已经非常无状态)。通常每个Controller / Component中有0..2 可变共享数据。哪个并不是很难同步(只是养成一个习惯,将同步的所有内容同步到你的类顶层(这样状态可识别/本地化)。有时候你只需要 synchronized collection 或使用java Atomic 包装类型。




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




  • 当我们有长期搜索时,会经历几个来源(一种线程工作者)。有几个/拉 MasterActor - > SiteSearchActor (就像它描述的计算 PI 这里)。MasterActor有最终结果.SiteSearchActor计算(在几个站点上搜索几个客户端)。

  • 或当我们有任何线程分叉时,当前的servlet o nes

  • 当我们确切知道/我们的系统将被数百万客户使用时(即使是简单的逻辑),我们应该提前考虑可扩展性表现


    • 演员非常好 - 我们可以委派一份作品从一个演员到N-one。

    • 演员在使用线程时保险箱处理器类型( 10000个线程 10000个客户端 ,在大多数情况下, 4个线程(与处理器核心的数量相同))




但总的来说,我同意这篇关于并发 parallelism 的文章。如果我有机会从头开始申请,我会使用Akka 没有Servlets容器关心消息(命令类)和 OOP 什么时候需要使用(在一般的web应用程序中没有那么多的 OOP 。无论如何我应该说。但没有人阻止在 OOP 方式,演员只是一个沟通胶水)。这比使用JMS更好/更简单。



但就像我说的那样:



Actors / Akka适合:


  1. 服务/控制器(而不是Servlet / SpringMVC)

  2. 像逻辑这样的线程工作者

  3. 特别是对于项目从头开始(当前基础设施不会使你应用演员一个障碍)。






我现在唯一的问题是性能比较。假设我们知道:


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


如果我们对具有N的AKKA / Servlets具有相同的场景(演员,其中N > 1000>,我们很可能会有更好的表现(因为没有人阻止任何人) ,除了队列本身,不需要从一个线程切换到另一个线程。)



但即使拥有一个具有10000个客户端的系统用于基于Servlet的(线程模型)应用程序,与100客户端,它可能会很好地工作。如果我们有连接池(当然我们有)它与Actor的队列(收件箱)做同样的工作,安排客户端访问某些服务。它可以在K次中改善我们的表现(如果我们没有游泳池那么K就更多了 - 让线程绝望地相互阻挡)。



问题是:



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


以此为参数:即使在Servlers上使用旧系统,使用
连接池也可以将性能提升到良好水平。这个
级别,很可能,可能足够好,以便不将AKKA应用于
现有的Servlet应用程序,比如尝试更改servlet模型
(与控制器相比应该是坏的在AKKA之上。


这样想是否有意义?


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


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

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



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



P.S。
在大多数情况下** Future **很好足够。如果你想要安全存储状态,演员很好(基本上与Future不同)。



更新:
有些人认为这根本不是一个好主意使用Actors。有用的是 - 纯粹的功能性方法或 scalaz 已经提供的功能(以及 Haskell 我想) - 但不适用于远程通话。


If I already have existing java web application that uses spring and servlet container. What is the proper way to integrate Akka in it?

Like I'g going to have Actor1 and Actor2 that communicate with each other. What would be the entry point to start using those actors? (like: 1. put it there 2. change config 3. get reference to actor)

I found http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html But his does not provide me a glue. Just want to get real example of integration.

Is there some simple integration example?

EDIT: Application does some search, getting some data from outside, storing info to files.

The application is quite big. Some components/object can leave their own life, that is out of direct client requests, it can do some things is parallel. Like some singleton objects that has mutable state in it.

The thing is I do not know exactly where I can apply Actors, I'm investigation it. But what I have already is lots of synchronized blocks here and there.

And, it is already, I believe, kind of sign that the actors might be applied. (because I'm not sure, maybe I forgot to put some synchronized, and of course there are no integration tests for it)

About configuration, I'm just not sure should I configure some application.conf for let Actrors/Akka live there (since documentation itself describes it).

What I see:

@Component("someManager")
public class SomeManager {
 List<Some> something;  // mutable state, that why I use locks here.
 // methods: add(), delete(), update()  
}

I could make it SomeManagerActor

SomeManager is used from controller. Thus, it would be nice to have controller Actor as well ? I it want to receive feedback into (onReceive() method).

This is kind of disputable... That's one more reason why I need some example.

I believe I can improve application by getting rid of all synchronized/whait/notify stuff, moving responsibilities to actors, using messages as a way of communication with/between them.

Or like this it could be the actor to write to property files:

EDIT:

For example, for now what I found: To make Actor1 send message to Actor2 I use a trick:

// somewhere in existing code
public void initActors() {

        ActorSystem system = ActorSystem.create(example");

        // initializing
        final ActorRef actor1 = system.actorOf(Props.create(Actor1.class), "actor1");

}

Actor1 has a method preStart() that is started as soon as I get reference to it (above). And it sends message to Actor2:

@Override
public void preStart() {

But I'm not sure that it is good why to initialize two actors to do their work.

解决方案

Answering my own question. Just to share my thoughts, what I came up with.

If we already have existing working Web application based on Servlets/Spring MVC, it seems that often there is no good reason switching to Actors/AKKA (or introducing actors to the existing system just for hack of it) if in our application we:

  • Don't have: Thread workers logic, when tasks are splitting over the backround. (usually typical web application doesn't have this), like long long calculation.. (parallelism).
  • Have: If we have sequential calls - when one component calls another one, then that calls another one, where the calls are depended on each other: Like Controllers call Component, Component save some data to some List (which is mutable, but synchronized as Synchronized-list ).
  • Do not have free time to replace all Spring Controllers by Akka actors or using different Servers at all (not Tomcat) (there are not so much managers/product owners who would allow you to do that)

What is wrong having Actors in this simple system:

  • Having tons of messages (classes that wrap commands to/from actors) that come through the components instead of calling general methods (using advantages of OPP, implementing interfaces, having several implementations - but Actors usually final class).

  • Having messages as a string, not good solution either - since it's hard to debug.

  • In such a system (like mvc site), usually there are no so many things to synchronize (it is already quite stateless). Usually there are 0..2 mutable shared data in each Controller/Component. Which is not so hard to synchronize (just make a habit to put synchronize everything that is common and shared in the top of your classes (so that states are recognizable/localized). Sometimes you just need to synchronized collection or use java Atomic wrapper type.

When the Actors might be used though for existing application. Use cases are might be like this:

  • when we have long-lived search, that goes through several sources (kind of thread worker). Having several/pull of MasterActor -> SiteSearchActor (like it was described for computation PI here). The MasterActor has the final result. Where SiteSearchActor calculates (do search over several sites) for several clients.
  • or when we have any thread forks, out of current servlet ones
  • when we know for sure / figured out that our system will be used by millions of clients (even with simple logic), we should think in advance about scalability and performance (
    • actors sacale good - we can delegate one work to from one actor to N-ones.
    • actors safes processor type when working with threads (no need 10000 threads for 10000 clients, in most cases enough have 4 threads (same amount as processors core let's say) )

But in general I agree with this article about concurrency and parallelism. If I have chance to make an application from scratch, I would use Akka without Servlets container and caring somehow about messages (command classes) and OOP when it needs to be used (there are not so many OOP in general web-applications. I should say anyway. But nobody prevent keep some business logic in OOP way, actors just a communication glue). That is much better/simpler than using JMS for example.

But like I said:

Actors / Akka is good for:

  1. Services/Controllers (instead of Servlet/SpringMVC ones)
  2. Thread workers like logic
  3. Especially for project from scratch (when current infrastructure does not make you barriers applying actor one).


The only question I have now is performance comparison. Assuming we know that:

having 10000 threads in one JVM with synchronized and locks for shared mutable data in our MVC Controllers/Services are might be very bad from the performance perspective. Since there are many possible locks, threads that are concurrent (a rival or competitor for a hared resource) to each other.

If we have the same scenario for AKKA/Servlets with N (actors, where N much more less than 1000), we most likely would have much better performance (since nobody blocks anyone, except the queue itself, no need to switch from one thread to another).

But even if having a system with 10000 clients for Servlet based (thread model) application, with 100 client it might work very well. And If we have pool of connection (certainly we have) it does the same work as Actor's queue (inbox), scheduling client to have access to some piece of service. It could improve our performance in K times (where K is much more that if we didn't have pool - letting thread block each other desperately).

The question is:

Is it a good reason to not apply AKKA for existing servlet based application?

Taking this a an argument: Even having old system on Servlers, with connection pool may improve the performance to good level. And this level, most likely, might be good enough in order NOT to apply AKKA to existing Servlet application, like trying to change servlet model (that' supposed to be bad comparing to Controllers on top of AKKA).

Does it make sense to think like this?

Consider connection pull is kind of INBOX (like in AKKA) scheduling the commands (connection).

Even if Servlets model is bad (having deal with locks in the rest(active) thread that are creating by connection coming from connection pool).

It might be good enough with connection pool, which is forgotten when comparing akka to servlets based stuff. We still can tune our application, changing MAX-CONNECTION in connection pool. And usually, we do all our best to make application stateless, so, in most cases we do not synchronize anything.

But of course it is bad having only One connection pool for Whole application. If comparing to Actors each actor has each own connection pool (mailbox), and each actor might be responsible for accepting HTTP request. That model certainly better.

P.S. In most cases **Future**s are good enough. Actors are good if you want "safety" store the state in it (that differs it from Future basically).

UPDATE: Some people believe that it is bad idea at all to use Actors. What is good is - pure functional approach or something that scalaz already provides (as well as Haskell I guess) - but not for remote calls yet.

这篇关于Akka与现有java项目的集成示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆