JAVA Web 学习(四)RabbitMQ、Zookeeper

十、消息队列服务器——RabbitMQ

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

img

  1. Channel:网络信道,读写都是在Channel中进行(NIO的概念),包括对MQ进行的一些操作(例如clear queue等)都是在Channel中进行,客户端可建立多个Channel,每个Channel代表一个会话任务
  2. Message:由properties(有消息优先级、延迟等特性)和Body(消息内容)组成
  3. Exchange:Routing and Filter7、Binding:把Exchange和Queue进行Binding8、Routing key:路由规则
  4. Binding:把Exchange和Queue进行Binding
  5. Routing key:路由规则
  • 优点:
    1. 解除业务系统之间的耦合,降低系统之间的依赖关系
    2. 实现消息的异步处理,无需同步等待
    3. 削峰填谷,将流量从高峰期引到低谷期进行处理
  • 缺点:
    1. 增加了系统的复杂度,带入了幂等、重复消费、消息丢失的问题
    2. 系统的可用性比原先要低,MQ挂了以后,整个系统也会崩溃.
    3. 消费端数据一致性问题
  • 使用场景
    • 消息订阅
    • 日志采集
    • 埋点
    • 订单
基于消息的模型,关心的是“通知”,而非“处理”.
在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦.
为了保证库存肯定有,可以将队列大小设置成库存数量,或者采用其他方式解决。
四种交换机(Exchange)
  • i. 直连交换机,Direct exchange:带路由功能的交换机,根据routing_key(消息发送的时候需要指定)直接绑定到队列,⼀个交换机也可以通过过个routing_key绑定多个队列。
  • ii. 扇形交换机,Fanout exchange:⼴播消息。
  • iii. 主题交换机,Topic exchange:发送到主题交换机上的消息需要携带指定规则的routing_key,主题交换机会根据这个规则将数据发送到对应的(多个)队列上。
  • iv. ⾸部交换机,Headers exchange:⾸部交换机是忽略routing_key的⼀种路由⽅式。路由器和交换机路由的规则是通过Headers信息来交换的,这个有点像HTTP的Headers。将⼀个交换机声明成⾸部交换机,绑定⼀个队列的时候,定义⼀个Hash的数据结构,消息发送的时候,会携带⼀组hash数据结构的信息,当Hash的内容匹配上的时候,消息就会被写⼊队列。
1. 在RabbitMQ集群中的节点只有两种类型:内存节点/磁盘节点,单节点系统只运行磁盘类型的节点。而在集群中,可以选择配置部分节点为内存节点。
2. 内存节点将所有的队列,交换器,绑定关系,用户,权限,和vhost的元数据信息保存在内存中。
3. 磁盘节点将这些信息保存在磁盘中,但是内存节点的性能更高,为了保证集群的高可用性,必须保证集群中有两个以上的磁盘节点,来保证当有一个磁盘节点崩溃了,集群还能对外提供访问服务
两种模式
主从模式:默认的集群模式、(高性能)
  • 内存节点的性能只能体现在资源管理上,比如增加或删除队列(queue),虚拟主机(vrtual hosts),交换机(exchange)等,发送和接受message速度同磁盘节点一样。
  • rabbitmq集群中可以共享user,vhost,exchange等,所有的数据和状态都是必须在所有节点上复制的,在集群模式下只要有任何一个节点能够工作,RabbitMQ集群对外就能提供服务。
  • 消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构,但队列的元数据仅保存有一份,即创建该队列的rabbitmq节点(A节点),当A节点宕机,你可以去其B节点查看,./rabbitmqctl list_queues发现该队列已经丢失,但声明的exchange还存在。
## 消费流程
当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer,所以consumer应平均连接每一个节点,从中取消息。
## 故障处理
该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。如果做了队列持久化或消息持久化,那么得等A节点恢复,然后才可被消费,并且在A节点恢复之前其它节点不能再创建A节点已经创建过的持久队列;

    这种模式更适合非持久化队列,只有该队列是非持久的,客户端才能重新连接到集群里的其他节点,并重新创建队列。假如该队列是持久化的,那么唯一办法是将故障节点恢复起来。
镜像模式:高可用性

消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用

搭建注意
  • 各节点之间使用“–link”连接,此属性不能忽略。
  • 各节点使用的 erlang cookie 值必须相同,此值相当于“秘钥”的功能,用于各节点的认证。
  • 整个集群中必须包含一个磁盘节点。
