本书以高可用服务架构为主题,侧重于讲解高可用架构设计的核心要点:可伸缩和可扩展,从应用层、数据库、缓存、消息队列、大数据查询系统、分布式定时任务调度系统、微服务等层面详细讲解如何设计可伸缩、可扩展的框架,并给出在各个领域解决特定问题的方法论和实践总结。随着本书的出版,我们还开源了4个行之有效的互联网可伸缩框架,包括数据库分库分表dbsplit、缓存分片redic、专业的发号器vesta和消息队列处理机框架kclient,每个框架都开箱即用,也可以作为学习互联网平台化框架搭建的素材,更可以作为开发开源项目的示例。本书的上册《分布式服务架构:原理、设计与实战》详细介绍了如何解决线上高并发服务的一致性、高性能、高可用、敏捷等痛点,本书与上册结合后可覆盖保证线上高并发服务的各个主题:一致性、高性能、高可用、可伸缩、可扩展、敏捷性等,每个主题都是一个方法论。充分理解这些主题,可保障线上服务健壮运行,对实现服务稳定性的n个9有着不可估量的作用。无论是对于互联网的或者传统的软件工程师、测试工程师、架构师,还是对于深耕于IT的其他管理人员,本书都有很强的借鉴性和参考价值,是值得每个技术人员阅读的架构级技术书。
云时代架构系列经典!重磅级架构书2018年重磅上市!
详解高可用架构设计的核心要点:可伸缩与可扩展
详解分布式发号器、消息队列框架、数据库分库分表、缓存、Elasticsearch、分布式调度任务、RPC服务、Dubbo、高性能网络代理中间件等
全面破解可伸缩服务架构的奥秘
分布式服务架构:原理、设计与实战读者的配套技能升级架构书。
前 言
本书的上册《分布式服务架构:原理、设计与实战》详细介绍了如何解决线上高并发服务的一致性、高性能、高可用、敏捷等痛点。本书延续了高可用服务架构的主题,侧重于讲解高可用架构设计的核心要点:可伸缩和可扩展,从应用层、数据库、缓存、消息队列、大数据查询系统、分布式定时任务调度系统、微服务等层面详细讲解如何设计可伸缩、可扩展的框架,并给出在各个领域解决特定问题的方法论和实践总结。随着本书的出版,我们还开源了4个行之有效的互联网可伸缩框架,包括数据库分库分表dbsplit、缓存分片redic、专业的发号器vesta和消息队列处理机框架kclient,每个框架都开箱即用,且都是独立的互联网高并发框架,是构建互联网级项目的重要组件,也可以作为学习互联网平台化框架搭建的素材,更可以作为开发开源项目的示例。
在写作本书的过程中,我们的多位作者根据自身在互联网大规模、高并发项目中遇到的实际问题,总结了切实有效的方法论和解决方案,最后沉淀出一套适合高并发服务的优秀开源技术框架,其中的方法论可以帮助读者解决实际问题,开源框架可以帮助读者快速搭建可伸缩的互联网高并发项目。无论是对于互联网的或者传统的软件工程师、测试工程师、架构师,还是对于深耕于IT的其他管理人员,本书都有很强的借鉴性和参考价值,是值得每个技术人员阅读的架构级技术书。
感谢我的作者团队,杨彪、海亮、刘淏、博岩等无数次地与我一起通宵达旦地赶稿子;感谢汪勤平、史先斌、潘运鹏、张诚、高亮、李继、周伟、曲源等同学在编辑阶段为我阅稿,并提出专业意见;感谢IT行业内的重量级大咖焦英俊、杨延峰、右军(于君泽)在百忙之中抽出时间为本书作序;也感谢大作者开涛和安晓辉等同学为本书写评语;感谢各个行业的重量级朋友们对本书的大力支持,包括:冯沁原、贺伟、张义明、马星光、高春东、黄福伟、李雪冰、付红雷等;更感谢加入云时代架构技术社区的小伙伴们的持续关注和支持!
在写书的过程中,我们每个人都兢兢业业、勤勤恳恳,每增加一部分内容,都互相审核,尽量保证书中案例的准确性和时效性,确保能为读者带来很有价值的设计经验,并且我们想做到授人以渔,而不是授人以鱼。在写作的过程中有辛苦、有快乐、有价值、有成果,我们希望能持续地为读者带来经验、解决方案、架构思路和快乐。
感谢电子工业出版社博文视点张国霞编辑的认真态度和辛勤工作,本书在经过作者们及国霞编辑大半年的努力后最终顺利出版。
最后,感谢我的妻子和父母在我写书期间对我的全力支持和帮助。
李艳鹏
2018年3月
推荐序一
从传统互联网到移动互联网再到物联网,中国乃至全球的互联网技术在近十年得到了高速发展。作为架构师,我们非常乐意把这些技术传播出去,让更多的人享受互联网技术的红利,让技术拓展商业的边界。阿里巴巴的双11技术已经越来越成熟,因为阿里巴巴已经逐步具备了基于云的计算能力,可以轻松应对各种业务压力。
本书的内容包括缓存分片、消息队列框架、数据库分库分表、分布式发号器、大数据查询系统、分布式定时调度任务系统、微服务和RPC等;并配备了4个开箱即用的开源项目,包括分库分表框架dbsplit、专业的发号器vesta、消息队列框架kclient和缓存分片的redic,每个项目都是独立的互联网高并发框架,是构建互联网级项目的重要组件。本书对行业内许多流行的开源项目也有很多介绍,读者可以在其中学到平台架构设计的方方面面,也可以了解开源项目在构思和实现方面的优秀实践。
互联网的技术核心其实源于分布式,这是互联网具备高性能、高并发特性的基础,掌握这些核心内容后,你会发现驾驭技术变得如此轻松!希望艳鹏的这本书可以带领大家掌握分布式的精髓,这本书非常棒!也感谢艳鹏邀请我为本书作序!
技术的世界是如此美妙,作为一名深耕架构的技术人,我由衷地希望有更多的人加入,一起为中国的技术添砖加瓦!
焦英俊
未达科技CEO、原阿里巴巴中文站首席架构师
推荐序二
近十年来,互联网服务在社交网络、搜索、电商、O2O、视频、移动和云计算等领域呈现了井喷式发展,伴随而来的是数千万的日订单量、数亿的日活跃用户、数百亿的日消息发送量等海量的业务规模。支撑这些海量的业务规模的则是基于廉价服务器集群的高可用、可伸缩的分布式互联网技术。
本书以可伸缩服务架构为重点,从理论基础、架构设计、一线行业的实践经验和代码实现细节等方面,系统化地介绍了分布式互联网的高可用、可伸缩技术的核心要点,是一本兼具深度和广度的技术参考书。
虽然本书的主题是架构,但是这并不影响本书的易读性,它比大多数同类书都要讲得透彻、明白,也适合有想法、有目标的初中级开发人员阅读。分库分表、Dubbo 源码解析等方面的内容,更可以帮助高级技术人员提升自己的技术实力,以及发挥更大的价值。
架构是在长期的生产活动中经过深度思考所积累下来的优秀实践和可复用的合理抽象,希望你不要错过本书的精彩内容。
杨延峰
开心网副总裁
推荐序三
杨彪兄弟找我为本书写序,我欣然从命。我阅读了这本佳作的若干个章节,发现它有几个特点:紧扣常见的问题域;结合了开源产品;代码很讲究。这里,我想谈一谈开源与写作的关系,因为我觉得这就是一场修行。
什么是开源?我的粗浅理解就是,开源就是开源产品,是开放了源代码的产品。我从业16年,用过不少开源产品,但发现被广泛使用的项目并不都拥有好的代码和充分的测试用例,可见知易行难。可喜的是,国人的开源产品在逐渐增多,也有不少好作品出现,艳鹏的vesta-id-generator解决的就是分布式系统中常见的ID生成问题。
古人谈学习有眼到、手到、心到之说。
眼到指的是阅读,但阅读面广并不见得知识就是自己的,例如一个早晚听张靓颖歌曲的粉丝不见得就能发出海豚音。
手到指的是要不断练习,当然,这并不是指简单、重复地练习。佛罗里达州立大学心理学家K. Anders Ericsson首次提出了刻意练习的概念,该练习方法的核心假设是:专家级水平是逐渐练出来的,而有效进步的关键在于找到一系列小任务让受训者按顺序完成,这些小任务必须是受训者正好不会做但又可以学习和掌握的。
我认为,心到的一个环节是写作。写作能帮我们把脉络梳理得更通畅。从自己懂,到给别人讲明白,再到写出来且别人还能明白,是进阶的关系。
所以,从项目产品实践,到开源,再到写作,就是一场修行。修行是外在的表现、是与同行交流、是与世界对话;修行也是内观,是收获若干思想的结晶、汲取若干灵感的泉水、沉淀若干系统的对白,在其中收获更多的就是作者自己。
开卷有益,愿读者也能在阅读和实践上收获知与行的快乐!
于君泽
蚂蚁金服高级技术专家
?李艳鹏云时代架构技术社区创始人,著有《分布式服务架构:原理、设计与实战》,现任某知名支付平台架构组负责人,曾在花旗银行、甲骨文、路透社、新浪微博等大型IT互联网公司担任技术负责人和架构师,现专注于大规模高并发的线上和线下支付平台的应用架构和技术架构的规划与落地,负责交易、支付、渠道、出款、风控、对账等核心支付系统的设计与实现,在移动支付、聚合支付、合规账户、扫码支付、标记化支付等业务场景上有产品应用架构规划与落地的实践经验。?杨彪现任游戏创业公司技术总监及合伙人,云时代架构技术社区合伙创始人,CSDN达人课讲师,著有《分布式服务架构:原理、设计与实战》。在互联网和游戏行业有近十年工作经验,曾在酷我音乐盒、人人游戏和掌趣科技等上市公司担任核心研发职位,在互联网公司做过日活跃用户量达千万的项目,也在游戏公司做过多款月流水千万以上的游戏。?李海亮现任某互联网公司搜索研发经理,有近十年互联网公司的搜索及搜索相关的研发经验?贾博岩现任某支付公司高级开发工程师,专注于支付系统领域的开发,例如商户入网、商户对外出款等业务。标准90后,喜欢钻研技术,维护个人简书博客贾博岩。?刘?B现任某互联网公司技术专家,长期在外企从事技术经理和架构工作,对数据库应用及搜索引擎应用有很深入的理解和实践;有大型数据服务集群的架构调优及运维经验;精通性能问题的解决与调优,以及高性能中间件的编写。目前主要研究业务数据自动化框架及其实现。
第1章 如何设计一款永不重复的高性能分布式发号器1
1.1 可选方案及技术选型2
1.1.1 为什么不用UUID2
1.1.2 基于数据库的实现方案2
1.1.3 Snowflake开源项目3
1.1.4 小结4
1.2 分布式系统对发号器的基本需求4
1.3 架构设计与核心要点6
1.3.1 发布模式6
1.3.2 ID类型7
1.3.3 数据结构7
1.3.4 并发9
1.3.5 机器ID的分配9
1.3.6 时间同步10
1.3.7 设计验证11
1.4 如何根据设计实现多场景的发号器11
1.4.1 项目结构12
1.4.2 服务接口的定义14
1.4.3 服务接口的实现15
1.4.4 ID元数据与长整型ID的互相转换22
1.4.5 时间操作25
1.4.6 机器ID的生成27
1.4.7 小结32
1.5 如何保证性能需求32
1.5.1 嵌入发布模式的压测结果33
1.5.2 中心服务器发布模式的压测结果33
1.5.3 REST发布模式(Netty实现)的压测结果33
1.5.4 REST发布模式(Spring Boot Tomcat实现)的压测结果34
1.5.5 性能测试总结34
1.6 如何让用户快速使用35
1.6.1 REST发布模式的使用指南35
1.6.2 服务化模式的使用指南38
1.6.3 嵌入发布模式的使用指南41
1.7 为用户提供API文档43
1.7.1 RESTful API文档44
1.7.2 Java API文档45
第2章 可灵活扩展的消息队列框架的设计与实现49
2.1 背景介绍50
2.2 项目目标50
2.2.1 简单易用50
2.2.2 高性能51
2.2.3 高稳定性51
2.3 架构难点51
2.3.1 线程模型51
2.3.2 异常处理53
2.3.3 优雅关机53
2.4 设计与实现54
2.4.1 项目结构54
2.4.2 项目包的规划55
2.4.3 生产者的设计与实现57
2.4.4 消费者的设计与实现58
2.4.5 启动模块的设计与实现67
2.4.6 消息处理器的体系结构76
2.4.7 反射机制79
2.4.8 模板项目的设计80
2.5 使用指南82
2.5.1 安装步骤82
2.5.2 Java API83
2.5.3 与Spring环境集成84
2.5.4 对服务源码进行注解85
2.6 API简介87
2.6.1 Producer API87
2.6.2 Consumer API88
2.6.3 消息处理器88
2.6.4 消息处理器定义的注解90
2.7 消息处理机模板项目91
2.7.1 快速开发向导91
2.7.2 后台监控和管理92
第3章 轻量级的数据库分库分表架构与框架93
3.1 什么是分库分表94
3.1.1 使用数据库的三个阶段94
3.1.2 在什么情况下需要分库分表95
3.1.3 分库分表的典型实例96
3.2 三种分而治之的解决方案97
3.2.1 客户端分片97
3.2.2 代理分片100
3.2.3 支持事务的分布式数据库101
3.3 分库分表的架构设计102
3.3.1 整体的切分方式102
3.3.2 水平切分方式的路由过程和分片维度106
3.3.3 分片后的事务处理机制107
3.3.4 读写分离119
3.3.5 分库分表引起的问题119
3.4 流行代理分片框架Mycat的初体验123
3.4.1 安装Mycat123
3.4.2 配置Mycat124
3.4.3 配置数据库节点128
3.4.4 数据迁移129
3.4.5 Mycat支持的分片规则129
3.5 流行的客户端分片框架Sharding JDBC的初体验138
3.5.1 Sharding JDBC简介138
3.5.2 Sharding JDBC的功能139
3.5.3 Sharding JDBC的使用141
3.5.4 Sharding JDBC的使用限制152
3.6 自研客户端分片框架dbsplit的设计、实现与使用153
3.6.1 项目结构154
3.6.2 包结构和执行流程155
3.6.3 切片下标命名策略159
3.6.4 SQL解析和组装167
3.6.5 SQL实用程序168
3.6.6 反射实用程序173
3.6.7 分片规则的配置177
3.6.8 支持分片的SplitJdbcTemplate和SimpleSplitJdbcTemplate接口API179
3.6.9 JdbcTemplate的扩展SimpleJdbcTemplate接口API184
3.6.10 用于创建分库分表数据库的脚本工具187
3.6.11 使用dbsplit的一个简单示例192
3.6.12 使用dbsplit的线上真实示例展示199
第4章 缓存的本质和缓存使用的优秀实践201
4.1 使用缓存的目的和问题202
4.2 自相似,CPU的缓存和系统架构的缓存203
4.2.1 CPU缓存的架构及性能205
4.2.2 CPU缓存的运行过程分析206
4.2.3 缓存行与伪共享208
4.2.4 从CPU的体系架构到分布式的缓存架构218
4.3 常用的分布式缓存解决方案221
4.3.1 常用的分布式缓存的对比221
4.3.2 Redis初体验225
4.4 分布式缓存的通用方法229
4.4.1 缓存编程的具体方法229
4.4.2 应用层访问缓存的模式233
4.4.3 分布式缓存分片的三种模式235
4.4.4 分布式缓存的迁移方案238
4.4.5 缓存穿透、缓存并发和缓存雪崩244
4.4.6 缓存对事务的支持246
4.5 分布式缓存的设计与案例248
4.5.1 缓存设计的核心要素248
4.5.2 缓存设计的优秀实践250
4.5.3 关于常见的缓存线上问题的案例253
4.6 客户端缓存分片框架redic的设计与实现257
4.6.1 什么时候需要redic258
4.6.2 如何使用redic258
4.6.3 更多的配置258
4.6.4 项目结构260
4.6.5 包结构261
4.6.6 设计与实现的过程261
第5章 大数据利器之Elasticsearch268
5.1 Lucene简介269
5.1.1 核心模块269
5.1.2 核心术语270
5.1.3 检索方式271
5.1.4 分段存储273
5.1.5 段合并策略275
5.1.6 Lucene相似度打分278
5.2 Elasticsearch简介286
5.2.1 核心概念286
5.2.2 3C和脑裂289
5.2.3 事务日志291
5.2.4 在集群中写索引294
5.2.5 集群中的查询流程295
5.3 Elasticsearch实战298
5.3.1 Elasticsearch的配置说明298
5.3.2 常用的接口300
5.4 性能调优305
5.4.1 写优化305
5.4.2 读优化308
5.4.3 堆大小的设置313
5.4.4 服务器配置的选择315
5.4.5 硬盘的选择和设置316
5.4.6 接入方式318
5.4.7 角色隔离和脑裂319
第6章 全面揭秘分布式定时任务321
6.1 什么是定时任务322
6.2 分布式定时任务341
6.2.1 定时任务的使用场景342
6.2.2 传统定时任务存在的问题342
6.2.3 分布式定时任务及其原理344
6.3 开源分布式定时任务的用法347
6.3.1 Quartz的分布式模式347
6.3.2 TBSchedule356
6.3.3 Elastic-Job365
第7章 RPC服务的发展历程和对比分析377
7.1 什么是RPC服务378
7.2 RPC服务的原理379
7.2.1 Sokcet套接字379
7.2.2 RPC的调用过程380
7.3 在程序中使用RPC服务382
7.4 RPC服务的发展历程383
7.4.1 第一代RPC:以ONC RPC和DCE RPC为代表的函数式RPC384
7.4.2 第二代RPC:支持面对象的编程388
7.4.3 第三代RPC:SOA和微服务398
7.4.4 架构的演进402
7.5 主流的RPC框架403
7.5.1 Thrift403
7.5.2 ZeroC Ice410
7.5.3 gRPC418
7.5.4 Dubbo430
第8章 Dubbo实战及源码分析436
8.1 Dubbo的四种配置方式437
8.1.1 XML配置437
8.1.2 属性配置440
8.1.3 API配置441
8.1.4 注解配置443
8.2 服务的注册与发现446
8.2.1 注册中心446
8.2.2 服务暴露449
8.2.3 引用服务451
8.3 Dubbo通信协议及序列化探讨455
8.3.1 Dubbo支持的协议455
8.3.2 协议的配置方法456
8.3.3 多协议暴露服务457
8.3.4 Dubbo协议的使用注意事项458
8.3.5 Dubbo协议的约束459
8.4 Dubbo中高效的I/O线程模型459
8.4.1 对Dubbo中I/O模型的分析459
8.4.2 Dubbo中线程配置的相关参数460
8.4.3 在Dubbo线程方面踩过的坑461
8.4.4 对Dubbo中线程使用的建议462
8.5 集群的容错机制与负载均衡462
8.5.1 集群容错机制的原理462
8.5.2 集群容错模式的配置方法464
8.5.3 六种集群容错模式464
8.5.4 集群的负载均衡465
8.6 监控和运维实践467
8.6.1 日志适配467
8.6.2 监控管理后台467
8.6.3 服务降级473
8.6.4 优雅停机475
8.6.5 灰度发布475
8.7 Dubbo项目线上案例解析477
8.7.1 线上问题的通用解决方案477
8.7.2 耗时服务耗尽了线程池的案例480
8.7.3 容错重试机制引发服务雪崩的案例481
8.8 深入剖析Dubbo源码及其实现483
8.8.1 Dubbo的总体架构设计483
8.8.2 配置文件486
8.8.3 Dubbo的核心RPC488
8.8.4 Dubbo巧妙的URL总线设计491
8.8.5 Dubbo的扩展点加载SPI492
8.8.6 Dubbo服务暴露的过程493
8.8.7 服务引用502
8.8.8 集群容错和负载均衡503
8.8.9 集群容错504
8.8.10 负载均衡509
第9章 高性能网络中间件512
9.1 TCP/UDP的核心原理及本质探索513
9.1.1 网络模型513
9.1.2 UDP、IP及其未解决的问题515
9.1.3 TCP详解519
9.1.4 是否可以用UDP代替TCP527
9.1.5 网络通信的不可靠性讨论529
9.2 网络测试优秀实践530
9.2.1 网络测试的关键点530
9.2.2 那些必不可少的网络测试工具532
9.2.3 典型的测试报告539
9.3 高性能网络框架的设计与实现544
9.3.1 对代理功能的测试及分析545
9.3.2 网络中间件的使用介绍549
9.3.3 内存和缓存的优化551
9.3.4 快速解析流数据554