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

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

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

通信的角色

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

  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.mzph.cn/news/578092.shtml

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

相关文章

Java---IO流讲解(2)

文章目录 1. 字符流1.1 为什么出现字符流1.2 字符流写数据的5种方式1.3 字符流读数据的两种方式1.4 字符缓冲流1.5 字符缓冲流特有功能 2. IO流小结2.1 字节流2.2 字符流 1. 字符流 1.1 为什么出现字符流 由于字节流操作中文时不是特别方便&#xff0c;因此Java提供了字符流。…

SpringBoot - Maven 打包合并一个胖 JAR 以及主项目 JAR 依赖 JAR 分离打包解决方案

问题描述 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><!--<classifier>exec</classifier>--…

12.25广义分布外检测学习/代码复现

A model.getA().toarray() # b np.array(model.RHS) sense np.array(model.sense) f np.array(model.obj)Aineq np.vstack((-Ale, Age)) # 把所有的<和>组合在一起 bineq np.append(-ble, bge) # 这里用append使bineq为一个一维矩阵&#xff0c;而不是2行1列的二…

SpringBoot 3.2.0 基于Spring Security+JWT实现动态鉴权

依赖版本 JDK 17 Spring Boot 3.2.0 Spring Security 6.2.0 工程源码&#xff1a;Gitee 为了能够不需要额外配置就能启动项目&#xff0c;看到配置效果。用例采用模拟数据&#xff0c;可自行修改为对应的ORM操作 编写Spring Security基础配置 导入依赖 <properties>&l…

java练习之abstract (抽象) final(最终) static(静态) 练习

1&#xff1a;分析总结&#xff1a;写出private、abstract、static、final之间能否联动使用&#xff0c;并写出分析原因 private static final 之间可以任意结合 abstract 不可以与private static final 结合使用 2&#xff1a;关于三个修饰符描述不正确的是(AD) A. static …

Linux操作系统基础知识点

Linux是一种计算机操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年首次发布。Linux操作系统通常与GNU套件一起使用&#xff0c;因此也被称为GNU/Linux。它是一种类UNIX的操作系统&#xff0c;设计为多用户、多任务…

计算机组成原理综合6

补码表示&#xff1a; X&#xff1a;1111 1111 1111 1101 Y&#xff1a;1111 1111 1101 1111 Z&#xff1a;0111 1111 1111 1100 转原码表示&#xff1a;从右往左找第一个“1”&#xff0c;左边的所有数值位按位取反 X&#xff1a;1111 1111 1111 1101 1000 0000 00…

OGG-MySQL无法正常同步数据问题分析

问题背景: 用户通过OGG从源端一个MySQL从库将数据同步到目标端的另一个MySQL数据库里面&#xff0c;后面由于源端的从库出现了长时间的同步延时&#xff0c;由于延时差距过大最后选择通过重建从库方式进行了修复 从库重建之后&#xff0c;源端的OGG出现了报错ERROR OGG-0014…

关于Sneaky DogeRAT特洛伊木马病毒网络攻击的动态情报

一、基本内容 作为复杂恶意软件活动的一部分&#xff0c;一种名为DogeRAT的新开源远程访问特洛伊木马&#xff08;RAT&#xff09;主要针对位于印度的安卓用户发动了网络安全攻击。该恶意软件通过分享Opera Mini、OpenAI ChatGOT以及YouTube、Netfilx和Instagram的高级版本等合…

《PySpark大数据分析实战》-19.NumPy介绍ndarray介绍

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

饥荒Mod 开发(二三):显示物品栏详细信息

饥荒Mod 开发(二二)&#xff1a;显示物品信息 源码 前一篇介绍了如何获取 鼠标悬浮物品的信息&#xff0c;这一片介绍如何获取 物品栏的详细信息。 拦截 inventorybar 和 itemtile等设置字符串方法 在modmain.lua 文件中放入下面代码即可实现鼠标悬浮到 物品栏显示物品详细信…

适合引流源码声音鉴定神器网站源码,轻松吸引用户关注

源码介绍 声鉴卡HTML5网页源码&#xff0c;完整可运转&#xff0c;调用wx录音&#xff0c;自动判断声音属性&#xff0c;输出结果 安装教程 只需要把源码上传至主机空间就可以 支持上传二级目录访问&#xff01;提示一下&#xff1a;wxvx打开效果是最佳的源码里面生成二维码…

测试服务器带宽(ubuntu)

apt install python3 python3-pippip3 install speedtest-clispeestest-cli

Hive05_DML 操作

1 DML 数据操作 1.1 数据导入 1.1.1 向表中装载数据&#xff08;Load&#xff09; 1&#xff09;语法 hive> load data [local] inpath 数据的 path [overwrite] into table student [partition (partcol1val1,…)];&#xff08;1&#xff09;load data:表示加载数据 &…

Redis数据结构(常用5+4种特殊数据类型)

1、Redis 数据类型以及使用场景分别是什么&#xff1f; Redis 提供了丰富的数据类型&#xff0c;常见的有五种数据类型&#xff1a;String&#xff08;字符串&#xff09;&#xff0c;Hash&#xff08;哈希&#xff09;&#xff0c;List&#xff08;列表&#xff09;&#xff…

119. 杨辉三角 II(Java)

给定一个非负索引 rowIndex&#xff0c;返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: rowIndex 3 输出: [1,3,3,1]示例 2: 输入: rowIndex 0 输出: [1]示例 3: 输入: rowIndex 1 输出: [1,1]提示…

通过自然语言处理增强推荐系统:协同方法

一、介绍 自然语言处理 (NLP) 是人工智能的一个分支&#xff0c;专注于使机器能够以有意义且有用的方式理解、解释和响应人类语言。它包含一系列技术&#xff0c;包括情感分析、语言翻译和聊天机器人。 另一方面&#xff0c;推荐系统&#xff08;RecSys&#xff09;是旨在向用户…

Android笔记(二十一):Room组件实现Android应用的持久化处理

一、Room组件概述 Room是Android JetPack架构组件之一&#xff0c;是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层&#xff0c;使之实现数据访问。 &#xff08;1&#xff09;实体类&#xff08;Entity&#xff09;&#xff1a;映射并封装了数据库对应的数据表中…

彻底卸载Keil4

彻底卸载Keil4 双击 然后回到该软件的文件夹位置&#xff0c;把该文件夹删除即可&#xff0c;然后清一下回收站。

【Midjourney】Midjourney提示词格式详解

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;Midjourney提示词格式 &#x1f341; 1.模型版本提示词&#x1f341; 参数 参数详解 应用示例 &#x1f343; 2.风格…