Distributed systems and cloud computing-Introduction
2026.9.4——by Everfades
总结自课程内容
如果您有宝贵的意见或建议,请发邮件至:everfades1218@gmail.com或everfades@foxmail.com
在使用Typora阅读前,请将文件→偏好设置→Markdown→内联公式 勾选上,以免显示出错!
Lecture 1: Introduction
一个分布式系统是:
- “…一个系统,你甚至不知道它存在的计算机发生故障,就有可能导致你自己的计算机无法使用——Leslie Lamport”
- …多台计算机通过网络进行通信
- …协同完成某项工作
- 由若干节点组成
为什么构建分布式系统?
- 天然的分布式特性(Inherently distributed)
- 为了更高的可靠性(Better reliability)
- 为了更好的性能(Better performance)
- 为了解决更大规模的问题(Solve bigger problems)
为什么不选择构建分布式系统?
The trouble with distributed systems:
- 通信可能会失败
- 进程可能会崩溃/宕机
- 以上问题都可能非确定性发生
容错(Fault tolerance):我们希望即使系统中的某些部分发生 故障,整个系统作为一个整体依然能够正常运行。 与编程单个计算机相比,处理故障使分布式计算从根本上不同, 而且往往更难。
对于分布式系统中两个节点之间的通信,我们做了简易抽象:

但现实要复杂得多:
- 各种网络运营商(蜂窝数据,无线网络,海底电缆,卫星通信)
- 物理交流(火车上配备了无线电,激光设备,还有硬盘驱动器…)
延迟和带宽
延迟:消息到达所需的时间
- 在同一栋建筑/数据中心内:≈1ms
- 从一个大陆到另一个大陆:≈ 100ms
- 卡车拉硬盘:≈ 1day
带宽:单位时间内传输的数据量
- 3G 蜂窝数据:≈ 1 Mbit/s
- 家庭宽带:≈ 10 Mbit/s
- 卡车拉硬盘:50 TB/车厢 ≈ 1Gbit/s
以上数值仅供参考,与实际会有很大差异。
Client-Server 架构
Client-Server 架构,简称为CS架构(显然不是Counter-Strike),即客户端-服务器架构

简单来说,其涉及两个因素:
- 服务器就是提供所请求服务的实体
- 客户就是那些提出服务需求的人
常见分布式系统架构对比:
| 客户端-服务端架构(Client-Server) | 对等网络架构(Peer-to-Peer,P2P) | 混合架构(Hybrid / Broker-based) | |
|---|---|---|---|
| 节点角色 | 严格非对等(Client 请求,Server 响应) | 完全对等(每个节点既是客户端也是服务端) | 分工混合(存在中心调节点,节点间可直连) |
| 通信角色 | Request-Response(请求-响应机制) | Gossip / 泛洪 / DHT 路由 | 发布-订阅(Pub-Sub) / 事件驱动 |
| 扩展性与瓶颈 | 受限(Server 易成为算例与带宽瓶颈) | 极高(节点加入同时贡献算力与带宽) | 良好(通过消息中间件 / 集群水平扩展) |
| 单点故障(SPOF) | 存在(Server 宕机导致不可用) | 无(单节点推出不影响全网) | 取决于协调中心(依赖主从冗余保障) |
| 一致性管理 | 简单(Server 作为中心真相源) | 极复杂(依赖最终一直性或去中心化共识) | 中等(依赖消息队列保证局部有序) |
| 典型代表 | Web(HTTP/REST),微服务 RPC,RDBMS | BitTorrent,区块链(Bitcoin),IPFS | Kafka,MQTT 物联网,即时通讯系统 |
CS架构示例:在线支付

远程过程调用(RPC-Remote Procedure Call)代码示例
// Online shop handing customer's card details
Card card = new card();
card.setCardNumber("1234 5678 8765 4321");
card.setexpiryDate("10/2024");
card.setCVC("123");
Result result =
paymentsService.processPayment(card, 3.99, Currency.GBP);
/*↑↑↑ Implementation of this function is on another node ↑↑↑*/
if(result.isSuccess()){
fulfilOrder();
}
/*
实现 RPC 的软件被称为RPC 框架或者中间件。
(并非所有中间件都基于 RPC;也存在使用其他通信模型的中间件。)
*/
远程过程调用-RPC(Remote Procedure Call)
RPC特性
基本特性:
- 被调用的程序位于另一个进程中,而那个进程很可能运行在另一台机器上。
- 这些进程不共享地址空间。
- 参数仅以值的形式传递。
- RPC在服务器进程的环境中执行。
- 它无法访问调用过程的环境。
重要特性:
- 语法调用简单
- 提供已知的语义信息
- 提供一个定义明确的接口
- 可以在同一台机器或不同机器上的进程之间进行通信
RPC工作流程

