分布式系统架构设计之分布式通信机制

二、分布式通信机制:保障系统正常运行基石

在分布式系统中,各个组件之间的通信是保障系统正常运行的基石,直接影响到系统的性能、可扩展性以及整体的可维护性。接下来我们就一起看看通信在分布式系统中的重要性,以及一些常用的技术实现方案。

通信的角色

在分布式系统中,通信扮演着连接各个节点的纽带,保障节点之间能够有效传递信息,关键角色主要包括:

  1. 节点之间的通信:分布式系统的核心在于多个节点之间的协同工作,节点通信是实现这一目标的基础
  2. 跨网络的通信:分布式系统通常部署在不同地理位置的服务器上,因此跨网络通信需要关注效率和安全性
  3. 异步通信:通过异步通信,系统能够更好地处理大量请求,提高整体性能和响应速度

通信的重要性

  1. 节点协同:分布式系统的核心在于多个节点之间的协同工作,而节点之间的协同离不开高效的通信机制
  2. 系统整合:一个分布式系统通常由多个独立的服务组成,它们需要相互通信以完成整体业务流程
  3. 性能优化:良好的通信机制可以优化系统性能,提高各节点之间的信息传递效率

常用通信实现技术方案

为了实现高效的通信,不同的技术和协议被开发出来以满足各种场景和需求。以下关于分布式系统中通信的一些技术实现、优缺点以及常用的技术框架或组件进行一个总结介绍:

同步通信场景

同步通信是一种阻塞式通信方式,发送方在等待接收方的确认之前不会进行其他操作,这种方式确保了数据的可靠性。

优点
  • 数据完整性:每个消息都会得到确认
  • 简单易用:编程模型相对简单
缺点
  • 性能:由于需要等待确认,可能影响系统的整体性能
  • 延迟:如果网络延迟较高,可能会导致请求响应时间增加
常用技术框架/组件

RPC(Remote Procedure Call) 框架,现今 RPC 框架可谓是百花齐放,比如 gRPC、Dubbo、Thrift 等,后面我有一个专门讲 RPC 的主题,可以期待一下。

异步通信场景

异步通信是非阻塞式的,发送方在发送消息后不需要等待接收方的确认就可以继续执行其他操作,这种模式通常使用消息队列来传递消息。

优点
  • 高性能:允许你系统在不等待回应的情况下处理更多任务
  • 解耦:发送者和接收者之间解耦,提高了系统的灵活性和可扩展性
缺点
  • 复杂性:相比同步通信,异步通信的编程模型更复杂
  • 可靠性:如果不采取额外措施,可能会丢失数据
常用技术框架/组件

消息队列,如 Apache Kafka、RabbitMQ、RocketMQ 等,后面我也有一个专门讲消息队列的主题,继续期待。

单播通信场景

单播通信是点对点的通信方式,一个节点向另一个特定的节点发送消息。

优点
  • 易于理解和实现
  • 资源利用效率高,因为只有一条路径进行传输
缺点
  • 如果目标节点不可达,可能导致消息丢失

广播通信场景

广播通信是一种一对多的通信方式,一个节点向所有其他节点发送相同的消息。

优点
  • 在需要通知多个节点时非常有用
缺点
  • 网络带宽消耗大,特别是当网络中有大量节点时

组播通信场景

组播通信介于单播和广播之间,一个节点向一组特定的节点发送消息。

优点
  • 与广播相比,减少了不必要的资源消耗
  • 适用于需要同时通知多个节点但不是全部节点的情况
缺点
  • 实现起来较为复杂,需要网络支持组播功能
常用技术框架/组件

组播库,如 Java 的 MulticastSocket 类。

流通信场景

流通信是一种持续的数据交换方式,适合传输大量数据或实时媒体内容。

优点
  • 支持大数据量传输
  • 实时性强,适合音视频等流媒体应用
缺点
  • 对网络稳定性要求较高
常用技术框架/组件

RTMP(Real-Time Messaging Protocol)、WebRTC(Web Real-Time Communication)等流媒体传输协议

通过选择适用于具体场景的通信技术,可以有效提高分布式系统的整体性能和可维护性。在实际应用中,通过需要根据系统的需求、架构的特点以及团队技术栈的熟悉程序来综合考虑选择最合适的通信方式。

问题解答

为什么单播通信场景和广播通信场景没有常用的技术框架/组件?

对于单播通信场景和广播通信场景,尽管是网络通信的基本场景,但是在分布式系统中,通常不会直接使用特定的框架/组件来实现这些通信场景,而是通过更高级别的抽象来完成,比如编程语言提供的网络库、操作系统提供的套接字 API、其他中间件等。

在使用 TCP/IP 协议时,无论是单播还是广播通信,都是通过 Socket API 来实现,可以配置目的 IP 地址和端口号来决定是发送到单个目标还是广播到所有接受者。

在有些情况下,一些中间件或技术可能会提供对单播和广播的支持,但他们通常不是专门为了实现这两种通信模式而设计的,比如一些网络库,像BSD Sockets(C/C++)、Java 的 java.net.Socket 类、Python 的 socket 模块等。

