Akka之消息路由

Akka:基于Actor的并发解决方案 Actor模型 在面向对象编程中,一个对象可以访问或修改另一个对象的值,在高并发情况下,由于机器性能的瓶颈,当有多个对象对同一竞争资源进行操作时,可能会出现数据错误的问题(即实际读取的数据不是预期数据,而是前面阶段到这一阶段未修改完成的数据)。Actor模型对此进行了修改,它不是直接对对象进行操作,而是通过消息传递的方式与外界进行交互。如图所示: Actor一次只接收处理一个消息,未处理消息会被放入队列等待处理。 Actor有几个重要概念: Actor:处理消息并修改内部状态的工作节点。 消息:用于在多个 阅读详情

Akka提供了非常灵活的消息发送机制。有时候我们使用一组Actor来提供服务,这一组Actor中所有的Actor都是对等的,也就是说你可以找任何一个Actor来为你服务。这种情况下,如何才能快速有效地找到合适的Actor呢?或者说如何调度这些消息,才可以使负载更为均衡地分配在这一组Actor中呢?为了解决这个问题,Akka使用一个路由器组件(Router)来封装消息的调度。系统提供了几种实用的消息路由策略,比如,轮询选择Actor进行消息发送,随机消息发送,将消息发送给最为空闲的Actor,甚至是在组内广播消息。

实例

package com.bzb.java8.akka;

import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;

/**
 * @author bzb
 * @Description: 当前示例中的唯一一个Actor
 * @date 2018/9/14 14:16
 */
public class MyWorker extends UntypedActor {

    private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);

    public static enum Msg {
        WORKING, DONE, CLOSE;
    }

    @Override
    public void onReceive(Object msg) throws Exception {
        if (msg == Msg.WORKING) {
            System.out.println("I am working");
        }
        if (msg == Msg.DONE) {
            System.out.println("Stop working");
        }
        if (msg == Msg.CLOSE) {
            System.out.println("I will shutdow");

            getSender().tell(Msg.CLOSE, getSelf());

            // 收到CLOSE消息时,关闭自己,结束运行。
            getContext().stop(getSelf());
        } else {
            unhandled(msg);
        }
    }
}
package com.bzb.java8.akka;

import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.Terminated;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.routing.ActorRefRoutee;
import akka.routing.RoundRobinRoutingLogic;
import akka.routing.Routee;
import akka.routing.Router;

import java.util.ArrayList;
import java.util.List;

/**
 * @author bzb
 * @Description: 监视者,如同劳动监工一样,一旦被监视者因为停止工作,则监视者就会收到一条消息
 * @date 2018/9/14 14:27
 */
public class WatchActor extends UntypedActor {

    private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);

    // 定义路由器组件Router
    public Router router;

    {
        List<Routee> routees = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            ActorRef worker = getContext().actorOf(Props.create(MyWorker.class), "worker-" + i);
            getContext().watch(worker);
            routees.add(new ActorRefRoutee(worker));
        }

        // 构造Router时,需要指定路由策略和一组被路由的Actor(Routee)。这里使用了RoundRobinRoutingLogin,也就是对所有的Routee轮询发送消息。
        /**
         * RoundRobinRoutingLogic: 轮询
         * BroadcastRoutingLogic: 广播
         * RandomRoutingLogic: 随机
         * SmallestMailboxRoutingLogic: 空闲
         */
        router = new Router(new RoundRobinRoutingLogic(), routees);
    }

    @Override
    public void onReceive(Object msg) throws Exception {
        if (msg instanceof MyWorker.Msg) {
            // 当需要投递消息给这5个worker时,只需要将消息投递给这个Router即可。
            // Router给根据给定的路由策略进行消息投递。
            router.route(msg, getSender());
        } else if (msg instanceof Terminated) { // 终止消息

            // 当一个worker停止工作时,可以简单的将其从工作组中移除
            router = router.removeRoutee(((Terminated) msg).actor());

            // 打印终止的Actor路径和剩余工作组的大小
            System.out.println(((Terminated) msg).actor().path() + " is closed, routees = " + router.routees().size());

            // 如果系统中没有可以的Actor,就会直接关闭系统
            if (router.routees().size() == 0) {
                System.out.println("Closed Systme");
                RouteMain.flag.send(false);
                getContext().system().shutdown();
            }
         } else {
            unhandled(msg);
        }
    }
}
package com.bzb.java8.akka;


