Akka2使用探索1(Remoting)

akka从1.2升级到现在的2.0.2后有了很大的改变。现在摸索一下如何使用。

Remoting可以方便地用于服务器之间通信。akka1.2可以使用clientActor.sendRequestReply将消息发送到服务器端,并且同步获取服务器端的返回消息。但是akka2已经不能这么用了,akka2使用tell方法给另一个Actor发消息。

tell有两个重载方法:

/**
* Sends the specified message to the sender, i.e. fire-and-forget semantics.<p/>
* <pre>
* actor.tell(message);
* </pre>
*/
final def tell(msg: Any): Unit = this.!(msg)(null: ActorRef)

只发送,不管其他,也不接收相应。actor.tell(msg)----给actor发送msg消息

/**
* Java API. <p/>
* Sends the specified message to the sender, i.e. fire-and-forget
* semantics, including the sender reference if possible (not supported on
* all senders).<p/>
* <pre>
* actor.tell(message, context);
* </pre>
*/
final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender)

只发送消息,并告诉对方你可以给我指定的sender回复消息。actor.tell(msg,sender)----给actor发送msg消息,actor处理时可以给sender回复消息。

所以akka2中actor是对等的。有消息来回发送的akka应用最好部署在对等互通的网络环境中。如果一个应用部署在内网,一个部署在外网,那么内网的actor给外网发消息没问题,但是外网的actor想给内网的actor回复消息就不行了。

另外,因为remoting的host最好指定成具体的ip或域名或hostname,不要指定成”0.0.0.0”,这样才方便定位远程actor。host和port在配置文件中指定。

注意区别Deploy,Deploy是指将本地Actor发布到远程akka Server上,withDeploy的参数RemoteScope指的是远程Server的ip、端口、sysName。并不是启动本地Server。

serverActor = system.actorOf(new Props(Server.class).withDeploy(new Deploy(new RemoteScope(new Address("akka", Server.AkkaSystemName, "127.0.0.1", 8888);))), "simple");

客户端可以直接用serverActor发消息,也可以通过路径查找,用actorFor(akka://${远程sysName}@${远程akka服务地址}/remote/${被发布的sysName}@${被发布的akka的地址(ip、端口)}/user/${actorOf第二个参数指定的路径})发消息。注意消息是在服务端收到。

现在来看看具体的例子:

首先引用typesafe的仓库:

<repository>
<id>typesafe-releases</id>
<url>http://repo.typesafe.com/typesafe/releases</url>
</repository>

加入依赖包:<akka.version>2.0.2</akka.version>

<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-remote</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-kernel</artifactId>
<version>${akka.version}</version>
</dependency>

首先定义ServerActor:

import akka.remote.RemoteScope
import akka.actor.*
import com.typesafe.config.ConfigFactory
class Server extends UntypedActor {
static final String AkkaSystemName = "xw"
LoggingAdapter log = Logging.getLogger(getContext().system(), this);

@Override
void onReceive(Object message) {
log.debug("server收到消息----${message}----self:${getSelf()},sender:${getSender()}")
getSender().tell(message)//给客户端actor发送消息
}

}

然后定义服务端应用,来启动ServerActor

import akka.kernel.Bootable
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.ActorRef
import akka.actor.Address
import akka.actor.Deploy
import akka.remote.RemoteScope
import com.typesafe.config.ConfigFactory

class ServerApp implements Bootable {
ActorSystem system
ActorRef serverActor

ServerApp() {
system = ActorSystem.create(Server.AkkaSystemName, ConfigFactory.load().getConfig("server"))
Address addr = new Address("akka", Server.AkkaSystemName, "10.68.15.16", 8888);
serverActor = system.actorOf(new Props(Server.class), "server");

// serverActor = system.actorOf(new Props(Server.class).withDeploy(new Deploy(new RemoteScope(addr))), "simple");
}

void startup() {

}

void shutdown() {
system.shutdown()
}

}
指定它加载“server”配置。需要在classpath下的application.conf中添加:

server {
akka {
//loglevel = "DEBUG"
actor {

provider = "akka.remote.RemoteActorRefProvider"//这里指定使用RemoteActor

}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
netty {
hostname = "10.68.15.16"//"0.0.0.0"//指定系统绑定的host
port = 8888//指定系统绑定的端口
}
}
}
}
现在只需要new ServerApp()将服务启动即可。

客户端很简单:

ActorSystem.create(Server.AkkaSystemName, ConfigFactory.load().getConfig("client")).actorFor("akka://xw@10.68.15.16:8888/user/server").tell("hello,I'm client")

客户端也需要加载配置文件:

client {
akka {

actor {
provider = "akka.remote.RemoteActorRefProvider"

}

}
}

这里需要注意:

1、必须指定provider为RemoteActorXXX

2、客户端只发不收消息时,ActorSystem的name没有要求。需要收消息时,如果和服务端相同则可能出问题。遇到问题时改下ActorSystem的那么试一下。

经过试验,如果服务端启多个ActorSystem和akka端口是没问题的。akka1.2中同一个进程不能启多个akka端口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值