一天吃透消息队列面试八股文

news2024/10/7 18:25:48

内容摘自我的学习网站:topjavaer.cn

为什么要使用消息队列?

总结一下,主要三点原因:解耦、异步、削峰

1、解耦。比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单操作失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。

2、异步。将消息写入消息队列,非必要的业务逻辑以异步的方式运行,不影响主流程业务。

3、削峰。消费端慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。比如秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉。这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,如果消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

使用了消息队列会有什么缺点

  • 系统可用性降低。引入消息队列之后,如果消息队列挂了,可能会影响到业务系统的可用性。
  • 系统复杂性增加。加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。

首先分享一份大彬精心整理的大厂面试手册,包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等高频面试题,非常实用,有小伙伴靠着这份手册拿过字节offer~

需要的小伙伴可以自行下载

链接:https://pan.quark.cn/s/76d6b4b3dc04

常见的消息队列对比

对比方向概要
吞吐量万级的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。
可用性都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。RocketMQ 基于分布式架构。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
时效性RabbitMQ 基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。其他三个都是 ms 级。
功能支持除了 Kafka,其他三个功能都较为完备。 Kafka 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准
消息丢失ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。

总结:

  • ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。
  • RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做 erlang 源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
  • RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的 MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用 RocketMQ 挺好的
  • Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。

本文内容摘自我的学习网站:topjavaer.cn

如何保证消息队列的高可用?

RabbitMQ:镜像集群模式

RabbitMQ 是基于主从做高可用性的,Rabbitmq有三种模式:单机模式、普通集群模式、镜像集群模式。单机模式一般在生产环境中很少用,普通集群模式只是提高了系统的吞吐量,让集群中多个节点来服务某个 Queue 的读写操作。那么真正实现 RabbitMQ 高可用的是镜像集群模式。

镜像集群模式跟普通集群模式不一样的是,创建的 Queue,无论元数据还是Queue 里的消息都会存在于多个实例上,然后每次你写消息到 Queue 的时候,都会自动和多个实例的 Queue 进行消息同步。这样设计,好处在于:任何一个机器宕机不影响其他机器的使用。坏处在于:1. 性能开销太大:消息同步所有机器,导致网络带宽压力和消耗很重;2. 扩展性差:如果某个 Queue 负载很重,即便加机器,新增的机器也包含了这个 Queue 的所有数据,并没有办法线性扩展你的 Queue。

Kafka:partition 和 replica 机制

Kafka 基本架构是多个 broker 组成,每个 broker 是一个节点。创建一个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据,这就是天然的分布式消息队列。就是说一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。

Kafka 0.8 以前,是没有 HA 机制的,任何一个 broker 宕机了,它的 partition 就没法写也没法读了,没有什么高可用性可言。

Kafka 0.8 以后,提供了 HA 机制,就是 replica 副本机制。每个 partition 的数据都会同步到其他机器上,形成自己的多个 replica 副本。然后所有 replica 会选举一个 leader 出来,生产和消费都跟这个 leader 打交道,然后其他 replica 就是 follower。写的时候,leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上数据即可。Kafka 会均匀的将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。

MQ常用协议

  • AMQP协议 AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。

    优点:可靠、通用

  • MQTT协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。

    优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统

  • STOMP协议 STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。

    优点:命令模式(非topic/queue模式)

  • XMPP协议 XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。

    优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大

  • 其他基于TCP/IP自定义的协议:有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCP\IP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。

MQ的通讯模式

  1. 点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一、一对多、多对多、多对一等多种配置方式,支持树状、网状等多种拓扑结构。
  2. 多点广播:MQ适用于不同类型的应用。其中重要的,也是正在发展中的是"多点广播"应用,即能够将消息发送到多个目标站点(Destination List)。可以使用一条MQ指令将单一消息发送到多个目标站点,并确保为每一站点可靠地提供信息。MQ不仅提供了多点广播的功能,而且还拥有智能消息分发功能,在将一条消息发送到同一系统上的多个用户时,MQ将消息的一个复制版本和该系统上接收者的名单发送到目标MQ系统。目标MQ系统在本地复制这些消息,并将它们发送到名单上的队列,从而尽可能减少网络的传输量。
  3. 发布/订阅(Publish/Subscribe)模式:发布/订阅功能使消息的分发可以突破目的队列地理指向的限制,使消息按照特定的主题甚至内容进行分发,用户或应用程序可以根据主题或内容接收到所需要的消息。发布/订阅功能使得发送者和接收者之间的耦合关系变得更为松散,发送者不必关心接收者的目的地址,而接收者也不必关心消息的发送地址,而只是根据消息的主题进行消息的收发。在MQ家族产品中,MQ Event Broker是专门用于使用发布/订阅技术进行数据通讯的产品,它支持基于队列和直接基于TCP/IP两种方式的发布和订阅。
  4. 集群(Cluster):为了简化点对点通讯模式中的系统配置,MQ提供 Cluster 的解决方案。集群类似于一个 域(Domain) ,集群内部的队列管理器之间通讯时,不需要两两之间建立消息通道,而是采用 Cluster 通道与其它成员通讯,从而大大简化了系统配置。此外,集群中的队列管理器之间能够自动进行负载均衡,当某一队列管理器出现故障时,其它队列管理器可以接管它的工作,从而大大提高系统的高可靠性

