内容简介
   对于想要学习Akka的Java 和 Scala 开发者们,有很多技术资源可供参考,但是如要想知道如何去应用这些技术就需要不同的思维方式了。为了帮助你正确地使用Akka,这本实用的实践指南提供了若干高级的设计模式,还包括了如何以及何时应用那些模式去解决在大型分布式系统中遇到的实际问题的一些案例。
     作者简介
   Michael Nash是Lightbend 的总监。过去30 多年间,他为各种规模的公司及客户设计、开发、发布了很多软件项目。作为项目管理和架构实践的软件工艺倡导者,他是“安全堆栈”*早的实践者之一,在Scala、Akka 和Spray 方面有五年以上的工作经验。他大部分业余时间致力于“安全响应式平台”的相关工作,在会议中发表主题演讲,以及在软件相关领域撰写书籍。Wade Waldron是Lightbend 的高级顾问。他现在针对Lightbend 响应式平台提供培训和咨询服务。在Lightbend 之外,Wade 在过去9 年中一直在建立坚实的软件和游戏,重点是设计测试驱动、设计域驱动、设计面向服务的架构、设计事件驱动架构以及敏捷开发。
高中开始接触编程,大学期间参加各种比赛,获得许多奖项。也因为比赛,大三就获得了微软的实习机会,学习到很多学校学不到的东西。也因此开始一有时间就会去各种公司实习,了解不同公司的企业文化。比较典型的程序员,热爱编程,喜欢研究算法,也喜欢学习各种好玩的开源项目。由于自身工作经历,对于分布式系统的实践经验有丰富的经验。
     目录
   目录  