$m_1=$
{
"request":"processPayment",
"card":{
"number":"1234567887654321",
"expiryDate":"10/2024",
"CVC":"123"
},
"amount":3.99,
"currency":"GBP"
}
$m_2=$
{
"result":"success",
"id":"XP61hWw2Rvo"
}
RPC架构组成
RPC架构主要由五个部分组成:
- 客户 (Client)
- 客户端stub
- RPC运行时环境(RPC Runtime)
- 服务器Stub
- 服务器(Server)
在RPC中,stub作为客户端和服务器之间的桥梁,它在客户端看起来像本地对象,但实际上封装了底层的网络通信逻辑,从而隐藏了复杂性。

RPC常见调用类型
1.同步RPC(Synchronous RPC)
客户端发出请求后阻塞等待,直到拿到服务段响应。
- 特点:逻辑直观简单,但存在等待阻塞开销。
- 场景:适用于需要立即确认结果的业务。
2.异步RPC(Asynchronous RPC)
客户端发送请求后直接继续执行,无需原地等待。
- 特点:实现复杂度稍高,但能显著提升系统相应与并发能力。
- 场景:适用于高并发场景及并发编程应用。
3.单向RPC(One-Way RPC)
客户端只负责发送请求,不等待也不接受任何返回结果。
- 特点:“即发即弃”(Fire-and-forget)模式,开销最小,延迟极低。
- 场景:常用于日志收集与消息通知服务。
4.回调RPC(Callback RPC)
服务端处理完成后,主动调用客户端提供的回调函数。
- 特点:非阻塞通信(时间解耦),避免客户端长时间挂起。
- 场景:适用于耗时较长的后台任务处理。
5.批处理RPC(Batch RPC)
客户端将多个请求打包成一个批次一次性发送。
- 特点:显著减少网络往返(RTT)与通信开销,提升吞吐量。
- 场景:适用于高频词,非即时的大量数据更新。
RPC vs LPC
- 地址空间隔离:本地调用共享进程内存;RPC跨物理节点通信,依赖参数序列化(Marshalling)与信息传递。
- 故障模式复杂(Higher Failure Proneness):本地调用具有确定性;RPC面临网络中断,节点宕机等部分失效(Partial Failure)且故障难以确诊。
- 通信延迟显著(Higher Latency):RPc受制于物理网络传输与协议封栈包,比本地过程调用花费更长的时间。
RPC的位置透明性
在理想情况下,RPC对远程函数的调用看起来就像是对本地函数的调用一样
位置透明性(Location transparency)——系统隐藏了资源所在的位置,使远程调用在语法和形式上与本地调用保持一致
RPC原则
如今,最常见的RPC实现方式是通过HTTP传输的JSON数据。
针对这类基于 HTTP 的 API,一套广为流行的设计原则叫做表述性状态转移(Representational State Transfer),简称 REST;遵循这套原则的 API 就被称为 RESTful(符合 REST 风格的)API。
这些原则包括:
- 通信无状态(每个请求都是自包含的,与其他请求相互独立);
- 资源(可以查看、操作的对象)由 URL 进行标识;
- 通过向对应 URL 发送携带标准方法类型(例如 POST、PUT)的 HTTP 请求,来更新资源的状态。
JS中的RPC/REST架构
let args = {amount: 3.99, currency: 'GBP',
/*...*/ };
let request = {
method: 'POST',
body: JSON.stringify(args),
headers: {'Content-Type': 'application/json'}
};
fetch('https://example.com/payments', request)
.then((response) => {
if (response.ok) success(response.json());
else failure(response.status); // server
error
})
.catch((error) => {
failure(error); // network error
});
grpc IDL example
message PaymentRequest {
message Card {
required string cardNumber = 1;
optional int32 expiryMonth = 2;
optional int32 expiryYear = 3;
optional int32 CVC = 4;
}
enum Currency { GBP = 1; USD = 2; }
required Card card = 1;
required int64 amount = 2;
required Currency currency = 3;
}
message PaymentStatus {
required bool success = 1;
optional string errorMessage = 2;
}
service PaymentService {
rpc ProcessPayment(PaymentRequest) returns (PaymentStatus) {}
}
RPC History
- SunRPC/ONC RPC(1980s, basis for NFS)
- COBRA:object -oriented middleware ,hot in the 1990s
- Mirosoft’s DCOM and Java RMI(Similar to COBRA)
- SOAP/XML-RPC:RPC using XML and HTTP(1998)
- Thrift(Facebook,2007)
- gRPC(Google,2015)
- REST(often with JSON)
- Ajax in web brosers


