akka(7)Akka Remote Actor and Akka in Spray

akka(7)Akka Remote Actor and Akka in Spray
 
Dispatcher is to pick up the thread to execute the message box and actor.
Router is an actor to route the message to different actors.
 
1. Akka System
router to jvm Akka System.
A very Simple Actor, just receive the Message and Print, EventMessageActor.
package com.sillycat.akka.actor
 
import akka.actor.Actor
import com.typesafe.scalalogging.slf4j.Logging
import com.sillycat.akka.model.EventMessage
 
class EventMessageActor extends Actor with Logging {
  logger.info("Created a EventMessage Actor")
  def receive = {
    case item: EventMessage => {
      //handle the eventMessage
      logger.debug("Logging I receive one object:" + item)
      //this will send the response back
      //sender ! item + " Server is running this task"
    }
    case item: String => {
      logger.debug("Logging I receive one object:" + item)
    }
    case _ => logger.error("Received a message I don't understand.")
  }
}
 
The WatcherActor
package com.sillycat.akka.actor
 
import akka.actor.{ Terminated, Actor, ActorRef }
import com.typesafe.scalalogging.slf4j.Logging
 
class ActorWatcher(watched: ActorRef) extends Actor with Logging {
  context.watch(watched)
  def receive = {
    case Terminated(watched) => {
      logger.info("The watched actor was terminated: " + watched.toString())
      context.system.shutdown()
    }
    case _ => logger.info("ActorWatcher got a message not intended for it!")
  }
}
 
The configuration file about this actor with router in localjvm.conf
akka {
  # Options: ERROR, WARNING, INFO, DEBUG
  loglevel = "DEBUG"
 
  # Log the complete configuration at INFO level when the actor system is started.
  # This is useful when you are uncertain of what configuration is used.
  #log-config-on-start = on
 
  actor.deployment {
    /EventMessageLocalRouter {
      router = round-robin
      resizer {
        lower-bound = 5
        upper-bound = 100
      }
    }
  }
}
 
Simple Application class, EventService for Testing
package com.sillycat.akka.server
 
import com.sillycat.akka.actor.{ ActorWatcher, EventMessageActor }
import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.slf4j.Logging
import akka.actor._
import akka.routing.{ FromConfig, RoundRobinRouter }
import akka.routing.Broadcast
import com.sillycat.akka.model.EventMessage
 
class EventService extends Logging {}
 
object EventService extends Logging {
 
  //private val logger = (new EventService()).logger
  logger.info("Starting EventService...")
 
  def startOne(item: EventMessage) = {
    router ! item
  }
 
  def shutdown() = {
    logger.info("Broadcast PoisonPill...")
    router ! Broadcast(PoisonPill)
    logger.info("EventService shut down.")
  }
 
  private lazy val actorSystem = ActorSystem("EventServiceLocalSystem", ConfigFactory.load("localjvm"))
  private lazy val router = actorSystem.actorOf(Props[EventMessageActor].withRouter(FromConfig()), name = "EventMessageLocalRouter")
 
  private lazy val routerWatcher =
    actorSystem.actorOf(Props(new ActorWatcher(router)), name = "EventMessageLocalRouterWatcher")
 
}
 
Testing Class based on EventService
package com.sillycat.akka.server
 
import com.sillycat.akka.model.EventMessage
import org.joda.time.DateTime
import org.scalatest.BeforeAndAfter
import org.scalatest.FunSuite
 
class EventServiceTest extends FunSuite with BeforeAndAfter {
 
  before {
  }
 
  after {
  }
 
  test("Testing EventService start one...") {
    def item = EventMessage(1, "request1", "request2", "admin", DateTime.now())
    Range(1, 10) foreach { i =>
      EventService.startOne(item)
    }
    Thread.sleep(1000)
    EventService.shutdown()
  }
 
}
 
2. Remote Akka System
Users/carl/work/akka/akka/akka-samples/akka-sample-remote-scala/tutorial/index.html
 
Server Side EventServiceRemoteApp.
package com.sillycat.akka.server
 
