【小也的Java之旅系列】02 分布式集群详解

news2025/4/3 2:38:26

文章目录

  • 前言
    • 为什么叫小也
  • 本系列适合什么样的人阅读
  • 正文
  • 单体
    • 优点
    • 缺点
  • CAP
    • 为什么CAP不可能全部满足?
    • CAP 三选二
  • 分布式事务
  • 分布式方案——Seata
    • XA模式(强一致)
    • AT模式(自动补偿,默认模式)
    • TCC模式(手动补偿)
    • Saga模式(长事务)
    • 四种模式的区别
  • 分布式锁
    • ZooKeeper 实现分布式锁
    • Redis 实现分布式锁
    • 区别
  • 总结

前言

做Java开发多年,一直以来都有想把Java做成一个系列的想法,最近整理自己的笔记发现有很多值得写的内容,但这些内容又往往杂乱不堪。CSDN上有很多高质量的Java博客,但大多不是从一个人成长的角度去写的。而我们——一个技术人员——一个人,是在不断的学习中成长的,这样的过程如果能体现在系列博客中那真的就太好了。于是,终于下定决心,想花一段时间整理成册——或许是几个月,或许是半年,或许是一年不止。希望自己能坚持下去。

为什么叫小也

孩子是我们之所以还努力的原因。

本系列适合什么样的人阅读

阅读本文最好有一定基础,最优人群是:

  1. 了解Java的基础语法
  2. 自己本身已经写过代码
  3. 对Java架构、大数据、轻代码等进阶有兴趣

如果你是个初出茅庐的初学者,对Java技术内容都不甚了解,也不用特别担心,我的另外一个系列你肯定感兴趣——《Java8系列博文合集》(或者访问我的博客园也可以阅读)。

正文

上一章内容大体描述了什么是分布式,以及分布式和微服务等架构的关系。接下来,我们要详细讨论分布式,以及如何在实战实战中使用。

上一章里,小也使用分布式思路帮助叔叔解决了厨房出餐效率的问题。那么,到底什么是分布式?

如果用一句话描述分布式:
将系统别发在不同的服务器,就是分布式。

分布式不是一种特指的代码架构,更多的是一种解决问题的方法。比如:我们可以说微服务就使用了分布式的思路,但微服务≠分布式。

在实战中,分布式更强调部署方式,而不是开发。

单体

在这里插入图片描述
同样以厨房为例:厨师=软件程序,工作台=服务器硬件。
单个软件运行在单个服务器上,就是单体系统。

在以往,最初的系统结构较为简单时,大多都是单体系统。

优点

  1. ​开发简单,代码集中管理
  2. ​部署便捷,运维成本低
  3. ​测试直观,集成测试无需模拟外部服务

缺点

  1. ​扩展性差,只能整体扩容,无法按需伸缩
  2. ​复杂性高,代码臃肿,依赖关系复杂
  3. ​技术更新难,升级技术栈需全局重构
  4. ​故障隔离差,单点故障可能影响全局

随着社会发展,程序逻辑越来越复杂,单体系统劣势越来越明显,高并发、高可用的呼声越来越大了。在这种情况下,必须出现一种模式解决单体系统的问题。

CAP

CAP 定理(Consistency, Availability, Partition Tolerance)是分布式系统中的一个基本理论,指出在一个分布式系统中,不可能同时满足以下三个特性:

  • 一致性(Consistency, C):所有节点访问同一份最新的数据副本。
  • 可用性(Availability, A):所有的请求都能收到一个响应,无论数据是否是最新的。
  • 分区容忍性(Partition Tolerance, P):系统能够继续运行,即使部分节点之间的通信失败。

为什么CAP不可能全部满足?

回到小也遇到的厨房问题。
厨房最开始只有一位厨师+一个工作台,当出现任何问题,如:工作台损坏或厨师生病,就会导致不能出餐。

小也开始思考这些问题,得出了一系列结论,如果要让饭店良好的运转,应该满足以下要求:

  • 一致性:不管是哪位厨师做餐,只要是同一个菜品,厨师出的餐就应该是一样的
  • 可用性:不管是何时何地点餐,厨师都应该及时做出指定的菜品。
  • 分区容忍性:不管遇到任何问题,哪怕是某位厨师生病或工作台损坏,都不影响出餐。
    在这里插入图片描述
    在这里插入图片描述

