问题描述
从akka实战数据上看到demo代码搭建,如下: 服务器端:
class AkkademyDb extends Actor{
val map = new mutable.HashMap[String, Any]()
override def receive: Receive = {
case SetRequest(key, value) =>
println("set: key="+key+",value="+value)
map.put(key, value)
sender() ! Status.Success
case GetRequest(key) =>
println("get: key="+key)
val option = map.get(key)
option match {
case Some(x) => sender() ! x
case None => sender() ! Status.Failure(new KeyNotFoundException(key))
}
case o => Status.Failure(new ClassNotFoundException())
}
}
object Main extends App{
ConfigFactory.load("server")
implicit val system = ActorSystem("akkademy",ConfigFactory.load("server"))
system.actorOf(Props(classOf[AkkademyDb]),"akkademy-db")
}
服务器端配置:
akka{
actor{
provider="akka.remote.RemoteActorRefProvider"
}
remote{
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp{
hostname = "127.0.0.1"
port = 8089
}
}
}
启动后显示监听端口与配置文件中设置的端口不一致
INFO akka.remote.artery.tcp.ArteryTcpTransport - Remoting started with transport [Artery tcp]; listening on address [akka://akkademy@192.168.30.119:25520] with UID [4751388696144811708]
分析问题如下
怀疑配置项不对,导致程序使用了默认监听端口
需要分析源码,找到实现类读的配置项信息
将配置信息设置为正确的配置项
问题解决
从网上查找资料,找akka remote源码分析,发现一段话:
在ActorSystem初始化时,调用了RemoteActorRefProvider的init函数,init创建了Remoting这个RemoteTransport,并调用了start,而RemoteTransport作用是什么呢?
参
RemoteTransport源码
//是抽象类
private[akka] abstract class RemoteTransport(val system: ExtendedActorSystem, val provider: RemoteActorRefProvider) {
/**
* Shuts down the remoting
*/
def shutdown(): Future[Done]
//找到两个实现类
private[remote] abstract class ArteryTransport
private[remote] class Remoting
//分别在两个实现类start方法上打断点,实际运行是ArteryTransport实现
查看官网文档,找到ArteryTransport使用配置文件格式
akka {
actor {
provider = remote
}
remote {
artery {
enabled = on
canonical.hostname = "127.0.0.1"
canonical.port = 25520
}
}
}
修改配置文件内容之后
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
netty.tcp {
hostname = "127.0.0.1"
port = 2554
}
artery {
enabled = on
canonical.hostname = "127.0.0.1"
canonical.port = 25521
}
}
}
akka.actor.allow-java-serialization=on
启动服务端,监听端口改变
INFO akka.remote.artery.tcp.ArteryTcpTransport - Remoting started with transport [Artery tcp]; listening on address [akka://akkademy@127.0.0.1:25521] with UID [-4923684430470272955]
启动客户端报协议不对,是因为书里指定的协议不对,修改如下:
val remotedDb = system.actorSelection(s"akka。tcp://akkademy@$remoteAddress/user/akkademy-db")
修改为:
val remotedDb = system.actorSelection(s"akka://akkademy@$remoteAddress/user/akkademy-db")
程序还报序列化有问题
需要将作为消息的样例类实现Serializable
case class SetRequest(key: String, value: Any) extends Serializable
在配置中打开java 序列化开关
akka.actor.allow-java-serialization=on
到此demo调试成功
参考链接: https://www.cnblogs.com/gabry/p/9389558.html
|