从上面介绍的通信场景中为什么没有 WebSocket 呢?

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许客户端和服务器之间建立持久性的连接,以便进行双向通信。WebSocket 协议通过一个握手过程开始,在这个过程中,客户端和服务器交换 HTTP 请求和响应来升级连接到 WebSocket。

从通信模式的角度看,WebSocket 可以被视为一种异步、双向的消息传递机制。然而,由于它是基于单一的长连接,它既不是传统的单播也不是广播,而是提供了一种更高级别的抽象,使得开发人员可以方便地实现各种通信模式。

通过使用 WebSocket,你可以很容易地实现:

  • 单播通信:向特定的目标节点发送消息
  • 广播通信:将消息发送给所有连接到同一 WebSocket 服务器的客户端
  • 组播通信:通过在服务器端进行逻辑处理,实现类似于组播的功能,如向一组具有特定属性或订阅了特定主题的客户端发送消息

因此,WebSocket 不属于上述的任何一种方式,而是一种能够支持多种通信模式的技术。

WebSocket 适用与实时性要求高、频繁通信的场景,比如在线聊天、实时监控等,不过相对于 HTTP,它引入了更多的开销,适用场景相对有限。

从上面介绍的通信场景中为什么没有 HTTP/RESTful 呢?

HTTP/RESTful 不完全属于上述的任何一种通信模式。它是一种应用层协议,通常用于在分布式系统中实现客户端与服务器之间的交互。而上面提到的单播、广播和组播是网络层或传输层的概念,它们描述的是数据在网络中的传输方式。

HTTP/RESTful 更多地关注于如何设计和使用 HTTP 协议来实现资源导向的架构风格(即 REST,Representational State Transfer)。RESTful API 是基于 HTTP 协议,通过使用不同的 HTTP 方法(如 GET、POST、PUT、DELETE 等)来操作资源,从而提供了一种标准的方式来访问和修改远程服务的状态。

从某种程度上讲,HTTP/RESTful 可以视为一种异步通信方式,因为客户端发送请求后不需要等待服务器响应就可以继续执行其他任务。然而,这并不意味着 HTTP/RESTful 就等同于异步通信。实际上,根据具体的应用场景和编程模型,HTTP/RESTful 也可以被用来实现同步通信。

总之,HTTP/RESTful 是一种用于构建分布式系统中客户端-服务器通信的技术,它可以支持多种通信模式,包括但不限于异步通信。

补充知识点:同步、异步、阻塞和非阻塞

在实际编程中,同步、异步、阻塞和非阻塞这是四个非常关键的概念,涉及到程序执行的并发性和数据一致性。专门补充介绍以下相关的概念和要求。

同步(Synchronous)

通常是指在执行一个操作时,调用者需要等待该操作完成才能继续执行后续的代码。例如,在Java中,当你调用一个方法并期望立即得到结果时,这就是同步行为。同步确保了操作的顺序性,并且可以避免竞态条件。

public int sum(int a, int b) {return a + b;
}int result = sum(10, 20);
异步(Asynchronous)

