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:
- Services/Controllers (instead of Servlet/SpringMVC ones)
- Thread workers like logic
- 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.
I have come across a similar problem.
I agree that there is little benefit of adding AKKA to simple web appliaciton with a small number of users.
But I don't think that it is hard to attach AKKA to existing spring mvc app. In case your project needs to scale you can wrap your @Service layer into actors.
Hence, @Controllers do not need to be inside actors.
Here is a presentation on merging spring with akka:
https://www.youtube.com/watch?v=fALUf9BmqYE
Source code for the presentation:
https://github.com/jsuereth/spring-akka-sample/tree/master/src/main/java/org/springframework/samples/travel