Akka 2.5.11 路由 Routing

当处理到来的消息流时,我们需要一个actor来引导消息路由到目标actor,从而提高消息的分配效率。在Akka中这个 actor就是Router它所管理的一些目标actor叫做routees

根据不同的情况需要,Akka提供了几种路由策略。当然也可以创建自己的路由及策略。

一个简单的Router

如何使用Router 还有如何管理routees。

Akka提供的路由策略如下:(详细见下文路由的使用)

akka.routing.RoundRobinRoutingLogic   轮询

akka.routing.RandomRoutingLogic    随机

akka.routing.SmallestMailboxRoutingLogic   空闲

akka.routing.BroadcastRoutingLogic   广播

akka.routing.ScatterGatherFirstCompletedRoutingLogic   分散聚集 

akka.routing.TailChoppingRoutingLogic      尾部断续 

akka.routing.ConsistentHashingRoutingLogic    一致性哈希


创建Router Actor

创建router actor 有两种方式:

            1. Pool(池)——routees都是router 的子actor,如果routees终止,router将把它们移除

            2.Group(群组)——routees都创建在router的外部,router通过使用actor来选择将消息发送到指定路径,但不监管routees是否终止。

Router actor 向 routees 发送消息,与向普通actor发送消息一样通过其ActorRef。Router actor 不会改变消息的发送人,routees 回复消息时发送回原始发件人,而不是Router actor。

Pool(池)

可以通过配置并使用代码在配置中获取的方法来实现  (例如创建一个轮询Router向5个routees发送消息)

也可以只使用编程的方式来实现

远程部署Router

既可以创建本地actor来作为Router,也可以命令Router在任一远程主机上部署子actor。

需要将路由配置放在RemoteRouterConfig下,在远程部署的路径类中要添加akka-remote模块

发送者

默认情况下,当一个routee发送消息,它隐式地设置自己为发送者。

sender() ! x // replies will go to this actor

但是通常将routee的父Router作为发送者更有用处。这样可以将routees的信息隐藏起来。

sender().tell("reply", context.parent) // replies will go back to parent

sender().!("reply")(context.parent) // alternative syntax (beware of the parens!)

监管

在Pool中,routees是Router 的子actor,所以Router也负责监管。

可以使用Pool 的supervisorStrategy属性来配置监管策略。如果没有提供配置,默认策略是“always escalate”(总是上升)。就是错误都会上传到Router的监管者进行处理。但是Router的监管者会认为是Router本身发生错误,因此会重启Router,所有的routees也将被重启,这样导致监管的效率变低。所以我们要指定监管策略。

Group(群组)

有时我们需要单独的创建routees,然后提供一个Router来供其使用。可以通过将routees的路径传递给Router的配置,消息将通过ActorSelection来发送到这些路径。

同样Group像Pool一样有两种方法创建。(为三个routee actor创建Router)

编程方式实现:


路由的使用