意味着调用者不需要等待操作完成就可以继续执行其他任务。在异步编程中,当一个操作开始时,控制权立刻返回给调用者,而实际的操作会在后台线程中进行。异步操作完成后,通常会通过回调函数或 Future 对象通知调用者。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {Thre`ad.sleep(1000);return 42;
});// 异步操作开始后,可以做其他事情
System.out.println("Doing other things...");// 当需要结果时,可以检查是否已经完成
Integer result = future.get(); // 如果尚未完成,这将阻塞直到结果可用
阻塞(Blocking)

是指在执行某个操作时,线程会被挂起,直到满足特定条件或操作完成为止。在Java中,许多I/O操作(如文件读写、网络通信等)默认是阻塞的,这意味着如果资源未准备好,调用线程将会被挂起,直到资源就绪。

InputStream is = new FileInputStream("file.txt");
byte[] buffer = new byte[1024];
int bytesRead = is.read(buffer); // 这个调用可能会阻塞,直到从文件中读取到数据
非阻塞(Non-Blocking)

指在执行操作时,即使资源尚未准备就绪,也不会导致线程被挂起。相反,非阻塞操作会立即返回一个状态,告诉调用者当前资源的状态(如“已就绪”、“正在进行”或“错误”)。非阻塞操作通常结合轮询或事件通知机制来实现。

在Java NIO(非阻塞I/O)中,提供了非阻塞的I/O通道,可以通过轮询的方式来检查数据是否可用。

Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", 8080));
channel.configureBlocking(false);channel.register(selector, SelectionKey.OP_READ);while (true) {if (selector.select() > 0) { // 这是非阻塞调用,如果没有可读的数据,将立即返回Iterator<SelectionKey> keys = selector.selectedKeys().iterator();while (keys.hasNext()) {SelectionKey key = keys.next();if (key.isReadable()) {ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = ((SocketChannel) key.channel()).read(buffer);// 处理读取到的数据...}keys.remove();}}
}

同步和异步关注的是调用者与被调用者之间的协作模式,阻塞和非阻塞关注的是线程在执行过程中是否会被暂停。两者之间是可以相互组合,以实现不同的并发编程模式,常见组合说明如下:

同步阻塞(Synchronous Blocking)

这是最常见的编程模型,调用者需要等待操作完成,并且在等待期间线程会被阻塞。

同步非阻塞(Synchronous Non-Blocking)

在这种情况下,调用者仍然需要等待操作完成,但不会阻塞线程。通常通过轮询或事件通知机制来检测操作是否完成。

异步阻塞(Asynchronous Blocking)

这种组合比较少见,因为异步操作的目的通常是避免阻塞。然而,在某些特定场景下,如等待异步操作的结果时,可能会发生阻塞。

异步非阻塞(Asynchronous Non-Blocking)

这是现代高并发系统中最常用的编程模型。调用者不需要等待操作完成,并且在等待期间不会阻塞线程。

理解这些概念及其组合可以帮助你更好地设计并发和分布式系统的代码。在实际应用中,根据性能、资源利用率和响应时间等需求,选择合适的编程模型至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/300910.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

北科智慧智能手提箱旗舰版惊艳亮相2023(香港)智能科技展

2023年12月8日&#xff0c;北科智慧团队在粤港澳大湾区创新发展峰会暨侨交会2023&#xff08;香港&#xff09;智能科技展上举办新品发布&#xff0c;推出三款自主研发科技产品&#xff1a;智能手提箱高级版和旗舰版&#xff0c;以及智能呈批夹。新品一经推出&#xff0c;便受到…

Java并发(二十一)----wait notify介绍

1、小故事 - 为什么需要 wait 由于条件不满足&#xff08;没烟干不了活啊&#xff0c;等小M把烟送过来&#xff09;&#xff0c;小南不能继续进行计算 但小南如果一直占用着锁&#xff0c;其它人就得一直阻塞&#xff0c;效率太低 于是老王单开了一间休息室&#xff08;调…

掌握JWT:解密身份验证和授权的关键技术

JSON Web Token 1、什么是JWT2、JWT解决了什么问题3、早期的SSO认证4、JWT认证5、JWT优势6、JWT结构Header 标头Payload 负载 Signature 签名 7、代码实现添加依赖生成Token认证token 8、工具类9、JWT整合Web10、拦截器校验11、网关路由校验12、解决多用户登录的问题13、客户端…

HTTP content-type内容类型的常见格式

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

C# ASP.NET 实验室 检验中心 医疗LIS源码

LIS系统能够自动处理大量的医学数据&#xff0c;包括样本采集、样本处理、检测分析、报告生成等。它能够快速、准确地进行化验检测&#xff0c;提高医院的运营效率。LIS系统还提供了丰富的数据分析功能&#xff0c;能够对医院化验室的业务流程进行全面、细致的监控。 LIS系统优…

windows搭建MySQL 8.25主从配置

1.本次搭建的版本 mysql-8.0.25-win-x64 2.在解压完成后的文件内并没有对应的my.ini的配置文件这个my.ini是需要的主配置文件需要自行创建。 注&#xff1a;安装路径及数据存放路径需根据实际安装情况进行修改&#xff08;其它配置信息可结合实际情况进行修改&#xff09; 3.在…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Progress进度条组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Progress进度条组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Progress组件 进度条也是UI开发最常用的组件之一&#xff0c;进度条组件…

python区块链简单模拟【05】

新增内容&#xff1a;构建去中心化网络 import socket #套接字&#xff0c;利用三元组【ip地址&#xff0c;协议&#xff0c;端口】可以进行网络间通信 import threading #线程 import pickle# 定义一个全局列表保存所有节点 NODE_LIST []class Node(threading.Thread…

【Spring实战】05 CommandLineRunner

文章目录 1. 简介2. 用法1&#xff09;单个 CommandLineRunner2&#xff09;多个 CommandLineRunner 3. 优点4. 缺点总结 CommandLineRunner 是 Spring Boot 提供的一个接口&#xff0c;用于在 Spring Boot 应用程序启动后执行一些任务。通过实现 CommandLineRunner 接口&#…

目标追踪:使用ByteTrack进行目标检测和跟踪

BYTE算法是一种简单而有效的关联方法&#xff0c;通过关联几乎每个检测框而不仅仅是高分的检测框来跟踪对象。这篇博客的目标是介绍ByteTrack以及多目标跟踪&#xff08;MOT&#xff09;的技术。我们还将介绍在样本视频上使用ByteTrack跟踪运行YOLOv8目标检测。 多目标跟踪&…

【数据结构和算法】找到最高海拔

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列…

2015年第四届数学建模国际赛小美赛C题科学能解决恐怖主义吗解题全过程文档及程序

2015年第四届数学建模国际赛小美赛 C题 科学能解决恐怖主义吗 原题再现&#xff1a; 为什么人们转向恐怖主义&#xff0c;特别是自杀性恐怖主义&#xff1f;主要原因是什么&#xff1f;这通常是大问题和小问题的结合&#xff0c;或者是一些人所说的“推拉”因素。更大的问题包…