问题
如何保证MQ中消息不会丢失?
  • RabbitMQ允许将消息标记为持久化,这意味着消息将会被写入磁盘而不是仅保存在内存中。这样,在消息发送到队列之后,即使RabbitMQ服务器发生故障或重启,消息也能够存储在磁盘上,并在恢复后仍然可用。
  • 生产者发生异常没有把消息成功发送给MQ,MQ成功接收到消息之后发生宕机了,消息未被成功,消费消费端要设置签收机制为手动签收,只有当消息最终被处理,才告诉MQ已经消费,此时MQ再去删除这条消息。
  • 消息预取(Message Prefetch):RabbitMQ允许消费者一次从队列中获取多个消息,并将它们存储在本地缓冲区中。这样可以提高消费者的效率,并减少消费者与RabbitMQ服务器之间的通信次数。
/*消息持久化方法?
1.声明交换机Exchange的时候设置 durable=true;
2.声明队列Queue的时候设置 durable=true;
3.发送消息的时候设置消息的 deliveryMode = 2;*/
//public TopicExchange(String name, boolean durable, boolean autoDelete)
return new TopicExchange(EXCHANGE_NAME,true,false);
//durable:是否将队列持久化 true表示需要持久化 false表示不需要持久化
return new Queue(QUEUE_NAME, false);

new MessageProperties() --> DEFAULT_DELIVERY_MODE = MessageDeliveryMode.PERSISTENT --> deliveryMode = 2;
如何解决消息堆积?
  • 启动多个消费者微服务
  • 优化消费者处理消息的能力,提高消费消息的性能
  • 调整RabbitMQ的队列容量
  • 设置过期时间,让一些不是那么重要的消息到达指定时间之后就丢弃
  • 将无法被消费的消息放到死信队列(DLQ)中
如何解决消息被重复消费?
  • 生产者发送消息的时候带上一个全局唯一的id,消费者拿到消息后,先根据这个id去 Redis 里查一下,之前有没消费过,没有消费过就处理,并且写入这个id到 Redis,如果消费过了,则不处理。
  • 基于数据库的唯一键
  • 消费者端幂等性:设计消费者端的处理逻辑具有幂等性。即无论消息被处理多次,最终结果都保持一致。这样,即使消息被重复消费,也不会对最终结果产生影响。
RabbitMQ 中 vhost 的作用是什么?

vhost:每个 RabbitMQ 都能创建很多 vhost,我们称之为虚拟主机,每个虚拟主机其实都是 mini 版的RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制,主要是为了隔离,vhost 不仅消除了为基础架构中的每一层运行一个RabbitMq服务器的需要, 童谣避免为每一层创建不同的集群.

RabbitMQ 集群中唯一一个磁盘节点崩溃了会发生什么情况?

如果唯一磁盘的磁盘节点崩溃了,
唯一磁盘节点崩溃了,集群是可以保持运行的,但你不能更改任何东西。

RabbitMQ 每个节点是其他节点的完整拷贝吗?为什么?

不是,原因有以下两个:

  • 存储空间的考虑:如果每个节点都拥有所有队列的完全拷贝,这样新增节点不但没有新增存储空间,反而增加了更多的冗余数据;

  • 性能的考虑:如果每条消息都需要完整拷贝到每一个集群节点,那新增节点并没有提升处理消息的能力,最多是保持和单节点相同的性能甚至是更糟

rabbitMQ节点的关闭顺序?

在关闭 RabbitMQ 集群时,应该先关闭从节点,然后再关闭主节点。这是因为从节点的状态是依赖于主节点的,如果先关闭主节点,可能会导致从节点无法正常工作。

十一、分布式应用程序协调服务——ZooKeeper

ZooKeeper 是一个开源的分布式协调框架,它的定位是为分布式应用提供一致性服务,是整个大数据体系的管理员ZooKeeper 会封装好复杂易出错的关键服务,将高效、稳定、易用的服务提供给用户使用。

img

特点
  1. 集群:Zookeeper是一个领导者(Leader),多个跟随者(Follower)组成的集群。
  2. 高可用性:集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。
  3. 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
  4. 更新请求顺序进行:来自同一个Client的更新请求按其发送顺序依次执行。
  5. 数据更新原子性:一次数据更新要么成功,要么失败。
  6. 实时性:在一定时间范围内,Client能读到最新数据。
  7. 设计模式角度来看,zk是一个基于观察者设计模式的框架,它负责管理跟存储大家都关心的数据,然后接受观察者的注册,数据反生变化zk会通知在zk上注册的观察者做出反应。
Zookeeper 有三种部署模式:
    单机部署:一台集群上运行;
    集群部署:多台集群运行;
    伪集群部署:一台集群启动多个 Zookeeper 实例运行。
Zookeeper 保持主从节点的同步?
    Zookeeper 的核心是原子广播机制,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模式和广播模式。
为什么要有主节点?
    在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能
ZooKeeper文件系统

ZooKeeper文件系统(ZooKeeper File System,ZFS)是ZooKeeper提供的一种类似于文件系统的数据模型,可以帮助用户通过树形节点结构,对ZooKeeper中的数据进行管理和访问。