import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.agent.Agent;
import akka.dispatch.ExecutionContexts;
import com.typesafe.config.ConfigFactory;
import scala.concurrent.ExecutionContext;

/**
 * @author bzb
 * @Description:
 * @date 2018/9/14 17:42
 */
public class RouteMain {

    public static Agent<Boolean> flag = Agent.create(true, ExecutionContexts.global());

    public static void main(String[] args) throws InterruptedException {
        ActorSystem system = ActorSystem.create("route", ConfigFactory.load("samplehello.conf"));

        ActorRef watcher = system.actorOf(Props.create(WatchActor.class), "watcher");

        int i = 1;

        // 不停发送消息,知道flag为false,即路由绑定的工作组中的Actor为0
        while (flag.get()) {
            watcher.tell(MyWorker.Msg.WORKING, ActorRef.noSender());
            if (i % 10 == 0) {
                watcher.tell(MyWorker.Msg.CLOSE, ActorRef.noSender()); // 每10次发送一条关闭消息
            }
            i++;
            Thread.sleep(100);
        }
    }
}

参考资源

<实战java高并发程序设计>

akka基础 [TOC] ps:本文主要参考《akka入门与实践》 学习akka之前最好先了解一下reactive架构,actor模型和erlang语言的设计思想 《大数据时代的软件架构范式:Reactive架构及Akka实践》 《面向软件错误构建可靠的分布式系统》 基本概念 akka:基于actor并发模型的分布式工具集,用于协调远程计算资源来进行一些工作。 actor:类似于进程或者线程的... 阅读详情

相关推荐

51、Akka与Camel集成开发指南

本文详细介绍了Akka与Camel的集成开发方法,涵盖消费者与生产者参与者的消息交互、CamelService的启动与自定义配置、Actor组件在Camel路由中的应用,以及实际集成示例和常见问题解决方案。通过编程式和声明式方式配置Camel环境,结合in-out与in-only消息模式,实现高效异步通信。文章还提供了完整的代码示例与流程图,帮助开发者构建基于Akka和Camel的企业级集成系统。

peace的博客 67

akka入门系列-5. 路由消息

5. 路由消息 之前的例子中我们创建和使用的都是单个actor,而一个actor同时只能处理一条消息,这并没有发挥出akka并行计算的优势,我们希望能并行地去处理消息,就像kafka的consumer那样。这就需要使用到akka中的路由了。 路由,和常规理解的一样,当消息到达后,可以按一定的策略,把消息分给路由之后的actor处理。在akka中有2类路由,pool路由和group路由。 pool路由:从名字看,一堆actor都在一个池子里。 group路由:从名字看,一堆actor都属于一个组。 那2个

xlchen123456的博客 1291

Wine7.22实战:如何在Ubuntu上完美运行通达信和微信(附字体配置技巧)

本文详细介绍了如何在Ubuntu系统上使用Wine7.22版本,完美运行通达信和微信这两款Windows专属软件。通过选择稳定的Wine7.22版本、利用现成的兼容容器,并重点解决了中文字体渲染的核心难题,提供了从环境搭建、字体配置到软件安装调优的一站式实战指南,帮助用户在Linux环境下无缝使用关键金融与通讯工具。

weixin_29280657的博客 549

3、Akka传递消息

1 消息传递 Akka 有 4 种核心的 Actor 消息模式: tell 、ask 、forward 和 pipe。 Ask:向 Actor 发送一条消息,返回一个 Future。当 Actor 返回响应时,会返回 Future。不会向消息发送者的邮箱返回任何消息。 Tell:向 Actor 发送一条消息。所有发送至 sender()的响应都会返回给发送消息的 Actor。 Forward:将接收到的消息再发送给另一个 Actor。所有发送至 sender() 的响应都会返回给原始消息的发送者。 Pip

数据工匠记 4972

京东豆自动领取脚本配置教程

腾讯云/阿里云服务器(Docker环境):全自动跑脚本领京豆(无需本地代理,使用加速源)

AIOT魔法师 859

FPGA/IC 秋招笔试/面试题总结(目录)

FPGA/IC 秋招笔试/面试题总结-目录介绍 文章目录FPGA/IC 秋招笔试/面试题总结-目录介绍一、FPGA内部资源1. 什么是FPGA2.FPGA内部资源二、同步时钟、同步/异步电路1.同步时钟2.同步/异步电路三、同步复位/异步复位1.同步复位2. 异步复位3. 异步复位同步释放四、同步FIFO/异步FIFO1.同步FIFO2.异步FIFO五、FIFO最小深度计算1.FIFO最小深度2.示例分析六、逻辑电平1.TTL电平标准2.LVTTL电平标准3.CMOS电平标准4.LVCOMS电平标准5.RS