(具体配置见Routing

1.RoundRobinPool RoundRobinGroup

Router对routees使用轮询机制

2.RandomPool RandomGroup

Router随机选择routees发送消息

3.BalancingPool

尝试从繁忙的routee重新分配任务到空闲routee,所有的routee共享一个mailbox

4.SmallestMailboxPool

Router创建的所有routees中谁邮箱中的消息最少发给谁

5.BroadcastPool BroadcastGroup

广播的路由器将接收到的消息转发到它所有的routee。

6.ScatterGatherFirstCompletedPool 和 ScatterGatherFirstCompletedGroup

将消息发送给所有的routees,然后等待到收到第一个回复,将结果发送回原始发送者。其他的回复将被丢弃

7.TailChoppingPool 和 TailChoppingGroup

将首先发送消息到一个随机挑取的routee,短暂的延迟后发给第二个routee(从剩余的routee中随机挑选),以此类推。它等待第一个答复,并将它转回给原始发送者。其他答复将被丢弃。

此Router的目标是通过查询到多个routee来减少延迟,假设其他的actor可能比第一个actor更快响应。

8.ConsistentHashingPool ConsistentHashingGroup

对消息使用一致性哈希(consistent hashing)选择routee

有三种方式定义哪些数据作为一致性哈希键

·    你可以定义路由的hashMapping,将传入的消息映射到它们一致哈希键。这使决策对发送者透明。

·    这些消息可能会实现akka.routing.ConsistentHashingRouter.ConsistentHashable。键是消息的一部分,并很方便地与消息定义一起定义。

·    消息可以被包装在一个akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope中,来定义哪些数据可以用来做一致性哈希。发送者知道要使用的键。


特殊处理的消息

Broadcast消息

用于向Router所有的routee发送一条消息,不管该Router通常是如何路由消息的。

PoisonPill消息

无论哪个actor收到PosionPill消息都会被停止。但是对于PoisonPill消息Router不会将其传给routees。但仍然能影响到routees,因为Router停止时它的子actor也会停止,就可能会造成消息未处理。因此我们可以将PoisonPill包装到Broadcast消息中。这样Router所管理的所有routees将会处理完消息后再处理PoisonPill并停止。

Kill消息

当Kill消息被发送到Router,Router将内部处理该消息,并且不会将它发送到其routee。Router将抛出ActorKilledException并失败,然后Router根据监管的策略,被恢复、重启或终止。

Router的子routee也将被暂停,也受Router监管的影响,但是独立在Router外部创建的routee将不会被影响。

Managagement消息

发送akka.routing.GetRoutees到一个Router actor,使其回送一个包含当前使用routee的akka.routing.Routees消息。

发送akka.routing.AddRoutee到一个Router actor会将那个routee添加到其routee集合中。

发送akka.routing.RemoveRoutee到一个Router actor将从其routee集合删除该routee。

发送akka.routing.AdjustPoolSize到一个Pool (Router actor)将从其routee集合中添加或删除该数目的routee。


动态改变大小的池

大多数Pool的routees数量是固定的,但是可以制定调整策略来动态改变routees的数量

两种调整方式(resizer): 默认的ResizerOptimalSizeExploringResizer

Resizer是根据压力的大小来调整的,繁忙的routees 占总数的百分比高于或低于某个阈值就会进行调整

OptimalSizeExploringResizer :将池的大小调整为最佳大小,来提供最多的消息吞吐量。

它跟踪每个Pool 的消息吞吐量来定期执行以下三个调整操作。

    ·    如果在一段时间内没有看到所有routees被充分利用的,就缩小规模。

    ·    随机探索附近的池大小,以尝试收集吞吐量指标。

    ·    对附近的池大小进行优化(比其他任何附近池的)吞吐量指标更好。


Akka中的路由是如何设计的

从表面看,Router就像普通的actor,但是它们实际实现是不同的。路由器在收消息和快速发消息给routee被设计的极度优化。

Router可以通过优化原有消息处理pipeline来支持多线程,从而达到更高的吞吐量。通过将路由策略直接嵌入到其ActorRef 发送到路由器ActorRef 的消息可以直接被路由到routees,直接跳过了单线程的Router actor。


自定义Router

在你创建自己的Router之前,要考虑到普通的actor性能不如Router actor高,因此你的程序可以接受较低的消息吞吐量。

假设你想获得最大的性能,请参考


配置调度器

为子Pool创建调度器将从Props中取调度器中有描述

为了可以很容易地定义池中routee的调度器,你可以在配置的部署一节中定义内联调度器。

启用一个池专用调度器,你唯一需要做的

Router的“头”,不能总在相同的调度器上运行,因为它处理各种各样不同类型的消息,因此这个“头”是个特殊的actor,不使用Props验证的调度器。但是在RouterConfig中的 routerDispatcher 是标准Router actor默认调度器,可以在Router 的构造器和工厂方法中配置。 即使是自定义的Router也必须要实现默认调度器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 持久化 当我们在集群系统中,一台机器向另一台机器发送一段数据,负责接收的机器在接收数据前突然宕机,就会造成数据丢失...
    mango_knight阅读 4,497评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Actor系统的实体 在Actor系统中,actor之间具有树形的监管结构,并且actor可以跨多个网络节点进行透...
    JasonDing阅读 3,326评论 2 6
  • 本章描述了Actor如何被识别和定位在于一个分布式Actor系统。这与固有的主管层次一样是Actor系统的核心内容...
    儿哥欠三百首阅读 1,796评论 0 0
  • 笔者这一周终于学会了如何把md文件生成report。虽然起步比其他同学慢了点,但是多试试结果终究会不一样的。 先前...
    嘈杂碎碎念阅读 303评论 0 1