Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM
-
Upload
daniel-sobral -
Category
Technology
-
view
1.308 -
download
0
description
Transcript of Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM
Uma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM
AkkaUma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM
• Daniel Capó Sobral• Consultor pela Tecnisys• Programador e Sysadmin• Ex-committer FreeBSD• Aficionado por Scala
AkkaUma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM
Conheça Akka, uma plataforma para o JVM para desenvolvimento de sistemas concorrentes e/ou distribuídos através do paradigma de Atores.
Descreveremos o paradigma de atores, suas vantagens e desvantagens, e mostraremos exemplos da API em Java e em Scala, com execução local e distribuída, memória transacional e tolerância a falhas.
Conteúdo
• O que é Akka?• Para que serve?• O que são atores?
Objetivos Principais
• Ensinar Akka• Ensinar programação com atores• Mostrar todos os módulos de Akka
Não é tema
O QUE É AKKA?
Uma cadeia de montanhas?
Uma cadeia de montanhas?• “Akka” é uma cadeia de montanhas na Suécia
Um componente do Typesafe Stack?
Um componente do Typesafe Stack?• A Typesafe foi fundada em 2011 pelos criadores da
linguagem de programação Scala e do middleware Akka.• O Typesafe Stack contém Scala, Akka e ferramentas de
desenvolvimento, tudo open source.• A Typesafe Subscription provê suporte comercial.
Uma solução de:
Concorrência
Escalabilidade
Tolerância à Falhas
Uma solução de:
• Atores• STM• Agentes• Dataflow
Concorrência
Escalabilidade
Tolerância à Falhas
Uma solução de:
Concorrência
• Vertical• Atores
• Horizontal• Atores Remotos• Gestão de Cluster
Escalabilidade
Tolerância à Falhas
Uma solução de:
Concorrência
Escalabilidade
• Supervisão de Atores• Todos Por Um• Cada Um Por Si
• “Deixe falhar”
Tolerância à Falhas
Concorrência
Atores
STM
Agentes
Dataflow
Atores
• Popularizou o conceito• 9 9s de disponibilidade
Erlang
• Atores como prova de conceito
Scala
• Novo design• Solução completa
Akka
Objetos vs Atores
• Públicos• Privados
Métodos
• Rascunho• Estático• Dinâmico
Estado
Objetos vs Atores
Objetos vs Atores
Objetos vs Atores
Objetos vs Atores
• Públicos• Privados
Métodos
• Rascunho• Estático• Dinâmico
Estado
• Orientado a eventos
Thread
Objetos vs Atores
Fatos sobre Atores
• Assíncronos• Threads próprios
Orientados à eventos
• Caixa de mensagens• Não compartilham estado!
Comunicação via mensagens
• Atores não são threads• Aproximadamente 600 bytes
Baratos
Definindo um Ator - Java
public class SampleUntypedActor extends UntypedActor { public void onReceive(Object message) throws Exception { if (message instanceof String) EventHandler.info(this, String.format("Received String message: %s", message)); else throw new IllegalArgumentException("Unknown message: " + message); }}
Criando um Ator - Java
import static akka.actor.Actors.*;ActorRef myActor = actorOf(SampleUntypedActor.class);myActor.start();
// Construtor com parâmetrosActorRef actor = actorOf(new UntypedActorFactory() { public UntypedActor create() { return new MyUntypedActor("service:name", 5); }}).start();
ActorRef vs Actor
• Serializável• Remote-aware
Portabilidade
• Actor é membro privado de ActorRef
Opacidade
• Actor this• ActorRef self
this vs self
Ciclo de Vida
New
• Não processa mensagens
Started
• Iniciado com “start”• Processa mensagens
Shutdown
• Iniciado com “exit” ou “stop”• Não pode fazer nada
Enviando uma mensagem
• actor.sendOneWay("Hello");
Envie e esqueça
• actor.sendOneWay("Hello", getContext());
Envie, com remetente
• Object result = actorRef.sendRequestReply("Hello", getContext(), 1000);
Envie, talvez receba resposta (ou exceção)
• Future future = actorRef.sendRequestReplyFuture("Hello", getContext(), 1000);
Envie, receba futuro
Futuros
interface Future<T> { void await(); boolean isCompleted(); boolean isExpired(); long timeoutInNanos(); Option<T> result(); Option<Throwable> exception(); Future<T> onComplete(Procedure<Future<T>> procedure);}
Usando Futuros - Java
Future future = actorRef.sendRequestReplyFuture("Hello", getContext(), 1000);future.await();if (future.isCompleted()) { Option resultOption = future.result(); if (resultOption.isDefined()) { Object result = resultOption.get(); ... } ... // whatever}
Respondendo ao Remetente - Java
public void onReceive(Object message) throws Exception { if (message instanceof String) { String msg = (String)message; if (msg.equals("Hello") && getContext().getSenderFuture().isDefined()) { // Reply to original sender of message using the channel getContext().channel().sendOneWay(msg + " from " + getContext().getUuid()); } }}
Respondendo Mensagem - Java
public void onReceive(Object message) throws Exception { if (message instanceof String) { String msg = (String)message; if (msg.equals("Hello")) { if (getContext().replySafe(msg + " from " + getContext().getUuid())) ... // success else ... // handle failure } }}
Parando um Ator - Java
actor.stop();
Akka em Scala
• router.tell(new Work(arg, nrOfElements), getContext());
• router ! Work(arg, nrOfElements)
Concisão
• val a = actorOf(new MyActor(..)).start()
Parâmetros “by-name”
• Ver exemplo de concisão acima!
Parâmetros implícitos
Akka em Scala
• case class Work(arg: Int, nrOfElements: Int)
• Coleções imutáveis por default• Estruturas de dados persistentes
Melhor suporte a imutabilidade
• case Work(arg, n) => // do stuff
Pattern matching
Typed Actors
• Requer Interface + Implementation
POJO -> TypedActors
• AspectWerkz Proxy
AOP
• Métodos viram mensagens assíncronas!
Objetos -> Atores
Agentes
Inspirado nos Agentes de Clojure
• Uma modificação de cada vez• Modificações de cada origem processadas em ordem
Modificações Assíncronas
• Toma parte em transações
Integrado ao STM
• Valor “atual” após todas modificações enfileiradas
Futuros
Agentes - Scala
• val agent = Agent(5)• agent.close()
Criando e Parando
• agent send 7• agent send (_ + 1)
Alterando
• val result = agent()• val result = agent.future.await.result.get
Lendo
STM
• Estado compartilhado• Transações multi-atores (transactors)
Mutabilidade Controlada
Modelo Clojure de Referências
Multiverse STM
STM - Java
final Ref<Integer> ref = new Ref<Integer>(0);
public int counter() { return new Atomic<Integer>() { public Integer atomically() { int inc = ref.get() + 1; ref.set(inc); return inc; } }.execute();}
Dataflow
• Mesmo resultado todas as vezes• Baseado em futuros• Scala Delimited Continuations
Concorrência Determinística
Derivado da linguagem Oz
• Exceções, data/hora, números aleatórios, etc
Nada de efeitos colaterais!
Dataflow - Scala
• val x = Promise[Int]()
Declarar variável dataflow
• flow { ... x() ... }
Usar valor
• flow { ... x << 5 ... }
Assinalar valor
• flow { ... x << y ... }
Assinalar a uma outra variável
Escalabilidade
• Atores• Dataflow
Vertical
• Atores Remotos• Gestão de Cluster
Horizontal
Atores Remotos - Java
// server code class HelloWorldActor extends UntypedActor { public void onReceive(Object msg) { getContext().replySafe(msg + " World"); } } remote().start("localhost", 9999).register( "hello-service", actorOf(HelloWorldActor.class));
// client code ActorRef actor = remote().actorFor( "hello-service", "localhost", 9999); Object res = actor.sendRequestReply("Hello");
Atores Remotos
Um por tipo
Um por sessão
Um por requisição
Tolerância à Falhas
• Não se proteja de exceções• Deixe outro lidar com o problema
Deixe falhar...
• Erlang OTP• Proteção em Profundidade
Supervisores
• OneForOne• AllForOne
Estratégias de Supervisão
Tolerância à Falhas
• Recuperável• Não-recuperável
Estado
• Antes da reinicialização• Depois da reinicialização
Ganchos de reinicialização
• Permanente• Temporário
Ciclo de vida
Só isso?
• getContext().forward(message, getContext());
Encaminhando mensagens para outro Ator
• become(scatter);• actor ! HotSwap( self => { case
message => self.reply("hotswapped body") })
Alterando o comportamento de um ator
Só isso?
• Por eventos• Por thread• Eventos priorizados• Eventos com work-stealing
Dispatcher
• Dispatcher (roteador, não módulo)• Load balance• Actor pool
Routing
• Usados por atores, agentes, dataflow e outros componentes
Futuros
Só isso?
Crédito:Palestra Above the Clouds: Introducing Akka
Jonas Bonér
Contato
• [email protected]• http://dcsobral.blogspot.com/• http://github.com/dcsobral• @dcsobral
Daniel Capó Sobral