import akka.actor.{ Props, ActorSystem }
import akka.kernel.Bootable
import com.sillycat.akka.actor.EventMessageActor
import com.typesafe.config.ConfigFactory
 
class EventServiceRemoteApp extends Bootable {
 
  val system = ActorSystem("EventServiceRemoteSystem", ConfigFactory.load("remotesystem"))
 
  def startup = {
    system.actorOf(Props[EventMessageActor], name = "EventMessageRemoteActor")
  }
 
  def shutdown = {
    system.shutdown()
  }
 
}
 
The configuration file common.conf
akka {
  # Options: ERROR, WARNING, INFO, DEBUG
  loglevel = "DEBUG"
 
  # Log the complete configuration at INFO level when the actor system is started.
  # This is useful when you are uncertain of what configuration is used.
  #log-config-on-start = on
 
  actor {
    serialize-messages = on
    serializers {
      java = "akka.serialization.JavaSerializer"
      proto = "akka.remote.serialization.ProtobufSerializer"
    }
 
    serialization-bindings {
      "java.lang.String" = java
      "com.sillycat.akka.model.EventMessage" = java
    }
  }
}
 
configuration file remotesystem.conf
 
include "common"
akka {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
    netty.tcp {
      hostname = "10.190.191.15"
      port = 2552
    }
  }
}
 
After that, we need to build the assembly jar and place the jar under 
/opt/akka/deploy
 
The binary Akka is downloaded from  http://akka.io/downloads/.
Command to start the remote Akka system 
> bin/akka com.sillycat.akka.server.EventServiceRemoteApp
 
Client System
EventServiceClientApp
package com.sillycat.akka.server
 
import akka.actor._
import akka.routing.{ Broadcast, FromConfig }
import com.sillycat.akka.actor.{ ActorWatcher, EventMessageActor }
import com.sillycat.akka.model.EventMessage
import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.slf4j.Logging
import org.joda.time.DateTime
 
object EventServiceClientApp extends App {
 
  val system = ActorSystem("EventServiceLocalSystem", ConfigFactory.load("clientsystem"))
  val clientActor = system.actorOf(Props[EventMessageActor].withRouter(FromConfig()), "EventMessageClientActor")
 
  private lazy val routerWatcher =
    system.actorOf(Props(new ActorWatcher(clientActor)), name = "EventMessageClientRouterWatcher")
 
  Range(1, 10) foreach { i =>
    def item = EventMessage(1, "request1", "request2", "admin", DateTime.now())
    clientActor ! "fire works."
    clientActor ! item
  }
 
  Thread.sleep(5000)
  clientActor ! Broadcast(PoisonPill)
  system.shutdown()
}
 
The Client Conf, clientsystem.conf
include "common"
 
akka {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }
}
 
akka {
 
  actor.deployment {
    /EventMessageClientActor {
      remote = "akka.tcp://[email protected]:2552/user/EventMessageRemoteActor"
      router = round-robin
      resizer {
        lower-bound = 10
        upper-bound = 100
      }
    }
  }
}
 
Directly run the command in project to testing.
> sbt "run com.sillycat.akka.server.EventServiceClientApp"
 
3. Akka with Spray
Build the actor in app when start the spray HTTP server
system.actorOf(Props[AttributeDBImportActor].withRouter(FromConfig()), name = "AttributeDBImportRouter")
 
Conf
akka {
  # Options: ERROR, WARNING, INFO, DEBUG
  loglevel = "ERROR"
 
  # Log the complete configuration at INFO level when the actor system is started.
  # This is useful when you are uncertain of what configuration is used.
  #log-config-on-start = on
 
  actor.deployment {
    /AttributeDBImportRouter {
      router = round-robin
      resizer {
        lower-bound = 8
        upper-bound = 40
      }
    }
  }
 
In the http service class, select the Actor from the Akka system
implicit val attributeActorRouter = actorRefFactory.actorSelection("/user/AttributeDBImportRouter") //actor name
 
4. Cluster Akka System
todo...
Users/carl/work/akka/akka/akka-samples/akka-sample-cluster-scala/tutorial/index.html
 
 
References:
old blog
 
 
 
 

猜你喜欢

转载自sillycat.iteye.com/blog/2175999