如何保证消息的顺序性?

RabbitMQ

拆分多个 Queue,每个 Queue一个 Consumer;或者就一个 Queue 但是对应一个 Consumer,然后这个 Consumer 内部用内存队列做排队,然后分发给底层不同的 Worker 来处理。

Kafka

  1. 一个 Topic,一个 Partition,一个 Consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。

  2. 写 N 个内存 Queue,具有相同 key 的数据都到同一个内存 Queue;然后对于 N 个线程,每个线程分别消费一个内存 Queue 即可,这样就能保证顺序性。

如何避免消息重复消费?

在消息生产时,MQ内部针对每条生产者发送的消息生成一个唯一id,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列。

在消息消费时,要求消息体中也要有一全局唯一id作为去重和幂等的依据,避免同一条消息被重复消费。

大量消息在 MQ 里长时间积压,该如何解决?

一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下:

  1. 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉;
  2. 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量;
  3. 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue;
  4. 接着临时用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据;
  5. 等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

MQ 中的消息过期失效了怎么办?

如果使用的是RabbitMQ的话,RabbtiMQ 是可以设置过期时间的(TTL)。如果消息在 Queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。这时的问题就不是数据会大量积压在 MQ 里,而是大量的数据会直接搞丢。这个情况下,就不是说要增加 Consumer 消费积压的消息,因为实际上没啥积压,而是丢了大量的消息。

我们可以采取一个方案,就是批量重导。就是大量积压的时候,直接将数据写到数据库,然后等过了高峰期以后将这批数据一点一点的查出来,然后重新灌入 MQ 里面去,把丢的数据给补回来。

消息中间件如何做到高可用?

以Kafka为例。

Kafka 的基础集群架构,由多个broker组成,每个broker都是一个节点。当你创建一个topic时,它可以划分为多个partition,而每个partition放一部分数据,分别存在于不同的 broker 上。也就是说,一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。

每个partition放一部分数据,如果对应的broker挂了,那这部分数据是不是就丢失了?那不是保证不了高可用吗?

Kafka 0.8 之后,提供了复制多副本机制来保证高可用,即每个 partition 的数据都会同步到其它机器上,形成多个副本。然后所有的副本会选举一个 leader 出来,让leader去跟生产和消费者打交道,其他副本都是follower。写数据时,leader 负责把数据同步给所有的follower,读消息时,直接读 leader 上的数据即可。如何保证高可用的?就是假设某个 broker 宕机,这个broker上的partition 在其他机器上都有副本的。如果挂的是leader的broker呢?其他follower会重新选一个leader出来。

如何保证数据一致性,事务消息如何实现?

一条普通的MQ消息,从产生到被消费,大概流程如下:

  1. 生产者产生消息,发送带MQ服务器
  2. MQ收到消息后,将消息持久化到存储系统。
  3. MQ服务器返回ACk到生产者。
  4. MQ服务器把消息push给消费者
  5. 消费者消费完消息,响应ACK
  6. MQ服务器收到ACK,认为消息消费成功,即在存储中删除消息。

举个下订单的例子吧。订单系统创建完订单后,再发送消息给下游系统。如果订单创建成功,然后消息没有成功发送出去,下游系统就无法感知这个事情,出导致数据不一致。
如何保证数据一致性呢?可以使用事务消息。一起来看下事务消息是如何实现的吧。

  1. 生产者产生消息,发送一条半事务消息到MQ服务器
  2. MQ收到消息后,将消息持久化到存储系统,这条消息的状态是待发送状态。
  3. MQ服务器返回ACK确认到生产者,此时MQ不会触发消息推送事件
  4. 生产者执行本地事务
  5. 如果本地事务执行成功,即commit执行结果到MQ服务器;如果执行失败,发送rollback。
  6. 如果是正常的commit,MQ服务器更新消息状态为可发送;如果是rollback,即删除消息。
  7. 如果消息状态更新为可发送,则MQ服务器会push消息给消费者。消费者消费完就回ACK。
  8. 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,然后根据查询到的结果执行最终状态。