Crazzy_M的博客 2万+

推荐开源项目:Akka SSE —— 轻量级的服务器推送利器

推荐开源项目:Akka SSE —— 轻量级的服务器推送利器 在现代Web应用中,实时数据更新变得日益重要,而Akka SSE正是解决这一需求的一把钥匙。虽然自Akka HTTP 10.0.8版本起,其已内建了对Server-Sent Events的支持,但让我们回顾并探讨这个曾经独立的项目——Akka SSE,它如何为我们的应用程序带来高效且简单的一向通信解决方案。 项目介绍 Akka SSE是...

gitblog_00027的博客 521

PyQt5简介和安装

在initUI方法中,设置了窗口的标题和大小,并创建了一个按钮。PyQt5是一个功能强大的Python界面开发框架,可以轻松创建跨平台的图形用户界面应用程序。本文介绍了PyQt5的简介和安装方法,并提供了一个简单的示例应用程序来演示PyQt5的基本用法。PyQt5是一个功能强大的Python界面开发框架,它提供了丰富的工具和组件,用于创建跨平台的图形用户界面(GUI)应用程序。信号是控件发出的事件,槽是与之关联的处理函数。接下来,我们将编写一个简单的PyQt5应用程序,以演示PyQt5的基本用法。

XdKwargs的博客 222

Akka在运行时对消息进行实时切换处理的特性: become和unbecome

Akka支持在运行时对角色消息循环 (例如它的的实现)进行实时替换: 在角色中调用getContext.become 方法。 热替换的代码被存在一个栈中,可以被pushed(replacing 或 adding 在顶部)和popped。 become一个特别好的例子是用它来实现一个有限状态机。 使用Become/Unbecome特性还可以很方便的实现状态转换机。 实例:Actor运行

DataFlow范式 1452

开源推荐:5个最实用的AIGC风格迁移项目

随着人工智能技术的飞速发展,AIGC(人工智能生成内容)领域取得了显著的成果。风格迁移作为AIGC中的一个重要分支,旨在将一种图像的风格应用到另一种图像上,创造出具有独特艺术效果的新图像。本文的目的是为读者推荐5个最实用的AIGC风格迁移开源项目,详细介绍这些项目的技术原理、使用方法和应用场景,帮助读者在实际项目中选择合适的工具进行风格迁移。文章的范围涵盖了这些项目的核心概念、算法原理、数学模型、项目实战以及相关的学习资源和未来发展趋势等方面。

AI 原生应用开发的博客 1704

13、控制依赖与切片的新基础及递归While程序的摘要

本文探讨了控制依赖和程序切片的新研究进展,并提出了一种用于递归While程序的广义过程摘要概念和验证框架。文章介绍了控制依赖的新定义及其优势,程序切片的相关工作,以及递归While程序的过程摘要在完全正确性和终止性证明中的应用。通过阶乘和插入排序程序的示例分析,展示了过程摘要的有效性。未来的研究将聚焦于并发程序的依赖计算、依赖关系的语义连接以及时间属性的保留。

kotlin6android的博客 85

为什么spark 1.6之后使用Netty来替代Akka通信库?

Akka的底层是使用Netty,尽管Akka能简化消息通信的使用,但使用Akka要求message发送端和接收端有相同的版本(例如spark streaming的receiver接收上游消息要求上游的actor有相同的Akka版本)由于spark对Akka的使用主要限于RPC和单线程event loop,所以为了避免Akka造成的版本问题,给用户的应用更大灵活性,决定使用更通用的RPC实现,也就是

简单就好 3798

【C2000系列DSP的Bootloader详解】实现过程、流程图与示例代码

C2000 Bootloader 的核心逻辑可概括为 “初始化→选模式→加载程序→校验→跳转” 五步。对于小白来说,无需纠结底层寄存器配置(驱动库已封装),重点理解 “启动流程” 和 “数据传输 + 校验” 的核心思想即可。 通过本文的流程图和示例代码,相信你已经掌握了 C2000 Bootloader 的核心原理。实际开发中,可基于 TI 提供的 Bootloader 示例(C2000Ware 中自带)进行修改,快速适配自己的硬件和应用场景。

昔时扬尘处 371

akka实战项目4--消息路由