但在实际操作中,小也很快发现了新问题:
一致性与可用性冲突:有一天,三位厨师正在为一桌客人做菜,做了一半时,客人告诉A厨师她不吃葱姜蒜,这时服务员也同时来取餐。A厨师立马停下了加葱姜蒜的手,但还没来得及告诉其他两位厨师,他们的菜已经做好(有葱姜蒜)。如果从一致性角度,厨师出的餐必须符合一致要求——A厨师应该立即告诉其他厨师去掉葱姜蒜重新做——再出餐。但从可用性角度,这时候服务员已经来取餐,不能让客人获取不到。

​假设: 存在一个分布式系统同时满足C、A、P
​当网络分区发生时:
根据A(可用性),系统必须响应所有请求
根据C(一致性),所有节点数据必须同步更新
但分区导致节点间无法实时通信,无法完成同步
​结论:假设不成立,三者无法共存

CAP 三选二

根据CAP定理,分布式系统只能在以下三种方案中选择两者:

  1. CP(Consistency + Partition Tolerance):保证数据一致性,即使某些节点发生分区故障,系统可能无法响应部分请求。例如:HBase、MongoDB(某些模式)。
  2. AP(Availability + Partition Tolerance):保证系统高可用性,即使发生分区,数据可能是不一致的。例如:Cassandra、DynamoDB。
  3. CA(Consistency + Availability):只在没有网络分区时成立,通常单机数据库(如传统的关系型数据库)可以满足。

在这里插入图片描述

如果选择:

  • CA:就是单体服务,因为没有分区,程序只在一个服务器运行,自然也能保证一致性和可用性。
  • CP:使用通信让不同分区间的程序数据保持一致,如:数据库主从,使用加锁方式强制保持一致。但这样就丧失了实时性。
  • AP:高并发模式下的系统可以同时允许多人访问,如:12306购票,可以使用缓存技术及时响应用户,但这样就丧失了一致性,导致在出票环节显示无票(痛苦的回忆 TT)。

分布式事务

分布式一旦成型后,还面临一个普遍的问题:任何关键流程一旦分布在不同服务器,就必须保证其所有环节的一致性。

以上文提到的12306购票为例:

提交订单→跳转第三方程序付款→确认付款成功→出票

假设这些程序分布在不同服务器,无论哪个程序出错都将导致订票失败。反过来讲,其中任何一个环节出错都应该终止订票。

分布式事务就是创造一个程序作为监视者,监控流程中的程序,当这些程序出现错误时,将整个订票流程回滚。

分布式方案——Seata

有了以上的理论基础,小也在面对分布式“炒菜”问题时,也有了结论:
如果能有一个人——比如饭店老板——专门控制菜品要求,让客人的需求及时反馈到厨房,同时让厨师按照要求做菜,这样就不会出现菜品不一致的问题。