在ZFS中,数据存储以节点(ZNode)的形式组织,每个ZNode可以保存一个Byte数组,同时也可以是一个目录节点,包含了子节点的信息。用户可以通过ZFS的API接口,对节点进行创建、读取、更新和删除等操作。

ZFS的根节点是"/“,通过这个节点,用户可以访问整个ZooKeeper文件系统。节点名字可以是任何的字符串,但是不能重复,节点名字可以有多级,中间用”/ "隔开。例如,/myapp/config是一个典型的ZFS节点路径。

ZNode节点四种类型:
  • 持久节点(persistent):这是最常见的节点类型,一旦创建,将一直存在于ZooKeeper的目录结构中,直到显式删除。
  • 临时节点(ephemeral):临时节点是指在创建客户端会话期间存在的节点。当客户端会话结束(由于某种原因)时,节点将被自动删除。临时节点非常有用,它们可以用于表示客户端会话是否处于特定状态。
  • 有序节点(sequential):有序节点还可以与上述两种节点类型结合使用,这样可以创建名称自动带有序增量的节点。有序节点用于排序构造出一种递增的节点名称集合。
  • 临时顺序节点(ephemeral sequential):这是一种组合节点类型,是临时节点和顺序节点的组合。这种节点将在客户端会话期间存在,并带有一个顺序号。当会话终止时,顺序号将自动从数据库中删除。
监听通知流程
  • 在main线程中创建Zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener)。
  • 通过connect线程将注册的监听事件发送给Zookeeper。
  • 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
  • Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。
  • listener线程内部调用了process()方法。
  • ZooKeeper 支持watch(观察)的概念。客户端可以在每个znode节点上设置一个观察。如果被观察服务端的znode结点有变更,那么watch就会被触发,这个watch所属的客户端将接收到一个通知包被告知结点已经发生变化,把相应的事件通知给设置过Watcher的Client端。
应用场景
1. 数据发布/订阅

当某些数据由几个机器共享,且这些信息经常变化数据量还小的时候,这些数据就适合存储到ZK中。

  • 数据存储:将数据存储到 Zookeeper 上的一个数据节点。
  • 数据获取:应用在启动初始化节点从 Zookeeper 数据节点读取数据,并在该节点上注册一个数据变更 Watcher
  • 数据变更:当变更数据时会更新 Zookeeper 对应节点数据,Zookeeper会将数据变更通知发到各客户端,客户端接到通知后重新读取变更后的数据即可。
2. 分布式锁

主要是避免了羊群效应,临时节点已经预先存在,所有想要获得锁的线程在它下面创建临时顺序编号目录节点,编号最小的获得锁,用完删除,后面的依次排队获取。

img

3. 负载均衡
  • 多个服务注册
  • 客户端获取中间件地址集合
  • 从集合中随机选一个服务执行任务

img

  1. 命名服务

利用 zk 创建一个全局唯一的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。

  1. Leader选举

    利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /Master 节点,最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很轻易的在分布式环境中进行集群选举了。

    就是动态Master选举。这就要用到 EPHEMERAL_SEQUENTIAL类型节点的特性了,这样每个节点会自动被编号。允许所有请求都能够创建成功,但是得有个创建顺序,每次选取序列号最小的那个机器作为Master

## ZooKeeper集群节点个数一定是奇数个
在节点数量是奇数个的情况下, zookeeper集群总能对外提供服务(即使损失了一部分节点);如果节点数量是偶数个,会存在zookeeper集群不能用的可能性(脑裂成两个均等的子集群的时候)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【实战】阿里智能编码助手通义灵码

文章目录 前言技术积累通义灵码是什么?Copilot是什么?通义灵码主要功能通义灵码有哪些优势?通义灵码支持语言/工具通义灵码接入方式通义灵码帮助中心 实战演示安装插件行/函数级实时续写自然语言生成代码代码优化单元测试生成代码注释生成解释…

Spring 事务原理总结三

今天这篇文章,我想梳理一下Spring事务用到的几个核心组件。这些核心组件是我们理解Spring事务原理的基础。通过它们我们可以体会学习一下Spring设计者设计Spring事务时的基本思路。这些组件是:TransactionInfo、TransactionStatus、TransactionManager、…

【Qt+MSVC2017_64bit +Cmake新建项目编译出错】

项目场景: 提示:这里简述项目相关背景: 项目新电脑环境配置 QtMSVC2017_64bit Cmake新建项目编译出错 问题描述 提示:这里描述项目中遇到的问题: QtMSVC2017_64bit Cmake新建项目编译出错 Running C:\Program Fil…

Java语法学习线程基础