package akka; import akka.actor.*; import akka.routing.*; import com.typesafe.config.ConfigFactory; import javax.naming.Context; import java.util.LinkedList; import java.util.List; public class rou...

zisuu的博客 306

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Akka消息收件箱以及消息路由、内置状态转换

消息收件箱(Inbox) Akka框架为我们准备了一个名叫"收件箱"的组件,使用它可以很方便的对Actor进行消息发送和接收,大大方便了应用程序与Actor之间的交互。 public class MyWorker extends UntypedAbstractActor { private final LoggingAdapter loggingAdapter= Logging.getLogger(getContext().system(),this); public static enu

qq_56224861的博客 324

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Akka路由机制详解:5种路由策略提升系统消息分发效率

Akka作为一款强大的分布式计算框架,其路由机制是实现高效消息分发的核心组件。本文将深入解析Akka中的5种路由策略,帮助开发者理解如何通过合理配置路由提升系统性能,实现消息的智能分发与负载均衡。 ## 一、什么是Akka路由机制? 在Akka Actor模型中,路由(Routing)是指将消息从一个源Actor转发到多个目标Actor的过程。通过路由机制,可以实现消息的负载均衡、广播分发和智

gitblog_00523的博客 915

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

消息路由

        Akka具有分布式、集群、微服务等特点,可以快速构建高可用、高性能的分布式应用。多个Actor之间消息传递,可以使用tell、ask、forward等简单方式,但是当一组Actor需要进行有规律的消息传递时,就显得稍微复杂。Akka路由组件,就是为了解决我们复杂的消息传递,例如广播、轮询、随机等,有两种实现方式:配置和代码创建。      什么是路由         路由就是一...

二月初二 2487

Akka路由_RoundRobinRoutingLogic

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34049032的博客 225

《Java高并发程序设计》学习 --7.7 消息路由

Akka提供了非常灵活的消息发送机制。有时候,会使用一组Actor而不是一个Actor来提供一项服务。这一组Actor中所有的Actor都是对等的,也就是说可以找任何一个Actor来服务。这种情况下,如何才能快速有效地找到合适的Actor?或者说如何调度这些消息,才可以使负载更为均衡地分配在这一组Actor中。 为了解决这个问题,Akka使用一个路由器组件(Router)来封装消息的调度。系统提

sunhaoning的专栏 1244

Akka-路由策略

热爱湘鄂的妹子,喜欢江浙的妹子

文天大人 1427

Akka路由_BroadcastRoutingLogic

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33811961的博客 266

Akka实践一些总结

最近在一些服务中使用了akka,主要用来做异步解耦和本地消息分发(路由),这里简单总结一下用法. 与spring集成 网上有不少集成的例子,要使用到spring的扩展. 我这边没有这样处理,而是简单把ActorSystem创建的actor的过程放在了spring configuration里,把ActorRef作为bean,毕竟actor本身不能为单例但是ref可以. actor要使用一些bean...

weixin_30517001的博客 170

Scala Actor并发编程实战:基于Akka构建高并发消息驱动系统

Actor是Actor模型中的基本计算单元,可以将其理解为一个"有信箱的独立个体":fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;Actor BActor A发送消息逐个处理更新发送消息内部状态信箱行为逻辑内部状态信箱行为逻辑外部发送者// 1. 定义消息协议(推荐使用密封特质)// 2. 定义Actor的行为工厂。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 2302

Akka in Action完整指南:10个核心概念带你深入理解Akka框架

想要构建高并发、高可用的分布式系统吗?🤔 Akka框架正是你需要的终极解决方案!Akka是一个基于Actor模型的并发框架,专为构建响应式、弹性、可伸缩的系统而设计。无论你是Scala开发者还是Java程序员,掌握Akka框架都能让你的应用程序性能大幅提升。本文将为你揭秘Akka框架的10个核心概念,带你从入门到精通! ## 🚀 什么是Akka框架? Akka是一个开源的工具包和运行时,用

gitblog_00243的博客 454

Akka Cluster Sharding

Akka Cluster Sharding DeepLearningZ关注 0.12018.03.22 10:57*字数 7911阅读 449评论 1喜欢 2 Sharding分片这个名词从P2P时代开始早已有之,对于分布式存储意味如何决定数据存到哪台节点机去、对于分布式计算意味如何决定计算分布到哪台节点机上,Akka中的分片兼而有之,用于将实体...

weixin_30312563的博客 485
上一篇: Akka之收件箱(Inbox)
下一篇: Actor的内置状态转换
菜鸟=大神
博客等级 码龄11年 5粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值