Akka remote源码走读与逻辑梳理

Akka remote源码走读与逻辑梳理

最近事情比较少,就抽了一天时间把akka remote模块的代码粗略走读了下,梳理了以下类结构和数据流。akka remote模块里大量使用了future\ promise,以下为我梳理出的简单类结构图(不清楚的话可以单独打开图片链接):

这里写图片描述

当前akka数据传输默认使用netty来实现,之后会被Artery模块取代。

在actor层级上,akka使用了两个独立的部分transportsendpointManager来分别管理底层连接和上层发送接收,两者均为systemactor的子actor。

transports actor负责管理底层连接、断开,它会为每个远程地址创建一个子actor,并交由子actor去管理该地址的所有连接。我们深入它的其中一种子actor AkkaProtocolManager来看,AkkaProtocolManager会为每个远程连接创建两个子actor,一个用于Inbound一个用于OutBound,这样实现了输入输出的双工操作,互不影响。这两个子actor其实是同一个类ProtocolStateActor,它实现了akka中的FSM有限状态机,其Inbound和OutBound功能是由其构建时的初始状态决定的。

endpointManager actor负责管理发送接收,是基于transports所建立起来的链路进行的,因此它可以专注于发送接收而不用过多关注链路相关问题。endpointManager会为每个连接创建一个EndpointWriter actor用来向远程发送消息,并且EndpointWriter 也会创建EndpointReader actor用来接收该链路上收到的消息。EndpointWriterEndpointReader也保证了上层传输中的全双工消息传递。

remote模块中传输的核心是被AkkaProtocolTransport包裹在内的NettyTransport。它的发送接收依赖inboundBootstrap变量和outboundBootstrap方法,inboundBootstrap定义如下:

private val inboundBootstrap: Bootstrap =           settings.TransportMode match {
case Tcp ⇒ setupBootstrap(new ServerBootstrap(serverChannelFactory), serverPipelineFactory)
case Udp ⇒ setupBootstrap(new ConnectionlessBootstrap(serverChannelFactory), serverPipelineFactory)
}

inboundBootstrap是一个不可变成员变量,def listen: Future[(Address, Promise[AssociationEventListener])]
方法会将其初始化,它作为server监听所有发送到该host:port下的信息,该方法会在endpointManager初始化时被调用。

outboundBootstrap是一个方法def outboundBootstrap(remoteAddress: Address): ClientBootstrap,它接受一个地址,并创建一个链接到这个地址的Channel,它会被方法def associate(remoteAddress: Address): Future[AssociationHandle]调用,即其他模块向该模块请求链接到一个远程地址remoteAddress: Address时,它会返回一个Future[AssociationHandle]

posted @ 2018-01-06 11:27  海角Q  阅读(214)  评论(0编辑  收藏  举报