Java语法学习线程基础 大纲 概念创建线程线程终止常用方法用户线程和守护线程线程的七大状态线程的同步互斥锁线程死锁释放锁 具体案例 1.概念 2. 创建线程 第一种: class Cat extends Thread {int time 0;Overridepublic void run() {while (true) {System.o…

Ubuntu 添加字体

Ubuntu 添加字体 Ubuntu如何添加新的字体?似乎远远没有Windows方便呀,查询了一些资料,与大家分享。 方法1 根据字体名称直接安装 oyroy-FMVU08001:~$ sudo apt-get install fonts-wqy-zenhei [sudo] roy 的密码: 正在读取软件…

基于springboot篮球竞赛预约平台源码和论文

随着信息化时代的到来,管理系统都趋向于智能化、系统化,篮球竞赛预约平台也不例外,但目前国内仍都使用人工管理,市场规模越来越大,同时信息量也越来越庞大,人工管理显然已无法应对时代的变化,而…

【数位dp】【动态规划】【KMP】1397. 找到所有好字符串

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1397. 找到所有好字符串 给你两个长度为 n 的字符串 s1 和 s2 ,以及一个字符串 evil 。请你返回 好字符串 的数目。 好字符串 的定义为&#x…

7隐藏进程_Linux_Rootkit.md

Xcellerator 密码学Linux其他逆向工程 文章目录 [Linux Rootkit 第 7 部分:隐藏进程](https://xcellerator.github.io/posts/linux_rootkits_07/)选择要隐藏的 PID隐藏 PID Linux Rootkit 第 7 部分:隐藏进程 2020-10-01 :: TheXcellerator # linux #…

Docker基础与持续集成

docker 基础知识: docker与虚拟机 !左边为虚拟机,右边为docker环境 – Server :物理机服务器Host OS :构建的操作系统Hypervisor :一种虚拟机软件,装了之后才能虚拟化操作系统Guest OS :虚拟化的操作系统…

xlsx xlsx-style 使用和坑记录

1 安装之后报错 npm install xlsx --savenpm install xlsx-style --save Umi运行会报错 自己代码 import XLSX from "xlsx"; import XLSXStyle from "xlsx-style";const data [["demo1","demo2","demo3","demo4&quo…

cesium-水平测距

cesium测量两点间的距离 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><el-breadcrumb-item&…

『运维备忘录』之 Cron 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

Logback学习

logback 1、logback介绍 Logback是由log4j创始人设计的另一个开源日志组件&#xff0c;性能比log4j要好。 lockback优点&#xff1a; 内核重写、测试充分、初始化内存加载更小&#xff0c;这一切让logback性能和log4j相比有诸多倍的提升。logback非常自然地直接实现了slf4j…

CSS的元素显示模式

一&#xff0c;什么是元素显示模式 元素显示模式是指元素以什么方式显示&#xff0c; 作用&#xff1a;了解不同类型的标签可以更好的布局网页。 HTML元素一般分为块元素和行内元素。 1.1块元素 常见的块元素有&#xff1a;<p><ul><ol><li>,<di…

OJ_成绩排序2

题干 c实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<vector> #include<algorithm> using namespace std;struct student {char name[16];int score;int seq; };bool comparefromhightolow(student a, student b) {if (a.score > b.…

4通过干扰 Char 设备为 PRNG 添加后门_Linux_Rootkit.md

Xcellerator 密码学Linux其他逆向工程 文章目录 [Linux Rootkit 第 4 部分&#xff1a;通过干扰 Char 设备为 PRNG 添加后门](https://xcellerator.github.io/posts/linux_rootkits_04/)Linux 中的字符设备字符设备的读取例程编写 Rootkit我们能去哪里呢&#xff1f; Linux Ro…

c#string方法对比

字符串的截取匹配操作在开发中非常常见&#xff0c;比如下面这个示例&#xff1a;我要匹配查找出来字符串数组中以“abc”开头的字符串并打印&#xff0c;我下面分别用了两种方式实现&#xff0c;代码如下&#xff1a; using System; namespace ConsoleApp23{ class Progra…

iOS应用提交上架的最新流程

摘要 本篇博客介绍了iOS应用程序上架的最新流程。包括上架基本需求资料、证书的创建和使用、测试设备的添加、描述文件的创建、打包、审核等步骤。 引言 在开发完iOS应用程序后&#xff0c;我们需要将其提交到App Store上架。然而&#xff0c;随着技术的不断发展&#xff0c;…

【数据结构】实现顺序表

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解顺序表&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一.概念及结构二.接口实现2.1 创建顺序表结构体2.2 初始化顺序表2.3 销毁顺序表2.4 打印顺序表…

力扣面试150 只出现一次的数字Ⅱ 哈希 统计数位 DFA有穷自动机

Problem: 137. 只出现一次的数字 II 文章目录 思路&#x1f496; 哈希&#x1f496; 位数统计&#x1f496; DFA 状态机 思路 &#x1f468;‍&#x1f3eb; 参考 &#x1f496; 哈希 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) cl…