活动介绍

使用AkkaTyped构建响应式应用程序

立即解锁
发布时间: 2025-08-19 00:05:41 订阅数: 9
PDF

Scala 2.13编程实战与进阶

### 使用 Akka Typed 构建响应式应用程序 #### 1. 问题背景与 Actor 监控 在系统运行过程中,可能会出现 Actor 初始化异常,例如 `akka.actor.ActorInitializationException`。当 `Mixer` 出现 `MotorOverheatException` 时,监督者尝试重启该 Actor 四次后放弃并停止了它。由于故障发生在设置块中,该 Actor 既无法接收 `Mix` 命令,也无法接收生命周期事件通知。 此时系统会陷入停滞,因为 `Chef` 仍在等待故障的 `Mixer` 完成工作。为了解决这个问题,我们需要一种机制来通知 `Chef` 哪些 `Mixer` 已终止。Akka Typed 提供了监控机制,具体实现如下: ```scala val mixers = for (i <- 1 to eggs) yield context.spawn(Mixer.controlledMix, s"Mixer_$i") mixers.foreach(mixer => context.watchWith(mixer, BrokenMixer(mixer))) ``` 这里,`context.watchWith` 的第一个参数是要监控的 Actor,第二个参数是消息适配器。`BrokenMixer` 消息的定义和处理如下: ```scala case class BrokenMixer(mixer: ActorRef[Mixer.Mix]) extends Command def mixing(...): Behavior[Command] = Behaviors.receivePartial { case (context, BrokenMixer(m)) => context.log.warning("Broken mixer detected {}", m) context.self ! Collect(Dough(0), m) Behaviors.same } ``` 当检测到子 Actor 终止时,`Chef` 会记录日志并给自己发送一条消息以补偿丢失的工作。 #### 2. Cook、Baker 与相关机制 在准备好面团后,需要 `Cook` 将面团制成生饼干,`Baker` 将生饼干放入烤箱烘烤。`Cook` 的实现较为简单,它只是将面团转换为一定数量的生饼干并发送给管理者。 `Baker` 则更为复杂,它需要一个烤箱。首先,我们使用一个特殊的行为来启动烤箱: ```scala def turnOvenOn: Behavior[Command] = Behaviors.setup { context => val oven = context.spawn(Oven.empty, "Oven") idle(oven) } ``` 然后定义 `idle` 行为,等待工作: ```scala def idle(oven: ActorRef[Oven.Command]): Behavior[Command] = Behaviors.receivePartial { case (context, BakeCookies(rawCookies, manager)) => oven ! Put(rawCookies.count, context.self) Behaviors.withTimers { timers => timers.startSingleTimer(TimerKey, CheckOven, DefaultBakingTime) baking(oven, manager) } } ``` 这里使用了 `withTimers` 行为构造函数,它提供了对 `TimerScheduler` 的访问,我们可以使用它来定义周期性和一次性定时器。 此外,由于烤箱容量有限,`Baker` 需要批量烘烤生饼干,因此需要管理一个生饼干队列。我们使用 `stash` 来实现这一点: ```scala def baking(oven: ActorRef[Oven.Command], manager: ActorRef[Manager.Command]): Behavior[Command] = Behaviors.setup[Command] { context => val buffer = StashBuffer[Command](capacity = 100) Behaviors.receiveMessage { case CheckOven => oven ! Extract(context.self) Behaviors.same case c: TooManyCookies=> buffer.stash(BakeCookies(c.raw, manager)) Behaviors.same case c : BakeCookies => buffer.stash(c) Behaviors.same case CookiesReady(cookies) => manager ! ReceiveReadyCookies(cookies) buffer.unstashAll(context, idle(oven)) } } ``` `stash` 会将当前行为无法处理的消息缓冲起来,并在切换到可以处理这些消息的替代行为之前重新播放它们。 #### 3. 管理者行为组合 在定义了面包店的各个工人后,我们需要一个管理者。在 Akka Typed 中,我们可以通过定义每个状态的原子行为,然后根据需要返回适当的行为来实现管理者的功能: ```scala def waitingForGroceries = receiveMessagePartial[Command] { case ReceiveGroceries(g) => context.log.info("Mixing {}", g) chef ! Chef.Mix(g, context.self) waitingForPastry } def waitingForPastry = receiveMessagePartial[Command] { case ReceivePastry(p) => context.log.info("Forming {}", p) cook ! Cook.FormCookies(p, context.self) waitingForRawCookies } ``` 我们还可以将这些行为组合起来,实现管理者的并行版本: ```scala def manage(chef: ActorRef[Chef.Command], cook: ActorRef[Cook.FormCookies], baker: ActorRef[Baker.Command]): Behavior[Command] = ... def sendBoyShopping = receiveMessagePartial ... def waitingForGroceries = receivePartial[Command] { ... manage(chef, cook, baker) } def waitingForPastry = receiveMessagePartial[Command] { ... manage(chef, cook, baker) } def waitingForRawCookies = receiveMessagePartial[Command] { case ReceiveRawCookies(c) => baker ! Baker.BakeCookies(c, context.self) manage(chef, cook, baker) } def waitingForReadyCookies = receiveMessagePartial[Command] { case ReceiveReadyCookies(c) => context.log.info("Done baking cookies: {}", c) manage(chef, cook, baker) } lookupSeller orElse sendBoyShopping orElse waitingForGroceries orElse waitingForPastry orElse waitingForRawCookies orElse waitingForReadyCookies } ``` 这样,管理者就能够在任何处理状态下处理每个消息。 #### 4. 集群配置 为了让杂货店作为一个单独的 Actor 系统运行,我们可以使用 Akka Typed 的集群功能。首先,需要在 `build.sbt` 中添加以下依赖: ```scala "com.typesafe.akka" %% "akka-cluster-typed" % akkaVersion, ``` 然后在 `application.conf` 中添加以下配置: ``` akka { actor.provider = "cluster" remote { netty.tcp { ```
corwn 最低0.47元/天 解锁专栏
赠100次下载
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

