- 已选 件
- 已售件
-
服务
- √7天无理由退货(拆封后不支持)
- √假一赔三
- √消费者保障服务
商品详情
-
ISBN编号
9787121487071
-
书名
从零构建Rust生产级服务
-
作者
[美] Luca,Palmieri(卢卡・帕尔米耶里) 著
-
出版社名称
电子工业出版社
-
定价
168.00
-
开本
16开
-
译者
温祖彤 译
-
出版时间
2024-09-01
-
纸张
胶版纸
-
包装
平装
- 查看全部
编辑推荐
适读人群 :Rust开发工程师,具有一定基础的进阶开发者,后端开发工程师
1.本书由资深Rust开发者撰写。
2.国内资深Rust咨询师技术审校。
3.Rust中文社区创始人由衷力荐。
4.聚焦Rust服务端应用开发实践。
内容简介
本书是一本面向 Rust 后端开发人员的入门参考书,通过实际项目引导读者从 0 到 1 构建一个功能齐全的电子邮件通信API。本书涵盖了广泛的主题,包括 Rust 生态系统的利用、应用结构的设计、测试的编写、用户认证和授权、错误处理策略的实施、应用状态的观察,以及持续集成和部署管道的建立等。本书不仅介绍了具体的工具和库,还深入探讨了系统设计、可观测性和易操作性等重要概念,能够帮助读者掌握专业的开发方法。 本书适合初学者,是开启Rust开发之旅的理想起点,即使没有Rust或后端开发经验,相信你也能够轻松跟上、快速入门。
作者简介
Luca Palmieri是Rust London用户组的联合组织者、开源贡献者和公众演讲者,拥有多年在生产环境中运行数十个Rust服务的经验,也是几个Rust编程的积极推广者和Rust研讨会作者。
温祖彤,电子信息专业硕士在读。曾于字节跳动进行后端开发实习,于清华大学开源操作系统训练营担任Rust基础/算法讲师,在Rust以及相关领域有一定的经验和见解;曾参与多项编程/算法相关竞赛,是一名资深的开源技术以及编程爱好者,还制作过多项人工智能/算法竞赛领域相关的开源课程。
李力,毕业于西安理工大学,Java技术专家,从业9年,曾在网易、Chainup、新东方在线等知名企业从事研发工作,现就职于西安腾讯云,从事于大模型知识引擎LKE开发,实践经验丰富。对分布式系统、架构设计、存储系统充满兴趣。《Scala编程实战》(第2版)译者。
杨楚天,毕业于华东师范大学,任职于诺基亚,从事通信系统开发工作,有多年的 C++ 技术开发经验。在业余时间修炼 Rust,对云原生架构与开发很感兴趣。
精彩书评
如果你想部署一个用Rust编写的Web API或Web应用程序,强烈建议你阅读这本书。这本书让我最欣赏的一点是作者强调了实用的、真实的Rust开发建议,不仅提供了明确可行的步骤来实现具体目标,还包括了现代应用部署策略。除此之外,作者的写作风格也让这本书非常易于阅读。
张汉东,资深Rust咨询师、《Rust编程之道》作者
市面上不缺讲解Rust语言编程的书,但是介绍如何运用Rust来解决行业问题的书还比较稀缺。在这方面,本书是业界公认的一本好书,非常期待这本书能为Rust语言在中文社区的推广和发展提供价值。
唐刚,Rust语言中文社区联合创始人
本书是Rust后端开发的宝典,融合了Rust的高性能与安全特性,以及现代API服务开发实践。讲解深入浅出,辅以丰富的实例,真正做到了从零构建Rust生产级服务。无论是Rust新手还是经验丰富的开发者,都能从本书中汲取宝贵知识,提升构建高效、可靠后端服务的能力。如果你想学习Rust开发,本书将是你的学习指南。
赵悦,资深Rust开发者
本书系统讲述了目前Rust Web Dev开发方向的生态,也提到了很多Rust风格的编码方式,非常适合在学习完Rust语法之后不知道如何实践的读者阅读。
连修明,资深服务端开发工程师
目录
第1章 准备工作 1
1.1 安装Rust工具链 1
1.1.1 编译目标 1
1.1.2 发布渠道 2
1.1.3 我们需要什么样的工具链 2
1.2 项目初始化 3
1.3 集成开发环境 3
1.3.1 rust-analyzer 4
1.3.2 IntelliJ Rust 4
1.3.3 应该如何选择IDE 4
1.4 内部开发循环 5
1.4.1 更快的链接 5
1.4.2 cargo-watch 6
1.5 持续集成 7
1.5.1 持续集成的步骤 8
1.5.2 准备就绪的持续集成流水线 10
第2章 构建邮件简报 12
2.1 引导示例 12
2.1.1 基于问题的学习 12
2.1.2 帮助完善本书 13
2.2 邮件简报服务应该做什么 13
2.2.1 捕捉需求:用户故事 13
2.3 循序渐进,不断迭代 14
2.3.1 准备开始 15
第3章 注册新的订阅者 16
3.1 前期准备工作 16
3.2 选择一个Web框架 17
3.3 实现第一个端点:健康检查 17
3.3.1 使用actix-web编写代码 18
3.3.2 actix-web应用程序剖析 19
3.3.3 实现健康检查处理器 24
3.4 第一次集成测试 27
3.4.1 如何对端点进行测试 27
3.4.2 应该将测试放在哪里 28
3.4.3 改变项目结构以便于测试 30
3.5 实现第一个集成测试 33
3.5.1 优化 36
3.6 重新聚焦 40
3.7 处理HTML表单 40
3.7.1 提炼需求 40
3.7.2 以测试的形式捕捉需求 41
3.7.3 从POST请求中解析表单数据 44
3.8 存储数据:数据库 52
3.8.1 选择数据库 52
3.8.2 选择数据库包 53
3.8.3 带有副作用的集成测试 55
3.8.4 数据库初始化 56
3.8.5 编写第一个查询 62
3.9 持久化一个新的订阅者 70
3.9.1 actix-web中的应用程序状态 70
3.9.2 actix-web工作进程 72
3.9.3 Data提取器 74
3.9.4 INSERT语句 74
3.10 更新测试 78
3.10.1 测试隔离 81
3.11 总结 85
第4章 遥测 86
4.1 未知的未知 86
4.2 可观测性 87
4.3 日志 88
4.3.1 log包 89
4.3.2 actix-web的Logger中间件 89
4.3.3 外观模式 90
4.4 插桩POST /subscriptions 92
4.4.1 与外部系统的交互 93
4.4.2 像用户一样思考 94
4.4.3 日志应当易于关联 96
4.5 结构化日志 98
4.5.1 tracing包 99
4.5.2 从log迁移到tracing 99
4.5.3 tracing中的跨度 100
4.5.4 插桩future 102
4.5.5 tracing的Subscriber 104
4.5.6 tracing-subscriber 105
4.5.7 tracing-bunyan-formatter 105
4.5.8 tracing-log 107
4.5.9 删除未使用的依赖 109
4.5.10 清理初始化流程 109
4.5.11 集成测试中的日志 112
4.5.12 清理插桩代码――tracing::instrument 116
4.5.13 保护隐私――secrecy 119
4.5.14 请求ID 121
4.5.15 借力tracing生态系统 124
4.6 总结 124
第5章 上线 125
5.1 我们必须讨论部署问题 125
5.2 选择工具 126
5.2.1 虚拟化:Docker 126
5.2.2 托管:DigitalOcean 127
5.3 应用程序的Dockerfile 127
5.3.1 Dockerfile 127
5.3.2 构建上下文 128
5.3.3 sqlx离线模式 129
5.3.4 运行镜像 131
5.3.5 网络 132
5.3.6 层次化配置 133
5.3.7 数据库连接 138
5.3.8 优化Docker镜像 139
5.4 部署到DigitalOcean应用平台 144
5.4.1 安装 144
5.4.2 应用规范 144
5.4.3 如何使用环境变量注入加密信息 147
5.4.4 连接到DigitalOcean的Postgres实例 149
5.4.5 应用配置中的环境变量 152
5.4.6 最后一步,推送 153
第6章 拒绝无效的订阅者(第一部分) 155
6.1 需求 156
6.1.1 姓名约束 156
6.1.2 安全约束 156
6.2 第一次实现 158
6.3 漏洞百出的验证 159
6.4 类型驱动开发 160
6.5 所有权遇见不变量 164
6.5.1 AsRef 167
6.6 panic 169
6.7 Result――将错误作为值 171
6.7.1 使解析函数返回Result类型 171
6.8 精确的断言错误:claim 174
6.9 单元测试 175
6.10 处理 Result 177
6.10.1 match 177
6.10.2 “?”操作符 178
6.10.3 400的请求错误 179
6.11 电子邮件地址格式 179
6.12 SubscriberEmail类型 180
6.12.1 拆分domain子模块 180
6.12.2 新类型的框架 181
6.13 属性测试 184
6.13.1 使用fake生成随机测试数据 184
6.13.2 quickcheck与proptest 185
6.13.3 quickcheck入门 185
6.13.4 实现Arbitrary特质 186
6.14 请求体验证 188
6.14.1 使用TryFrom重构 192
6.15 总结 195
第7章 拒绝无效的订阅者(第二部分) 196
7.1 确认邮件 196
7.1.1 订阅者的同意 196
7.1.2 确认用户的流程 197
7.1.3 实现策略 198
7.2 邮件发送组件――EmailClient 198
7.2.1 如何发送电子邮件 198
7.2.2 如何使用reqwest编写REST客户端 201
7.2.3 如何测试REST客户端 208
7.2.4 EmailClient::send_email的初版实现 213
7.2.5 加强正常的测试 221
7.2.6 处理失败情况 228
7.3 可维护测试套件的骨架和原则 237
7.3.1 为什么要编写测试 238
7.3.2 为什么不编写测试 238
7.3.3 测试代码也是代码 238
7.3.4 测试套件 239
7.3.5 测试发现 240
7.3.6 每个测试文件都是一个包 241
7.3.7 共享测试辅助函数 241
7.3.8 共享启动逻辑 244
7.3.9 构建API客户端 252
7.3.10 小结 256
7.4 重新聚焦 256
7.5 零停机部署 257
7.5.1 可靠性 257
7.5.2 部署策略 258
7.6 数据库迁移 261
7.6.1 状态存在于应用程序之外 261
7.6.2 部署与迁移 261
7.6.3 多步迁移 262
7.6.4 新的必填字段 262
7.6.5 新表 263
7.7 发送确认邮件 264
7.7.1 固定的电子邮件地址 264
7.7.2 固定的确认链接 269
7.7.3 等待确认 272
7.7.4 GET /subscriptions/confirm的骨架 276
7.7.5 整合 278
7.7.6 订阅令牌 287
7.8 数据库事务 294
7.8.1 全部成功,或者全部失败 294
7.8.2 Postgres中的事务 295
7.8.3 sqlx中的事务 295
7.9 总结 299
第8章 错误处理 300
8.1 错误处理的目的 300
8.1.1 系统内部错误 301
8.1.2 系统交互错误 303
8.1.3 小结 305
8.2 为操作人员提供错误报告 305
8.2.1 跟踪错误的根本原因 308
8.2.2 Error特质 313
8.3 控制流与错误处理 316
8.3.1 控制流的分层 316
8.3.2 使用枚举对错误建模 317
8.3.3 只有错误类型还不够 319
8.3.4 使用thiserror减少样板代码 323
8.4 防止“大泥球”型的错误枚举 324
8.4.1 使用anyhow擦除错误类型 329
8.4.2 使用anyhow还是thiserror 331
8.5 错误日志由谁来记 331
8.6 总结 333
第9章 投递邮件简报 334
9.1 用户故事在变化 334
9.2 不要向未确认的订阅者发送 335
9.2.1 使用公共API设置状态 336
9.2.2 scoped mock 337
9.2.3 绿色测试 338
9.3 所有已确认的订阅者都会收到新内容 339
9.3.1 组合测试辅助函数 339
9.4 实现策略 341
9.5 请求体的内容 341
9.5.1 测试无效输入 342
9.6 获取已确认的订阅者列表 344
9.7 发送邮件简报 346
9.7.1 context与with_context 347
9.8 验证存储的数据 348
9.8.1 责任界限 352
9.8.2 关注编译器 353
9.8.3 移除样板代码 355
9.9 简单方法的局限性 356
9.10 总结 357
第10章 API的安全性 358
10.1 认证 358
10.1.1 缺点 359
10.1.2 多因素身份验证 359
10.2 基于密码的身份验证 359
10.2.1 基本身份验证 360
10.2.2 密码验证――简单的方法 365
10.2.3 密码存储 368
10.2.4 不要阻塞异步执行器 384
10.2.5 用户枚举 390
10.3 这安全吗 395
10.3.1 传输层安全性 395
10.3.2 密码重置 395
10.3.3 交互类型 395
10.3.4 机器对机器 396
10.3.5 使用浏览器的用户 396
10.3.6 机器对机器(机器代表人) 397
10.4 插曲:下一步计划 397
10.5 登录表单 398
10.5.1 提供HTML页面 398
10.6 登录 401
10.6.1 HTML表单 401
10.6.2 登录成功后的重定向 404
10.6.3 处理表单数据 405
10.6.4 上下文错误 412
10.7 会话 443
10.7.1 基于会话的身份验证 443
10.7.2 会话存储 444
10.7.3 选择会话存储 444
10.7.4 actix-session 445
10.7.5 管理仪表板 448
10.8 种子用户 459
10.8.1 数据库迁移 459
10.8.2 密码重置 460
10.9 重构 477
10.9.1 如何实现一个actix-web中间件 478
10.10 总结 484
第11章 容错的工作流 486
11.1 重温POST /admin/newsletters 486
11.2 我们的目标 488
11.3 失败模式 488
11.3.1 无效输入 488
11.3.2 网络I/O 489
11.3.3 应用程序崩溃 490
11.3.4 作者的操作 490
11.4 幂等简介 490
11.4.1 幂等实践:支付 491
11.4.2 幂等键 492
11.4.3 并发请求 493
11.5 测试需求(第一部分) 493
11.6 实现策略 495
11.6.1 有状态的幂等:保存和重放 495
11.6.2 无状态的幂等:确定性的键生成 495
11.6.3 时间问题有些棘手 495
11.6.4 做出选择 496
11.7 幂等存储 496
11.7.1 应该使用哪种数据库 496
11.7.2 数据库模式 497
11.8 保存和重放 498
11.8.1 读取幂等键 498
11.8.2 查询已保存的响应 502
11.8.3 保存响应 505
11.9 并发请求 512
11.9.1 测试需求(第二部分) 512
11.9.2 同步 513
11.10 处理错误 520
11.10.1 分布式事务 522
11.10.2 后向恢复 522
11.10.3 前向恢复 523
11.10.4 异步处理 523
11.11 后记 539
前言/序言
这是关于什么的书
后端开发的世界是广阔的。
你所处的环境对于确定解决问题的工具和实践方法有着巨大的影响。例如,基于主干(trunk)的开发方式非常适合编写在云环境中持续部署的软件。但是,对于那些销售本地托管和运行的软件的团队来说,这样的方法可能不太适合他们的商业模式和面临的挑战——他们可能更适合采用Gitflow方法。
而如果是从事独立开发的,则可以直接在main分支上工作。
在软件开发领域,没有绝对的事情,我认为在评估任何技术或方法的利弊时,澄清自己的观点都是有益的。
《从零构建Rust生产级服务》将重点讨论由拥有不同经验和水平的四五名工程师组成的团队在编写云原生应用程序时所面临的挑战。
云原生应用程序
定义云原生应用程序的含义本身就可以写一本书了。我们不规定云原生应用程序应该是什么样子的,而是阐述期望云原生应用程序能做什么。
借用Cornelia Davis的话,我们期望云原生应用程序:
1.—在容易出现故障的环境中实现高可用性;
2.—允许在零停机的情况下持续发布新版本;
3.—处理动态的工作负载(例如请求量)。
这些要求对软件架构的解决方案产生了深远影响。
高可用性意味着即使一台或多台计算机突然发生故障(这在云环境中很常见),我们的应用程序也应该能够在零停机的情况下处理请求。这要求应用程序是分布式的——应该在多台计算机上运行多个实例。
如果希望能够处理动态的工作负载,我们必须能够衡量系统是否处于过载状态,并通过启动新的应用程序实例来提高计算能力。这要求基础设施具有弹性,以避免过度配置和增加成本。
运行应用程序的副本会影响数据持久化的处理方式——我们将避免使用本地文件系统作为持久化解决方案,而是依赖数据库来满足持久化需求。
因此,《从零构建Rust生产级服务》将广泛涵盖那些与后端应用程序开发看似不相关的主题。但是,云原生软件与DevOps和彩虹部署这些概念有关,因此,我们将花费大量时间来讨论与操作系统相关的传统主题。
我们将介绍如何对Rust应用程序进行插桩,收集日志、跟踪信息和指标,以便观测系统。
我们将介绍如何通过迁移来设置和演进数据库模式。
我们将介绍所有必要的材料,以使用Rust来解决云原生API的日常问题。