Seata​(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的分布式事务解决方案,提供AT、TCC、Saga 和 ​XA 四种事务模式,支持跨数据库、跨服务的分布式事务管理。

术语说明
​TCTransaction Coordinator(事务协调器):全局事务的调度者(独立部署)
​TMTransaction Manager(事务管理器):定义全局事务边界(@GlobalTransactional)
​RMResource Manager(资源管理器):管理分支事务的资源(如数据库连接)

TC:饭店老板,在饭店里协调客人完成点餐→出餐→吃饭→结账
TM:服务员,负责接待客人,确认其需求并报告给老板协调
RM:厨师,为每个客人出餐

XA模式(强一致)

在这里插入图片描述

原理:基于数据库XA协议的两阶段提交
适用场景:传统数据库跨库事务(如银行核心系统)

流程:

  1. TM首先向TC注册
  2. TM分别调用RM
  3. RM各自向TC注册
  4. RM各自执行操作并向TC汇报状态(正常或异常)
  5. TM从TC处获取各RM执行情况,并向TC提出提交/回滚
  6. TC要求所有RM执行统一操作:提交/回滚

AT模式(自动补偿,默认模式)

原理:通过代理数据源拦截SQL,生成逆向SQL实现回滚
适用场景:跨数据库事务(如MySQL、Oracle)

在这里插入图片描述
流程:

  1. TM首先向TC注册
  2. TM分别调用RM
  3. RM各自向TC注册
  4. RM各自执行操作并直接提交(commit),将操作记录到undolog表,之后向TC汇报状态(正常或异常)
  5. TM从TC处获取各RM执行情况,并向TC提出提交/回滚
  6. TC要求所有RM执行统一操作:如果是提交则保留RM各自的执行结果,如果是回滚则根据undolog的内容进行反向恢复操作

一句话总结:AT是先执行错了都再改回去,XA是必须保证都对再执行。

TCC模式(手动补偿)

原理:通过 Try-Confirm-Cancel 三阶段实现
适用场景:跨境支付(汇率锁定+资金划转)

  1. Try阶段:

    • 预留资源(如冻结库存)
    • 生成预备数据
  2. Confirm阶段:

    • 提交预备数据(如扣减冻结库存)
  3. Cancel阶段:

    • 释放预留资源(如解冻库存)

流程:
Try:冻结用户美元账户资金
Confirm:实际扣款并完成人民币入账
Cancel:解冻冻结资金(若汇率波动超阈值)

Saga模式(长事务)

原理:通过状态机编排服务调用,失败时执行补偿操作
适用场景:旅游平台多服务预订(酒店+机票+租车)

​流程:
正向操作:预订酒店 → 预订机票 → 租车
补偿操作:若租车失败 → 取消机票 → 取消酒店

四种模式的区别

对比维度AT(自动补偿)​TCC(手动补偿)​Saga(长事务补偿)​XA(强一致性)​
实现原理代理数据源生成逆向SQL回滚Try-Confirm-Cancel三阶段手动控制正向服务链 + 逆向补偿链数据库原生XA协议两阶段提交
一致性级别最终一致性(默认)强一致性最终一致性强一致性
业务侵入性低(仅需数据源代理)高(需实现Try/Confirm/Cancel接口)中(需定义补偿服务)无(数据库驱动实现)
锁机制一阶段提交即释放锁Try阶段锁定资源无锁(依赖业务幂等)全程持有数据库锁
性能高(本地事务快速提交)中(需多次RPC调用)低(长事务延迟高)低(两阶段同步阻塞)
隔离性通过全局锁实现读隔离业务自行控制隔离性无隔离(可能脏读)完全隔离
适用场景跨数据库事务(如订单+库存)金融交易(如支付扣款)长流程业务(如机票预订)传统数据库跨库事务(如银行转账)
典型框架Seata AT模式Seata TCC模式Apache ServiceComb SagaAtomikos、Narayana
补偿方式自动生成反向SQL手动编写补偿逻辑手动或配置式补偿数据库自动回滚
数据一致性保障最终一致性(允许短暂不一致)强一致性最终一致性(需补偿成功)强一致性

分布式锁

小也用分布式事务的思维模式解决了流程上统一性的问题,但又有了新问题。
以前一个厨师的时候,大家点餐都是先来后到,反正就这么一个厨子,按顺序出餐就是了。但现在厨师多了,大家同时点餐时,厨师们有时候需要同时用到某一台厨具,这个时候就产生了竞争。

控制对同一对象/资源使用,就需要用到锁。

以前单体系统的时候,程序在一台服务器上,使用Java的自带锁就可以解决大部分问题,但现在程序分散在不同服务器,要保证业务流程正确的前提下,还要保证对竞争资源的顺序使用,就需要一个跨服务器的分布式锁。

Java架构中常用的分布式锁有:ZooKeeper 和redis。

ZooKeeper 实现分布式锁

利用 ZooKeeper 的 ​临时顺序节点 和 ​Watcher 机制 实现公平锁。

  • 优点
    ​强一致性:ZAB协议保证数据一致性
    ​自动清理:临时节点自动删除避免死锁
    ​公平锁:按节点顺序获取锁

  • ​缺点
    ​性能较低:频繁创建节点和触发Watcher有延迟
    ​依赖ZooKeeper集群:需维护ZooKeeper服务

Redis 实现分布式锁

通过 SETNX(或 SET 命令扩展参数)实现互斥锁,配合Lua脚本保证原子性。

  • 优点
    ​高性能:内存操作响应快
    ​简单易用:API友好,支持多种客户端

  • ​缺点
    ​非强一致:主从切换可能导致锁丢失(RedLock缓解但未彻底解决)
    ​锁续期复杂:需处理过期时间与业务执行时间的匹配

区别

维度ZooKeeperRedis
一致性强一致性(ZAB协议)最终一致性(主从同步延迟)
性能低(频繁节点操作和Watcher触发)高(内存操作)
死锁处理临时节点自动删除依赖超时机制
锁类型公平锁非公平锁(Redisson可配置为公平锁)
适用场景需严格一致性的系统(如金融交易)高并发且允许短暂不一致的场景(如库存扣减)
运维复杂度需维护ZooKeeper集群单节点简单,RedLock需多实例部署

总结

分布式虽然带来了高并发高可用的优点,但同时也带了新问题。以往单体服务的事务、锁机制都可以控制在单一服务器内解决,但现在不得不从多个服务器角度思考。于是,提出了分布式事务和分布式锁。其原理与单体服对应解决方案一致,但由于分布式复杂性,在实际解决时需要考虑不同服务器之间通信和状态同步。

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

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

相关文章

Ubuntu里安装Jenkins

【方式1】:下载war包,直接运行,需提前搭建Java环境,要求11或17,不推荐,war包下载地址,将war包上传到服务器,直接使用命令启动 java -jar /data/jenkins/jenkins.war【方式2】&#…

C++包管理工具vcpkg的安装使用教程

前言 使用vcpkg可以更方便地安装各种库,省去配置的时间和配置失败的风险,类似python中的anaconda,懒人必备 参考 安装参考:https://bqcode.blog.csdn.net/article/details/135831901?fromshareblogdetail&sharetypeblogde…

微服务面试题:配置中心

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

Qt msvc2017程序无法用enigma vitrual box打包,用winrar打包

我们通常打包Qt程序用Enigma virtual box。这样我们的程序就可以在别的电脑上也能运行,但是有时候,我们发现Enigma virtual box在打包的时候,对于msvc2017需要编译的程序中引用webengineview模块,打包时候发现不能运行。 我们如何…

微服务集成测试 -华为OD机试真题(A卷、JavaScript)

题目描述 现在有n个容器服务,服务的启动可能有一定的依赖性(有些服务启动没有依赖),其次,服务自身启动加载会消耗一些时间。 给你一个n n 的二维矩阵useTime,其中useTime[i][i]10表示服务i自身启动加载需…

Mac: 运行python读取CSV出现 permissionError

在MAC机器里,之前一直运行程序在某个指定的目录下读取excel和csv文件,没有出现错误,有一天突然出现错误:permissionError:[Errno 1] Operation not permitted, 具体错误信息如下: 经过调查得知&#xff0c…

UE5 学习笔记 FPS游戏制作30 显示击杀信息 水平框 UI模板(预制体)

文章目录 一制作单条死亡信息框水平框的使用创建一个水平框添加子元素调整子元素顺序子元素的布局插槽尺寸填充对齐 制作UI 根据队伍,设置文本的名字和颜色声明变量 将变量设置为构造参数根据队伍,设置文本的名字和颜色在构造事件中,获取玩家…

西门子TCP通讯过程中硬件连接突然断开

通信原理探秘又结合在工作中遇到的问题,关注到了通讯中的KeepAlive定时器的设置,所以做了如下实验。 硬件: 1513PLC TCP客户端 PC TCP服务器 前提条件:禁用PLC侧KeepAlive 程序: 测试流程: 打开PC端网络调试助手,设置为TCP服务器,打开链接; PC端打开WireShack软…

2025宁德时代测评Verify考什么?网申测评如何通过SHL笔试|附真题线上笔试考点、高分攻略、CATL新能源科技SHL测评宁德社招题目、面试攻略、求职建议

——职小豚 带你拆解新能源巨头招聘密码 一、宁德时代:新能源赛道「超级独角兽」 作为全球动力电池龙头,宁德时代(CATL)的江湖地位无需多言: 技术硬实力:麒麟电池、钠离子电池、无钴电池等黑科技加持&…

Spring Boot @RequestParam 解析参数时的常见问题及解决方案

1,遇到的问题:将后端接口写完后我想通过PostMan进行简单的测试一下,一不小心就遇到了这样的情况: org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter contractId is not prese…

Firefox 浏览器同步一个账户和书签网址

Firefox 浏览器同步一个账户和书签网址 Firefox 支持跨设备接续浏览,可实现电脑、手机与平板无缝衔接。无论您在使用哪台设备上使用 Firefox,都能获取书签、浏览历史、保存的密码等信息。当然也能实现windows、ios、linux、android系统中安装firefox浏览…

Maven多模块项目,其他项目引用子模块的依赖,无法打包,提示没有找到依赖

背景: 微服务项目 每个服务都是单独的项目,会存在依赖关联的问题,在子模块的下面 depoly 之后,就会出现别的项目,无法package 原因: 多模块项目,depoly 需要在父模块下面执行

mediacodec服务启动时加载media_codecs.xml

media.codec服务启动时, 会创建 implementation::Omx 和 implementation::OmxStore, 构造 Omx时, 会解析codec相关的xml文件,一般从会如下目录中, // from getDefaultSearchDirs() { "/product/etc",&quo…

本地部署DeepSeek-R1(Dify压力测试和性能调优)

安装压测软件 为了有效测试,应在局域网设备测试,我这里用的服务器是局域网内的Ubuntu,下载的压测软件是WRK apt install wrk测试脚本 为了省事我直接在/root目录下新建lua脚本 vim test.lua脚本内容如下,app-xxxx更换为你工作…

自动备份文件到服务器,自动备份文件到服务器有哪些方法?

将SQL Server数据库自动备份文件到服务器,可以通过多种方法实现。以下是几种常用的方法: 一、使用SQL Server Management Studio(SSMS)和SQL Server代理 配置SQL Server代理:确保SQL Server代理服务已启动。如果未启…

Ollama+open-webui搭建私有本地大模型详细教程

Ollamaopen-webui搭建私有本地大模型详细教程 1. 什么是 Ollama? 1.1. Ollama 简介 ​ Ollama 是一个轻量级的 AI 模型运行时,专注于简化 AI 模型的部署和使用。它支持多种预训练模型(如 Llama、Vicuna、Dolly 等),…

GPT-4o 原生图像生成技术解析:从模型架构到吉卜力梦境的实现

最近不少 AI 爱好者、设计师、Vlogger 在社交平台晒出了 GPT-4o 生成的梦幻图像,尤其是吉卜力风格的作品——柔和光影、日系构图、治愈色彩、富有情感的角色表达,一下子击中了无数人的“童年回忆 审美舒适区”。 🎨 下面是一些 GPT-4o 实际生…

测试cursor-AI编辑器

Cursor是一个免费的,内置AI插件的编辑器,在vscode基础上开发,可以创建和分析代码,还能提出修改建议。官网是 https://www.cursor.com/cn 载入SFTP的方式跟vscode是一样的,但是会有这样的报错: 报错&#x…

[首发]烽火HG680-KD-海思MV320芯片-2+8G-安卓9.0-强刷卡刷固件包

烽火HG680-KD-海思MV320芯片-28G-安卓9.0-强刷卡刷固件包 U盘强刷刷机步骤: 1、强刷刷机,用一个usb2.0的8G以下U盘,fat32,2048块单分区格式化(强刷对U盘非常非常挑剔,usb2.0的4G U盘兼容的多&a…

Spring Boot 快速入手

前言:为什么选择 Spring Boot? 🚀 在现代 Java 开发中,Spring Boot 已成为最流行的后端框架之一。无论是小型 Web 应用、企业级系统,还是微服务架构,Spring Boot 都能提供快速开发、自动配置、轻量级部署的…