如何设计一个消息队列?

首先是消息队列的整体流程,producer发送消息给broker,broker存储好,broker再发送给consumer消费,consumer回复消费确认等。

producer发送消息给broker,broker发消息给consumer消费,那就需要两次RPC了,RPC如何设计呢?可以参考开源框架Dubbo,你可以说说服务发现、序列化协议等等

broker考虑如何持久化呢,是放文件系统还是数据库呢,会不会消息堆积呢,消息堆积如何处理呢。

消费关系如何保存呢? 点对点还是广播方式呢?广播关系又是如何维护呢?zk还是config server

消息可靠性如何保证呢?如果消息重复了,如何幂等处理呢?

消息队列的高可用如何设计呢? 可以参考Kafka的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务。

消息事务特性,与本地业务同个事务,本地消息落库;消息投递到服务端,本地才删除;定时任务扫描本地消息库,补偿发送。

MQ得伸缩性和可扩展性,如果消息积压或者资源不够时,如何支持快速扩容,提高吞吐?可以参照一下 Kafka 的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了吗。

参考链接

多线程异步和MQ的区别

  • CPU消耗。多线程异步可能存在CPU竞争,而MQ不会消耗本机的CPU。
  • MQ 方式实现异步是完全解耦的,适合于大型互联网项目。
  • 削峰或者消息堆积能力。当业务系统处于高并发,MQ可以将消息堆积在Broker实例中,而多线程会创建大量线程,甚至触发拒绝策略。
  • 使用MQ引入了中间件,增加了项目复杂度和运维难度。

总的来说,规模比较小的项目可以使用多线程实现异步,大项目建议使用MQ实现异步。


最后给大家分享200多本计算机经典书籍PDF电子书,包括C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,感兴趣的小伙伴可以自取:

链接:https://pan.quark.cn/s/5e1f0fc1ba67

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

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

相关文章

【电机控制】PMSM无感FOC控制(九)无感启动

0. 前言 终于到了FOC无感入门的最后被一个章节了,无感foc的启动其实很好理解,分为三个阶段:转子定位、I/F强拖、电流转速双闭环。 1. 无感foc启动 (1)转子定位阶段: 首先将q轴电流设定一个能将转子拖动的值…

U-Mamba: Enhancing Long-range Dependency for Biomedical Image Segmentation

Abstract 卷积神经网络(Convolutional Neural Networks, cnn)和transformer是生物医学图像分割中最流行的架构,但由于固有的局部性或计算复杂性,它们处理远程依赖关系的能力有限。为了解决这一挑战,我们引入了U-Mamba,一个通用的…

IO详解(二)字符流

字符流 FileReader //创建一个文件字符输入流管道与源文件接通 Reader fr new FileReader("D:\\resource\\a.txt");//覆盖管道 Reader fr new FileReader("D:\\resource\\a.txt",true);//追加管道 int c fr.read();---char[] buffer new char[1024]; …

力扣hot100 环形链表 快慢指针 计步器

