2011-11-13 19 views
59

Soy nuevo en el framework Akka y estoy construyendo una aplicación de servidor HTTP sobre Netty + Akka.Akka - ¿Cuántas instancias de un actor debería crear?

Mi idea hasta ahora es crear un actor para cada tipo de solicitud. P.ej. Tendría un actor para un POST to/my-resource y otro actor para un GET to/my-resource.

Donde estoy confundido es ¿cómo debo hacer para crear un actor? Debería:

  1. Crear un nuevo actor para cada solicitud (con esto quiero decir para cada solicitud debería hacer un TypedActor.newInstance() del actor apropiado)? ¿Qué tan caro es crear un nuevo actor?

  2. Crear una instancia de cada actor en el inicio del servidor y utilizar esa instancia actor para cada solicitud? He leído que un actor solo puede procesar un mensaje a la vez, ¿no podría ser esto un cuello de botella?

  3. ¿Hacemos algo más?

Gracias por cualquier comentario.

Respuesta

30

Bueno, crea un Actor para cada instancia de estado mutable que desee administrar.

En su caso, podría tratarse de un solo actor si my-resource es un único objeto y desea tratar cada solicitud en serie, lo que garantiza fácilmente que solo devuelva estados consistentes entre las modificaciones.

Si (más probable) gestiona varios recursos, un actor por instancia de recurso suele ser ideal a menos que se encuentre con muchos miles de recursos. Si bien también puede ejecutar actores por solicitud, terminará con un diseño extraño si no piensa en el estado al que están accediendo esas solicitudes, p. si solo crea un Actor por solicitud POST, se encontrará preocupado de cómo evitar que modifique simultáneamente el mismo recurso, lo que es una clara indicación de que ha definido a sus actores de manera incorrecta.

Normalmente tengo actores de solicitud/respuesta bastante triviales cuyo objetivo principal es abstraer la comunicación con sistemas externos. Su comunicación con los actores de "instancia" normalmente se limita a un par de solicitud/respuesta para realizar la acción real.

8
  1. Es una opción bastante razonable, pero si es adecuada depende de los detalles del manejo de su solicitud.

  2. Sí, por supuesto que podría.

  3. En muchos casos, lo mejor sería tener un solo actor respondiendo a cada solicitud (o tal vez un actor por tipo de solicitud), pero lo único que hace este actor es reenviar la tarea a otro actor (o generar un Future) que realmente hará el trabajo.

+0

En 3), ¿no significaría eso que si la máquina que ejecuta el actor tiene más de un núcleo, no se usará correctamente? – Diego

+1

@Diego No, ya que los actores/futuros a los que se dirige pueden funcionar en esos núcleos. –

20

Si está utilizando Akka, puede crear un actor por solicitud.Akka es extremadamente delgada en recursos y puede crear literalmente millones de actores en un montón bastante común de JVM. Además, solo consumirán cpu/stack/threads cuando realmente hagan algo.

Hace un año hice un comparison entre el consumo de recursos de los actores estándar basados ​​en hilos y en eventos. Y Akka es incluso mejor que la base de eventos.

Uno de los grandes puntos de Akka en mi opinión es que permite a diseñar su sistema como "un actor por uso", donde los sistemas de actor anteriores menudo se ven obligados que haga "utilice sólo los actores para los servicios compartidos" debido a la sobrecarga de recursos.

recomendaría que vaya a la opción 1.

20

Opciones 1) o 2) tienen ambos sus inconvenientes. Así pues, vamos a utilizar opciones 3) Routing (Akka 2.0+)

router es un elemento que actúa como un equilibrador de carga , encaminar las solicitudes a otros actores que llevará a cabo la tarea necesaria.

Proveedores de Akka diferentes Implementaciones de enrutadores con lógica diferente para enrutar un mensaje (por ejemplo, SmallestMailboxPool o RoundRobinPool).

Cada Enrutador puede tener varios hijos y su tarea es supervisar su Buzón de correo para decidir dónde enrutar el mensaje recibido.

//This will create 5 instances of the actor ExampleActor 
//managed and supervised by a RoundRobinRouter 
ActorRef roundRobinRouter = getContext().actorOf(
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(5)),"router"); 

Este procedimiento se explica bien en this blog.

Cuestiones relacionadas