前言 .......................................................................................... xvii  
第1 章 Actor 模型 ........................................................................1  
现实是最终一致的 .................................................................................................1  
解构Actor 模型 .....................................................................................................3  
所有的计算都在一个actor 中执行 .........................................................................4  
actor 之间只能通过消息进行通信 .........................................................................5  
actor 可以创建子actor ...........................................................................................6  
actor 可以改变自己的状态或行为 .........................................................................8  
一切都是actor .......................................................................................................9  
Actor 模型的使用 .................................................................................................10  
定义清晰的边界 ................................................................................................... 11  
何时适合使用Actor 模型 ....................................................................................13  
结论 .....................................................................................................................13  
第2 章 Akka 简介 .......................................................................15  
Akka 是什么......................................................................................................... 15  
Akka 是开源的 .............................................................................................. 15  
Akka 正在蓬勃发展 .......................................................................................16  
Akka 是为分布式设计的 ...............................................................................16  
Akka 组件 ............................................................................................................17  
Akka actor .....................................................................................................17  
子actor .......................................................................................................... 18  
remoting :不同JVM 上的actor ....................................................................20  
clustering :集群成员的自动化管理 ..............................................................20  
Akka HTTP ...................................................................................................24  
TestKit ........................................................................................................... 25  
contrib ........................................................................................................... 25  
Akka OSGi ................................................................................................... 25  
Akka HTTP ...................................................................................................26  
Akka Streams ................................................................................................26  
Akka 实现的Actor 模型 ......................................................................................26  
Actor 模型中的Akka actor ..................................................................................26  
消息传递 .......................................................................................................27  
actor 系统 ...................................................................................................... 28  
Akka Typed 项目 .................................................................................................. 28  
结论 ....................................................................................................................29  
第3 章 分布式领域驱动设计 ........................................................31  
DDD 概述 ............................................................................................................31  
DDD 的好处 .........................................................................................................32  
DDD 组件 ............................................................................................................33  
域实体 ..................................................................................................................34  
域值对象 .............................................................................................................34  
聚合与聚合根 ..................................................................................................... 35  
仓储 .....................................................................................................................37  
工厂和对象创建 ................................................................................................... 38  
域服务 .................................................................................................................. 38  
有界上下文 ..........................................................................................................39  
结论 ....................................................................................................................41  
第4 章 优秀的Actor 设计 ...........................................................43  
大系统小做 ..........................................................................................................43  
封装actor 中的状态 ............................................................................................44  
使用字段封装状态 .......................................................................................44  
使用“状态”容器封装状态 ........................................................................47  
使用become 封装状态 ................................................................................. 48  
将futures 与actors 混合 ............................................................................... 50  
Ask 模式和替代方案 ............................................................................................ 54  
Ask 模式的问题 ........................................................................................... 55  
附带的复杂性 ................................................................................................ 57  
Ask 的替代方案 ........................................................................................... 57  
命令与事件 .......................................................................................................... 59  
构造函数的依赖注入 ....................................................................................61  
使用路径查找actor ......................................................................................61  
结论 ....................................................................................................................62  
第5 章 数据流 ............................................................................63  
吞吐量与延迟 ......................................................................................................63  
流 .........................................................................................................................64  
路由器 ..................................................................................................................66  
邮箱 ..................................................................................................................... 68  
无界邮箱 ...................................................................................................... 68  
有界邮箱 ......................................................................................................69  
拉取的工作模式 ..................................................................................................70  
背压 .....................................................................................................................73  
ack .................................................................................................................73  
高水位标记 ...................................................................................................73  
队列长度监控 ................................................................................................74  
速率监控 ......................................................................................................74  
Akka 数据流.........................................................................................................74  
源 .................................................................................................................. 75  
汇 ..................................................................................................................77  
RunnableGraph ............................................................................................. 78  
流 ..................................................................................................................79  
交叉点 ........................................................................................................... 80  
Akka 流中的背压 ......................................................................................... 81  
Akka 流的使用 ............................................................................................. 82  
结论 .................................................................................................................... 84  
第6 章 一致性和可扩展性 ...........................................................85  
事务和一致性 ...................................................................................................... 85  
强一致性与最终一致性 ....................................................................................... 86  
并发性与并行性 ................................................................................................... 86  
为什么全局一致的分布式状态影响可扩展性 ...................................................... 86  
位置透明性 ......................................................................................................... 87  
交付保证 ............................................................................................................. 87  
最多投递一次 ................................................................................................ 87  
最少投递一次 ................................................................................................ 88  
恰好一次交付是不可能的(但可以近似做到) .............................................91  
如何近似做到恰好一次交付 .........................................................................91  
集群单例 .......................................................................................................92  
可扩展性 ..............................................................................................................94  
避免全局状态 ............................................................................................... 98  
避免共享状态 ............................................................................................... 98  
遵循Actor 模型 .............................................................................................99  
避免顺序操作 ...............................................................................................99  
隔离阻塞型操作 ...........................................................................................99  
监控和调优 ..................................................................................................99  
集群分片和一致性 ...............................................................................................99  
分片 ............................................................................................................. 100  
Akka 中的分片 ........................................................................................... 101  
分片键的生成 ............................................................................................. 102  
分片的分布 ................................................................................................ 103  
一致性边界 ................................................................................................. 103  
可扩展性边界 ............................................................................................. 104  
分片聚合根 ................................................................................................ 105  
持久化 ......................................................................................................... 106  
钝化 ............................................................................................................. 106  
使用集群分片保证一致性 ........................................................................... 107  
结论 .................................................................................................................. 109  
第7 章 容错 .............................................................................111  
故障类型 ........................................................................................................... 112  
异常 ............................................................................................................ 112  
JVM 中的致命错误 .................................................................................... 113  
外部服务故障 ............................................................................................. 113  
不符合服务等级协议 .................................................................................. 113  
操作系统和硬件级故障 .............................................................................. 114  
故障隔离 ........................................................................................................... 114  
舱壁模式 .................................................................................................... 114  
优雅降级 ..................................................................................................... 117  
使用Akka 集群隔离故障 ............................................................................ 119  
使用熔断器控制故障 ................................................................................... 119  
故障处理 ............................................................................................................ 122  
异常处理 ..................................................................................................... 123  
外部服务的故障处理 .................................................................................. 128  
结论 ................................................................................................................... 131  
第8 章 可用性 ..........................................................................133  
微服务和单体式应用 ........................................................................................ 133  
用有界上下文划分微服务 ................................................................................. 134  
细粒度的微服务 ................................................................................................. 135  
集群感知路由器 ................................................................................................. 135  
分布式数据 ....................................................................................................... 137  
优雅降级 ............................................................................................................ 140  
部署 ................................................................................................................... 141  
分阶段部署/ 滚动重启 ..................................................................................... 142  
蓝/ 绿部署 ........................................................................................................ 142  
崩溃恢复/ 运维监测 ......................................................................................... 143  
健康检查和应用状态页面 .......................................................................... 143  
度量 ............................................................................................................ 145  
日志 ............................................................................................................. 146  
看门狗工具 ................................................................................................. 146  
结论 .................................................................................................................. 147  
第9 章 性能 ...........................................................................149  
隔离瓶颈 ........................................................................................................... 150  
优化Akka ......................................................................................................... 150  
减少或隔离阻塞型操作 .............................................................................. 150  
缩短消息处理时间 ...................................................................................... 151  
增加处理消息的actor ................................................................................ 151  
派发器 ................................................................................................................ 151  
标准派发器 ................................................................................................. 151  
固定派发器 ................................................................................................. 153  
平衡派发器 ................................................................................................ 154  
calling-thread 派发器 .................................................................................. 154  
何时使用单独的派发器 .............................................................................. 155  
提高并行性 ................................................................................................ 157  
结论 .................................................................................................................. 158  
后记 ..........................................................................................159  
参考文献 ...................................................................................161  
关于作者 ...................................................................................162  
封面介绍 ...................................................................................163      
前言/序言
   前言
 响应式应用开发是软件开发的新前沿。 随着联网设备的普及,数据量也在增加。以前的单线程批处理数据的旧技术根本无法满足这个新领域所提出的需求。大数据的概念已经兴起,我们需要新的工具和新的技术来应对它。
 通常,解决现有问题的灵感并不是来自现有的技术,而是来自过去的经验。许多现今用于处理大数据的新工具实际上是基于旧的actor 的概念而产生的。actor 是构建Akka 的关键概念,但其根源追溯起来应该属于过去。actor 不是一个新概念,相反,它是一个被重新关注的旧概念。
 当开始探索Akka、actor、streams 和其他与之相关的技术时,我们将从现实世界的角度来看待它们:如何在一系列项目中安排一组人,同时优化他们的可用时间及技能?这是一个复杂的问题,并不是只用一个下午就可以解决的。但这又是一个有趣的问题,为深度探索提供了很大的空间。这也是大多数软件开发人员在职业生涯中的某个时刻一定会遇到的问题。 在对Akka 进行探索的过程中,我们将回顾这个问题。
 在解决问题之前,我们必须先了解可用的工具,还需要了解这些工具为什么存在,以及它们可以解决什么样的问题。我们需要知道Akka 的起源及其在Actor 模型中的根源。我们需要一套指导原则将应用程序拼接在一起,这套原则会在探索域驱动设计(DDD)的过程中被发现。有了这些基础,便可以开始使用Akka 提供的所有工具来构建域了。我们可以探索简单的actor 的使用方法以及它如何与流关联,可以让系统分布在多个节点上,使其具有更好的容错性、可用性及可扩展性。
 首先,我们需要知道这一切的根源在哪里。
 
 
 译者序
 我在大学期间开始接触并使用Scala,当时就发现了这门语言的强大。正如其名字所表达的那样,Scala 是一门可扩展的编程语言,融合了函数式编程和面向对象编程的特点,支持并发,让异步编程变得很自然,同时表达能力也特别强。虽然Scala 的学习成本会比较高,尤其和Golang、Python 这类语言相比,但是这门语言还是非常实用的,对提高开发效率很有帮助。而且Scala 的创始人Martin Odersky 说过:“Scala 现在是为聪明人创造的,以后也是为聪明人服务的。” Scala 相信程序员的聪明才智,让程序员自行选择合适的结构,以应对千变万化的任务需求,这一点是Scala 做得很不错的地方。
 编写正确的具有容错性和可扩展性的分布式、高并发程序非常困难,主要是因为我们使用了错误的工具和错误的抽象层次,而Akka 的出现改变了这种情况。Akka 是参照Apache 2 许可证(一种公认的开源许可证)发布的开源项目,通过使用Actor 模型来提高抽象的级别,并提供了一个更好的平台来构建可扩展的、有弹性的、响应式的应用程序,详细信息可参阅The Reactive Manifesto。对于容错,Akka 采用“让它崩溃(Let It Crash)”的模式,这种模式可以帮助构建可自我修复和永不停止的软件系统。其中actor还提供了透明的分布式抽象,以及真正的可扩展与高容错应用的基础设施。
 毕业后,我在腾讯微信团队的后台架构部从事软件开发工作,作为腾讯的战略级产品,微信平均每天面临亿级的在线用户。面对这种用户规模的挑战,基本每一行代码都需要考虑高并发和分布式的场景,大道至简的思想基本贯彻在整个技术产品线上。例如,大系统小做,让一切可扩展;剥离复杂,让剩下的更简单;在容灾之前面向最坏情况思考,防止雪崩;精细监控,迅速响应等。微信团队内部的很多技术点也和Actor 模型很像,比如微信最核心的消息模型和Actor 的邮件模型就很有渊源。消息被发出后,会先在后台临时存储,为了使接收者能更快接收到消息,系统会推送通知给接收者,最后客户端主动到服务器端拉取消息。当然整个微信架构就是微服务的架构,每一个请求后面可能会涉及几百个服务。如何扩展、如何高容错、如何弹性,这些基本是每天都会遇到的挑战,并且也都是设计和开发系统的时候需要考虑的事情。
 后来,我离开腾讯,在猎豹移动的广告系统架构部以及新闻团队从事系统架构开发工作,同样涉及微服务架构,每天都要考虑到这些分布式系统可能遇到的并且需要处理的问题。尤其广告系统涉及金钱,因而需要严格保证其高可用性和一致性。
 现在,我在创业公司担任技术负责人,同时负责公司内部多个系统的架构工作,也需要时时刻刻考虑和处理高并发、高容错等分布式问题,同样用到了高并发的分布式微服务架构。
 本书原名是Applied Akka Patterns :A Hands-On Guide to Designing Distributed Applications,书中介绍了一些很好的分布式系统的设计原则,而且也介绍了Actor 模型和Akka 工具包,对于使用JVM 体系结构的开发者来说是非常值得一看的,因为通过本书能很快地学习并掌握一个强大的工具,在工作中提高生产效率。对于那些使用非JVM体系结构的开发者来说,通过这本书能了解到一个更强大的工具,也是极有帮助的。同时,本书介绍的很多指导原则对于分布式系统设计有很大的借鉴意义,可以避免让自己陷入困境。这本书是一个起点,帮助我们发现新大陆,但绝不会是我们的终点,开拓这块新大陆还需要自己不断努力。其实Scala 本身就是一门很强大的语言,最近也因为Spark、Kafka 等项目在国内掀起了一波关注热潮。Akka 也很优秀,以至于被 Lightbend 收购,并直接用Akka 的actor 替代了Scala 本身的actor。总之,本书中介绍的内容都是非常值得探索和学习的。
 决定翻译这本书,不仅因为我参与和主导了不少分布式的项目,也因为对分布式系统设计和开发的热爱,以及对Scala 语言本身的喜欢。我抱着把Actor 模型以及Akka 传递给中国的工程师并让更多人能接触、了解它们的态度来尝试翻译这本书。虽然它们在国内还不算太火,但是在国外已经非常受欢迎。
 这本书虽然只有160 多页,但是翻译过程还是比较辛苦的,很多地方的意思都比较隐晦,用中文直译会很有挑战。所以我平时会留意大家在社区里讨论的内容,参考社区里的资料,在遇到一些和自己项目经验不太一致或者比较不确定的地方,也会尝试去查看Akka的源码来尽量保证自己的理解无误,避免误导读者。
 在本书的翻译工作结束之际,我首先要感谢博云科技的CTO 李亚琼老师,他的引荐让我获得了翻译这本书的机会。还要感谢孙国立、曾杰瑜、付冉、刘岸,他们在百忙中帮我审阅了本书翻译稿的大部分章节,并针对涉及的专业概念提出不少修改意见。最后要感谢本书的策划编辑孙奇俏,她为本书的编辑和校对做了大量细致的工作。
 翻译过程中虽力求理解作者意图,把握全文,但是难免会发生错误,若广大读者发现错误,我在此深表歉意。欢迎广大读者及时与我和出版社联系,提交勘误,方便后续读者更好地阅读。如果有任何好的想法和建议,也欢迎和我邮件沟通,我的邮箱地址是hangzhong.yu@gmail.com。
 虞航仲
 2017 年8 月于北京
 
    
				 
				
				
					Akka应用模式:分布式应用程序设计实践指南  图书简介  在这本深入的指南中,我们将一同探索Akka这个强大的工具集,它为构建健壮、高可用且可扩展的分布式系统提供了坚实的基础。本书并非空泛的理论阐述,而是聚焦于解决实际问题,通过一系列精心设计的应用模式,引导您掌握如何在复杂的分布式环境中有效地设计、开发和部署应用程序。我们将深入剖析Akka的核心概念,并展示如何将这些概念转化为可行的、经过实践检验的设计方案。  核心理念与基石:Actors、消息传递与不可变性  理解Akka的精髓,离不开对其核心理念的深刻洞察。本书将从最基础的Actor模型入手,详细讲解Actor的生命周期、状态管理以及它们如何通过异步消息传递进行通信。我们将摒弃传统的线程与锁的复杂纠缠,拥抱Akka所倡导的“一切皆Actor”的哲学。通过大量的代码示例和图示,您将清晰地理解Actor如何成为分布式系统中独立、隔离的计算单元,以及它们之间如何通过“别无选择”的消息传递机制来实现高效协作。  不可变性是Akka设计中的另一块重要基石。我们将深入探讨为什么不可变数据结构在分布式环境中至关重要,以及它们如何显著简化并发编程的复杂性,消除竞态条件,并提升系统的整体可靠性。您将学会如何利用Akka提供的工具和模式来有效地处理不可变数据,从而构建更加安全和易于推理的系统。  分布式应用模式的实践  本书的主体内容将围绕一系列经过验证的Akka应用模式展开,这些模式是应对分布式系统挑战的实战策略:     Actor层级与容错(Supervision Strategies): 在分布式系统中,组件的失败是不可避免的。本书将详细介绍Akka强大的Actor层级结构,以及如何利用其内置的容错机制来管理Actor的生命周期。我们将深入探讨不同的监督策略(如“停止”、“重启”、“恢复”、“升级”)及其适用场景,并通过实际案例演示如何构建能够自我 healing 的分布式系统,最大限度地减少因局部故障对整体可用性的影响。您将学会如何设计Actor的层级结构,确保系统能够优雅地处理异常,并在错误发生时快速恢复。     状态管理与持久化(State Management and Persistence): 分布式系统需要可靠的状态管理。本书将详细介绍Akka Persistence,一个为Actor提供持久化能力的强大模块。您将学习如何使用Event Sourcing和CQRS(Command Query Responsibility Segregation)等模式来构建能够处理高并发读写请求的系统。我们将演示如何将Actor的状态持久化到各种后端存储(如数据库、文件系统),并演示如何从持久化的事件流中恢复Actor的状态。这将帮助您构建能够应对数据丢失风险、提供强大一致性保证的应用程序。     集群与分布式协调(Clustering and Distributed Coordination): 构建大规模分布式系统离不开集群的概念。本书将深入探讨Akka Cluster,它使得跨多个节点的Actor系统能够无缝协作。您将学习如何设置Akka Cluster,配置成员加入与离开机制,以及如何利用集群singleton、分布式数据(Distributed Data)和分布式锁(Distributed Locks)等高级特性来实现跨节点的分布式协调和状态同步。通过实际场景的演练,您将能够构建高度可用的、能够自动伸缩的分布式服务。     消息路由与负载均衡(Message Routing and Load Balancing): 在大型分布式系统中,高效的消息路由和负载均衡是提升系统吞吐量和响应速度的关键。本书将介绍Akka的Router机制,演示如何使用不同的路由策略(如轮询、随机、一致性哈希)来将消息分发到Actor的池中。您将学会如何根据业务需求选择最合适的路由策略,从而有效地平衡节点负载,防止单点过载,并提升整体系统的性能。     流式处理与事件驱动(Streaming and Event-Driven Architectures): 现代应用程序越来越倾向于事件驱动和流式处理。本书将深入介绍Akka Streams,一个用于构建响应式流式处理应用程序的声明式API。您将学习如何使用Source、Flow和Sink来组合和处理数据流,实现低延迟、高吞吐量的数据管道。我们将演示如何将Akka Streams与其他Akka模块(如Akka Cluster)结合,构建复杂的事件驱动系统,处理实时数据分析、消息队列集成等场景。     分布式缓存与数据一致性(Distributed Caching and Data Consistency): 高性能的分布式应用通常需要高效的缓存机制。本书将探讨如何在Akka环境中实现分布式缓存,并重点关注数据一致性问题。我们将介绍Akka Distributed Data提供的CRDTs(Conflict-free Replicated Data Types),以及如何利用它们来构建最终一致性的分布式数据结构,从而在保证一定程度的数据一致性的同时,实现高性能的读写操作。     与外部系统的集成(Integration with External Systems): 任何分布式系统都不可能孤立存在,与外部系统的集成是必不可少的。本书将提供指导,说明如何利用Akka的Actor模型与外部服务(如数据库、消息队列、REST API)进行交互。您将学习如何设计Actor来封装外部系统的客户端,并利用Akka的Actor间通信机制来实现异步、解耦的集成,从而提高系统的灵活性和可维护性。  高级主题与最佳实践  除了核心的应用模式,本书还将涵盖一些高级主题和最佳实践,帮助您更上一层楼:     性能调优与监控(Performance Tuning and Monitoring): 构建高性能的分布式系统需要细致的调优和持续的监控。我们将探讨Akka的性能特点,提供识别瓶颈和进行优化的技巧。您将学习如何利用Akka提供的监控工具和第三方解决方案来跟踪Actor的行为,分析消息流,并识别潜在的性能问题。     测试策略(Testing Strategies): 分布式系统的测试是其复杂性所在。本书将介绍针对Akka应用程序的各种测试策略,包括单元测试、集成测试和端到端测试。您将学习如何利用Akka TestKit来模拟Actor的行为,构建可靠的测试场景,确保您的分布式组件能够按预期工作。     部署与运维(Deployment and Operations): 将分布式系统成功部署到生产环境是关键一步。本书将讨论Akka应用程序的部署考量,包括容器化(如Docker)、服务发现以及与CI/CD流程的集成。您将获得关于如何在分布式环境中进行有效的系统管理和故障排除的指导。  面向读者  本书适合有一定Java或Scala编程经验,并希望深入理解和实践分布式系统设计的开发者、架构师和技术领导者。无论您是初次接触Akka,还是已经有所了解但希望系统性地掌握其应用模式,本书都将为您提供宝贵的知识和实用的指导。  本书的目标  通过阅读本书,您将能够:     深刻理解Akka的核心概念,并将其应用于实际开发中。    掌握多种Akka应用模式,并能够根据具体场景选择和实现。    构建健壮、高可用、可扩展的分布式应用程序,有效应对并发和容错挑战。    提升分布式系统的设计与开发能力,自信地应对复杂的系统需求。    为构建下一代分布式解决方案奠定坚实的基础。  踏上Akka的应用之旅,本书将是您最可靠的向导。