Problem: 141. 环形链表 文章目录 思路💖 快慢指针法💖 计步器法 思路 👨‍🏫 参考题解 💖 快慢指针法 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) /*** Definition for singly-linked list…

IP地址组成

一、简介 ​ IP地址由四段组成,每个字段是一个字节,即4个字节、 每个字节有8位,最大值是255(256:0~255),是全世界范围是唯一的 32 位(4个字节 * 8位)的标识符。 ​ IP地址由两部分组成&#x…

Mybatis-Generator-1.4.2

知道代码自动化原理,可以自己搞的,连客户端js html一起弄掉 Low Code Development Platform(LCDP)_cms lcdp-CSDN博客

【模拟】力扣38(Java)

题目 class Solution {public String countAndSay(int n) {String ret "1";for(int i1;i<n;i)//解释n-1次ret{StringBuffer tmp new StringBuffer();int len ret.length();for(int left 0,right 0;right<len;){//双指针while(right < len &&…

Gradle 笔记

Gradle依赖管理&#xff08;基于Kotlin DSL&#xff09; **注意&#xff1a;**如果不是工作原因或是编写安卓项目必须要用Gradle&#xff0c;建议学习Maven即可&#xff0c;Gradle的学习成本相比Maven高很多&#xff0c;而且学了有没有用还是另一回事&#xff0c;所以&#xff…

Oracle 19c rac集群管理 -------- 集群启停操作过程

Oracle rac集群启停操作过程 首先查看数据库的集群的db_unique_name SQL> show parameter nameNAME TYPE VALUE ------------------------------------ ----------- --------------------------- cdb_cluster_name …

IMX6ULL|input子系统(按键实验)

一.input子系统 input子系统是Linux对输入设备提供的统一驱动框架。如按键、键盘、触摸屏和鼠标等输入设备的驱动方式是类似的&#xff0c;当出现按键、触摸等操作时&#xff0c;硬件产生中断&#xff0c;然后CPU直接读取引脚电平&#xff0c;或通过SPI、I2C等通讯方式从设备的…

【大数据精讲】全量同步与CDC增量同步方案对比

目录 背景 名词解释 问题与挑战 FlinkCDC DataX 工作原理 调度流程 五、DataX 3.0六大核心优势 性能优化 背景 名词解释 CDC CDC又称变更数据捕获&#xff08;Change Data Capture&#xff09;&#xff0c;开启cdc的源表在插入INSERT、更新UPDATE和删除DELETE活动时…

Linux: hardware: HP: DIMM

今天遇到一个问题是服务器上BIOS检查DIMM出现错误&#xff1a; 462-Uncorrectable Memory Error Threshold Exceeded(Processor 1, DIMM 14). The DIMM is mapped out and is currently not available. Action: Take corrective action for the failing DIMM. Re-map all DIMMs…

CentOS上安装Mellanox OFED

打开Mellanox官网下载驱动 Linux InfiniBand Drivers 点击下载链接跳转至 Tgz解压缩执行 ./mlnxofedinstall发现缺少模块 # ./mlnxofedinstall Logs dir: /tmp/MLNX_OFED_LINUX.11337.logs General log file: /tmp/MLNX_OFED_LINUX.11337.logs/general.log Verifying KMP rpm…

基于SpringBoot Vue求职招聘系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

抖音评论区链接,如何实现跳转到微信?-数灵通

在抖音发布带货视频后&#xff0c;如何有效地将用户吸引到我们的店铺呢&#xff1f;以微商为例&#xff0c;我们可以利用抖音评论区的评论置顶功能来达到这一目的。 评论置顶功能允许作者将一条评论置于评论区的顶部&#xff0c;使其成为评论区的焦点。我们可以利用这一功能来吸…

实现VLAN之间的路由

原理&#xff1a;路由器子接口 一个接口允许多个VLAN通过&#xff08;避免占用物理路由器接口&#xff09;。 目标 第 1 部分&#xff1a;单臂路由 第 2 部分&#xff1a;配置第三层交换机的路由端口 第 3 部分&#xff1a;带SVI的VLAN间路由 第 4 部分&#xff1a;补充知…

书生·浦语大模型实战营-学习笔记5

LMDeploy 大模型量化部署实践 大模型部署背景 LMDeploy简介 轻量化、推理引擎、服务 核心功能-量化 显存消耗变少了 大语言模型是典型的访存密集型任务&#xff0c;因为它是decoder-by-decoder 先把数据量化为INT4存起来&#xff0c;算的时候会反量化为FP16 AWQ算法&a…

WINCC 7.5SP2安装过程

最近在群里有人问WINCC的安装问题&#xff0c;而且费了好大功夫就是安装不上&#xff0c;不管WINCC哪个版本&#xff0c;安装过程都差不多&#xff0c;于是昨天用虚拟机做了个WIN10系统&#xff0c;安装了7.5SP2版本&#xff0c;先在把安装的详细过程说一下 1、系统要求 很多…

webpack如何把dist.js中某个模块js打包成一个全局变量,使得在html引入dist.js后可以直接访问

webpack可以通过使用expose-loader来将模块中的一个js文件暴露为全局可以访问的变量。下面是一个示例代码&#xff1a; 1、安装expose-loader npm install expose-loader --save-dev 2、webpack.config.js配置文件 值得注意的是&#xff1a;我在本地使用16.14.2版本的node打包…

[docker] 关于docker的面试题

docker命名空间 docker与虚拟机的区别 容器虚拟机所有容器共享宿主机的内核每个虚拟机都有独立的操作系统和内核通过namespace实现资源隔离&#xff0c;通过cgroup实现限制资源的最大使用量完全隔离。每个虚拟机都有独立的硬件资源秒级启动速度分钟级启动速度容器相当于宿主机…