李_涛

知名公司架构师
拥有多年在大型科技公司的工作经验,曾在多个大厂担任技术主管和架构师一职。擅长设计和开发高效稳定的后端系统,熟练掌握多种后端开发语言和框架,包括Java、Python、Spring、Django等。精通关系型数据库和NoSQL数据库的设计和优化,能够有效地处理海量数据和复杂查询。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看

最新推荐

【RedisDesktopManager 2021.0网络问题诊断】:一文搞定连接故障处理

![【RedisDesktopManager 2021.0网络问题诊断】:一文搞定连接故障处理](https://docs.opnsense.org/_images/redis_general.png) # 摘要 RedisDesktopManager 2021.0是一个功能丰富的客户端工具,旨在简化Redis数据库的管理和操作。本文首先概述了RedisDesktopManager的基本概念及其特性,随后介绍了网络基础知识和诊断技术,包括TCP/IP协议栈、常用网络诊断工具以及网络故障类型分析。接着,本文详细阐述了RedisDesktopManager的网络连接机制,包含连接配置、初始化过程

【VoWiFi部署宝典】:H3C优化无线语音通话质量全攻略

![【VoWiFi部署宝典】:H3C优化无线语音通话质量全攻略](https://www.cisco.com/c/dam/en/us/support/docs/wireless/5500-series-wireless-controllers/113682-bdr-limit-guide-00-07.jpeg) # 摘要 随着无线通信技术的发展,VoWiFi技术已经广泛应用于各种通信网络。本文首先概述了VoWiFi技术及其部署的理论基础,分析了无线通信原理、语音编码与压缩技术、以及QoS在网络中的作用。然后,具体探讨了H3C设备在VoWiFi中的应用,包括无线控制器配置、AP与语音终端的联动

【塑性响应理解】:OW-AF模型与复合材料相互作用分析

![【塑性响应理解】:OW-AF模型与复合材料相互作用分析](https://cdn.comsol.com/wordpress/2015/06/yeoh-ogden-uniaxial-test-equibiaxial-test.png) # 摘要 本文系统介绍了塑性响应基础及OW-AF模型的理论与应用。首先概述了塑性理论的基本概念,并对OW-AF模型的构建过程和与传统理论的对比进行了详尽分析。文章着重探讨了该模型在复合材料领域的适用性和实际应用案例,分析了模型参数的确定、塑性流动的模拟及其在特定复合材料中的应用。此外,本文还探讨了OW-AF模型的数值实现与验证,包括数值计算方法的选择、模拟结

Havok与VR_AR的未来:打造沉浸式互动体验的秘籍

# 摘要 本文系统地介绍了Havok引擎及其在虚拟现实(VR)和增强现实(AR)领域的应用。文章首先概述了Havok引擎的核心特性,如物理模拟技术和动画与模拟的集成,并通过VR游戏和AR互动应用的具体实例展示了其在VR_AR环境中的应用。接着,本文探讨了沉浸式体验的理论基础,包括心理学原理和交互技术,并分析了构建沉浸式体验时面临的技术挑战。最后,文章展望了Havok引擎与VR_AR技术的未来,预测了物联网和人工智能与Havok结合的新趋势,以及沉浸式体验的潜在发展方向。 # 关键字 Havok引擎;VR_AR;物理模拟;沉浸式体验;交互技术;跨平台开发 参考资源链接:[深入浅出Havok物

CUDA纹理内存与常量内存:优化特定数据存取的黄金法则

![CUDA纹理内存与常量内存:优化特定数据存取的黄金法则](https://developer-blogs.nvidia.com/wp-content/uploads/2021/04/Nsight-visual-featured.png) # 摘要 本文综述了CUDA内存架构的核心概念和优化技术,深入探讨了纹理内存和常量内存的原理、特性和编程模型。文中分析了纹理内存的内部工作机制,包括缓存机制和映射寻址方式,并讨论了其优势和局限性。同时,文章阐述了常量内存的缓存原理和性能影响,提供了编程指导以优化内存使用。最后,结合实践案例,本文探索了大规模数据处理和高性能计算中的内存优化策略,并分享了内

【FFT在无线通信中的角色】:关键角色与传输效率提升

![【FFT在无线通信中的角色】:关键角色与传输效率提升](https://www.datocms-assets.com/53444/1666012177-fft-harmonic-markers.png?auto=format&w=1024) # 摘要 无线通信技术的发展促进了快速傅里叶变换(FFT)算法的广泛应用。本文首先介绍了无线通信的基础原理和FFT的理论,深入探讨了FFT算法的发展、优化及其在信号处理中的关键作用。随后,文章分析了FFT如何提升无线通信的传输效率,特别是在信号调制、检测以及频谱资源管理方面。此外,本文还讨论了FFT在实际应用中的技术挑战及其解决方案,并提供了优化策略

TSI578与PCIe技术比较:揭示交换模块设计的未来趋势

# 摘要 TSI578与PCIe技术在高速数据传输领域扮演重要角色。本文首先概述了PCIe技术的发展历程、架构和性能特点。随后,详细介绍了TSI578技术的原理、应用场景及其性能优势,并与传统PCIe技术进行了比较。文章进一步探讨了交换模块设计面临的挑战及其创新策略,特别是在TSI578技术的应用下。最后,通过实践案例分析了PCIe技术在不同行业的应用,并对TSI578与PCIe技术的未来发展方向进行了展望。 # 关键字 TSI578;PCIe技术;数据传输;性能分析;交换模块设计;技术实践应用 参考资源链接:[TSI578串行RapidIO交换模块:设计与关键技术](https://we

【Visio图标绘制全攻略】:从入门到精通CloudEngine 12800的绘制技巧

![【Visio图标绘制全攻略】:从入门到精通CloudEngine 12800的绘制技巧](https://viso.ai/wp-content/uploads/2022/02/viso-suite-build-ai-vision-1060x597.png) # 摘要 本文系统性地介绍了Visio图标绘制的理论基础和实践技巧,涵盖从基础操作到高级功能的各个方面。文中首先阐释了Visio在图标绘制中的理论基础和界面布局,接着详细讲解了图形对象的操作、图层管理以及页面设置。第三章和第四章分别探讨了图标绘制的技巧与实践,以及如何将图标与特定设备如CloudEngine 12800结合应用。第五章

dnSpy-ne实用技巧大公开:快速解决反编译难题

# 摘要 本文旨在提供dnSpy工具的综合指南,从基础使用到高级应用,再到实际案例分析。dnSpy是一个流行的.NET反编译器和调试工具,能够加载、编辑和反编译.NET程序集。本文首先概述dnSpy的基本功能,然后详细介绍其用户界面布局、面板配置以及.NET架构的理解。接着,探讨了dnSpy的高级功能,如代码编辑、调试、字节码操作、代码重构和优化。此外,本文还探讨了dnSpy在逆向工程中的应用,包括漏洞发现和修复、第三方库管理,以及逆向工程中的法律与伦理问题。最后,通过实战案例分析,分享了dnSpy的使用技巧、问题解决方法和学习心得,旨在帮助读者提高使用dnSpy的效率和技能。 # 关键字

数控机床精度问题诊断与解决:专家经验分享与实战技巧

![数控机床位置精度的检测及补偿.zip](https://wx2.sinaimg.cn/large/9b30df69ly1hocg6k87d4j210t0dwacr.jpg) # 摘要 数控机床精度问题是影响加工质量和机床性能的关键因素,本文综合分析了数控机床精度问题的定义、分类、成因及影响。在理论基础部分,探讨了设计、制造、使用等多方面因素对数控机床精度造成的影响,并对加工质量和机床寿命的影响进行了评估。针对诊断方法,文章比较了传统与现代诊断技术,并强调了维护管理中诊断的重要性。同时,提出了包括机械精度调整、数控系统优化在内的解决策略,以及精度保持和提高的措施。文章最后通过实战案例分析,