Linux Cgroups

Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。这个项目最早是由Google的工程师在2006年发起(主要是Paul Menage和Rohit Seth),最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词太过广泛,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。然后,其它开始了他的发展。

Linux CGroupCgroup 可​​​让​​​您​​​为​​​系​​​统​​​中​​​所​​​运​​​行​​​任​​​务​​​(进​​​程​​​)的​​​用​​​户​​​定​​​义​​​组​​​群​​​分​​​配​​​资​​​源​​​ — 比​​​如​​​ CPU 时​​​间​​​、​​​系​​​统​​​内​​​存​​​、​​​网​​​络​​​带​​​宽​​​或​​​者​​​这​​​些​​​资​​​源​​​的​​​组​​​合​​​。​​​您​​​可​​​以​​​监​​​控​​​您​​​配​​​置​​​的​​​ cgroup,拒​​​绝​​​ cgroup 访​​​问​​​某​​​些​​​资​​​源​​​,甚​​​至​​​在​​​运​​​行​​​的​​​系​​​统​​​中​​​动​​​态​​​配​​​置​​​您​​​的​​​ cgroup。

主要提供了如下功能:

● Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制。

● Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐。

● Accounting: 一些审计或一些统计,主要目的是为了计费。

● Control: 挂起进程,恢复执行进程。

使​​​用​​​ cgroup,系​​​统​​​管​​​理​​​员​​​可​​​更​​​具​​​体​​​地​​​控​​​制​​​对​​​系​​​统​​​资​​​源​​​的​​​分​​​配​​​、​​​优​​​先​​​顺​​​序​​​、​​​拒​​​绝​​​、​​​管​​​理​​​和​​​监​​​控​​​。​​​可​​​更​​​好​​​地​​​根​​​据​​​任​​​务​​​和​​​用​​​户​​​分​​​配​​​硬​​​件​​​资​​​源​​​,提​​​高​​​总​​​体​​​效​​​率​​​。

在实践中,系统管理员一般会利用CGroup做下面这些事(有点像为某个虚拟机分配资源似的):

● 隔离一个进程集合(比如:nginx的所有进程),并限制他们所消费的资源,比如绑定CPU的核。

● 为这组进程 分配其足够使用的内存

● 为这组进程分配相应的网络带宽和磁盘存储限制

● 限制访问某些设备(通过设置设备的白名单)

那么CGroup是怎么干的呢?我们先来点感性认识吧。

首先,Linux把CGroup这个事实现成了一个file system,你可以mount。在我的CentOS7.9下,你输入以下命令你就可以看到cgroup已为你mount好了。

[root@sentry ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuacct,cpu)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,memory)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,net_prio,net_cls)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,blkio)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuset)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,devices)

或者使用lssubsys命令:

[root@sentry ~]# lssubsys  -m
cpuset /sys/fs/cgroup/cpuset
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids

我们可以看到,在/sys/fs下有一个cgroup的目录,这个目录下还有很多子目录,比如: cpu,cpuset,memory,blkio……这些,这些都是cgroup的子系统。分别用于干不同的事的。

你可以到/sys/fs/cgroup的各个子目录下去make个dir,你会发现,一旦你创建了一个子目录,这个子目录里又有很多文件了。

[root@sentry cpu]# mkdir limit
[root@sentry cpu]# cd limit/
[root@sentry limit]# ll
总用量 0
-rw-r--r--. 1 root root 0 7月   6 18:38 cgroup.clone_children
--w--w--w-. 1 root root 0 7月   6 18:38 cgroup.event_control
-rw-r--r--. 1 root root 0 7月   6 18:38 cgroup.procs
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.cpu_exclusive
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.cpus
-r--r--r--. 1 root root 0 7月   6 18:38 cpuset.effective_cpus
-r--r--r--. 1 root root 0 7月   6 18:38 cpuset.effective_mems
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.mem_exclusive
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.mem_hardwall
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.memory_migrate
-r--r--r--. 1 root root 0 7月   6 18:38 cpuset.memory_pressure
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.memory_spread_page
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.memory_spread_slab
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.mems
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.sched_load_balance
-rw-r--r--. 1 root root 0 7月   6 18:38 cpuset.sched_relax_domain_level
-rw-r--r--. 1 root root 0 7月   6 18:38 notify_on_release
-rw-r--r--. 1 root root 0 7月   6 18:38 tasks

CPU 限制

假设,我们有一个非常吃CPU的程序,叫cpu_limit,其源码如下:

#include <stdio.h>
int main(void)
{int i = 0;for(;;) i++;return 0;
}

执行起来后,毫无疑问,CPU被干到了100%(下面是top命令的输出)

gcc cpu_limit.c -Wall -o cpu_limit && ./cpu_limit

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                  
31344 root      20   0    4212    352    280 R 100.0  0.0   0:15.82 deadloop 

然后,我们这前不是在/sys/fs/cgroup/cpu下创建了一个limit的group。我们先设置一下这个group的cpu利用的限制:

[root@sentry]# cat /sys/fs/cgroup/cpu/limit/cpu.cfs_quota_us 
-1
[root@sentry limit]# echo 20000 > /sys/fs/cgroup/cpu/limit/cpu.cfs_quota_us

我们看到,这个进程的PID是31344,我们把这个进程加到这个cgroup中:

# echo 31344 >> /sys/fs/cgroup/cpu/limit/tasks

然后,就会在top中看到CPU的利用立马下降成20%了。(前面我们设置的20000就是20%的意思)

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                  
31344 root      20   0    4212    352    280 R  20.3  0.0   3:38.55 deadloop

内存使用限制

我们再来看一个限制内存的例子(下面的代码是个死循环,其它不断的分配内存,每次512个字节,每次休息一秒):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{int size = 0;int chunk_size = 1024*1024;void *p = NULL;while(1) {if ((p = realloc(p, chunk_size)) == NULL) {printf("out of memory!!\n");break;}memset(p, 1, chunk_size);
        size += chunk_size;printf("[%d] - memory is allocated [%8d] bytes \n", getpid(), size);sleep(1);}return 0;
}

编译并执行程序

gcc mem_limit.c -Wall -o mem_limit && ./mem_limit

然后,在我们另外一边:

# 创建memory cgroup
$ mkdir /sys/fs/cgroup/memory/limit
$ echo 64k > /sys/fs/cgroup/memory/limit/memory.limit_in_bytes
# 禁用swap
echo 0 > memory.swappiness
# 把上面的进程的pid加入这个cgroup
$ echo [pid] > /sys/fs/cgroup/memory/limit/tasks 

你会看到,一会上面的进程就会因为内存问题被kill掉了。

[26991] - memory is allocated [   70144] bytes 
[26991] - memory is allocated [   70656] bytes 
[26991] - memory is allocated [   71168] bytes 
[26991] - memory is allocated [   71680] bytes 
[26991] - memory is allocated [   72192] bytes 
[26991] - memory is allocated [   72704] bytes 
[26991] - memory is allocated [   73216] bytes 
已杀死

Cgroup的内存限制可能会有一些延迟,特别是在内存使用接近限制时。系统需要一些时间来检测和响应内存限制的超出情况。Cgroup内存限制可能不会精确到字节级别,因此设置的内存限制和实际触发OOM杀死进程的内存使用量之间可能会有一些差异。以下是一些可能的原因和解释:

1.  内存使用延迟

Cgroup的内存限制可能会有一些延迟,特别是在内存使用接近限制时。系统需要一些时间来检测和响应内存限制的超出情况。

2.  内存使用统计

Cgroup内存限制考虑的不仅仅是用户态内存,还包括内核态内存和其它系统开销。因此,进程的实际内存使用量可能比你看到的数值要高。

3.  内存分配单位

内存分配可能是以页(通常为4KB)为单位进行的,因此实际分配的内存可能会超过指定的限制。Cgroup可能会在分配内存的边界上进行四舍五入处理。

4.  内存缓存和缓冲区

系统可能会为进程分配额外的内存用于缓存和缓冲区,这些内存可能在Cgroup限制之外。实际的内存使用量可能会略高于配置的限制。

5.  OOM决策延迟

即使内存使用超过了限制,OOM杀死进程的决策可能需要一些时间来执行。内核需要检测到内存超出限制并执行相应的操作,这可能会有一定的延迟。

磁盘I/O限制

我们先看一下我们的硬盘IO,我们的模拟命令如下:(从/dev/sda上读入数据,输出到/dev/null上)

dd if=/dev/sda of=/dev/null iflag=direct

dd 命令默认会使用一定的缓存来提高性能,这可能会导致短时间内的瞬时读取速度超过你设置的限制。可以尝试使用 dd 命令的 iflag=direct 选项来禁用缓存,这样可以更准确地测试实际的磁盘读取速度

我们通过iotop命令我们可以看到相关的IO速度是128MB/s(虚拟机内):

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                                       
25722 be/4 root      128.87 M/s    0.00 B/s  0.00 %  1.30 % dd if=/dev/sda of=/dev/null

然后,我们先创建一个blkio(块设备IO)的cgroup

mkdir /sys/fs/cgroup/blkio/limit

并把读IO限制到1MB/s,并把前面那个dd命令的pid放进去(注:8:0 是设备号,你可以通过ls -l /dev/sda1获得):

echo '8:0 1048576'  > /sys/fs/cgroup/blkio/limit/blkio.throttle.read_bps_device 
echo [pid] > /sys/fs/cgroup/blkio/limit/tasks

再用iotop命令,你马上就能看到读速度被限制到了1MB/s左右。

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                                       
13571 be/4 root     1043.21 K32    0.00 B/s  0.00 % 97.64 % dd if=/dev/sda of=/dev/null iflag=direct

CGroup的子系统

好了,有了以上的感性认识我们来,我们来看看control group有哪些子系统:

● blkio — 这​​​个​​​子​​​系​​​统​​​为​​​块​​​设​​​备​​​设​​​定​​​输​​​入​​​/输​​​出​​​限​​​制​​​,比​​​如​​​物​​​理​​​设​​​备​​​(磁​​​盘​​​,固​​​态​​​硬​​​盘​​​,USB 等​​​等​​​)。

● cpu — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​调​​​度​​​程​​​序​​​提​​​供​​​对​​​ CPU 的​​​ cgroup 任​​​务​​​访​​​问​​​。​​​

● cpuacct — 这​​​个​​​子​​​系​​​统​​​自​​​动​​​生​​​成​​​ cgroup 中​​​任​​​务​​​所​​​使​​​用​​​的​​​ CPU 报​​​告​​​。​​​

● cpuset — 这​​​个​​​子​​​系​​​统​​​为​​​ cgroup 中​​​的​​​任​​​务​​​分​​​配​​​独​​​立​​​ CPU(在​​​多​​​核​​​系​​​统​​​)和​​​内​​​存​​​节​​​点​​​。​​​

● devices — 这​​​个​​​子​​​系​​​统​​​可​​​允​​​许​​​或​​​者​​​拒​​​绝​​​ cgroup 中​​​的​​​任​​​务​​​访​​​问​​​设​​​备​​​。​​​

● freezer — 这​​​个​​​子​​​系​​​统​​​挂​​​起​​​或​​​者​​​恢​​​复​​​ cgroup 中​​​的​​​任​​​务​​​。​​​

● memory — 这​​​个​​​子​​​系​​​统​​​设​​​定​​​ cgroup 中​​​任​​​务​​​使​​​用​​​的​​​内​​​存​​​限​​​制​​​,并​​​自​​​动​​​生​​​成​​​​​内​​​存​​​资​​​源使用​​​报​​​告​​​。​​​

● net_cls — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​等​​​级​​​识​​​别​​​符​​​(classid)标​​​记​​​网​​​络​​​数​​​据​​​包​​​,可​​​允​​​许​​​ Linux 流​​​量​​​控​​​制​​​程​​​序​​​(tc)识​​​别​​​从​​​具​​​体​​​ cgroup 中​​​生​​​成​​​的​​​数​​​据​​​包​​​。​​​

● net_prio — 这个子系统用来设计网络流量的优先级

● hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。

关于各个子系统的参数细节,以及更多的Linux CGroup的文档,你可以看看下面的文档:

● Linux Kernel的官方文档

● Redhat的官方文档

CGroup的术语

CGroup有下述术语:

● 任务(Tasks):就是系统的一个进程。

● 控制组(Control Group):一组按照某种标准划分的进程,比如官方文档中的Professor和Student,或是WWW和System之类的,其表示了某进程组。Cgroups中的资源控制都是以控制组为单位实现。一个进程可以加入到某个控制组。而资源的限制是定义在这个组上,就像上面示例中我用的haoel一样。简单点说,cgroup的呈现就是一个目录带一系列的可配置文件。

● 层级(Hierarchy):控制组可以组织成hierarchical的形式,既一颗控制组的树(目录结构)。控制组树上的子节点继承父结点的属性。简单点说,hierarchy就是在一个或多个子系统上的cgroups目录树。

● 子系统(Subsystem):一个子系统就是一个资源控制器,比如CPU子系统就是控制CPU时间分配的一个控制器。子系统必须附加到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。Cgroup的子系统可以有很多,也在不断增加中。

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

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

相关文章

能把进程和线程讲的这么透彻的,没有20年功夫还真不行【0基础也能看懂】

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

【verilog】Verilog 中的 ifdef 语法指南:Verilog-2001 与 SystemVerilog

目录 简介 Verilog-2001 中的 ifdef 基本语法 示例 1&#xff1a;Verilog-2001 风格 SystemVerilog 中的 ifdef 基本语法 示例 2&#xff1a;SystemVerilog 风格 示例 3&#xff1a;调试与发布配置 注意事项 简介 在 Verilog 硬件描述语言中&#xff0c;ifdef 是一种…

SQL Server 创建用户并授权

创建用户前需要有一个数据库&#xff0c;创建数据库命令如下&#xff1a; CREATE DATABASE [数据库名称]; CREATE DATABASE database1; 一、创建登录用户 方式1&#xff1a;SQL命令 命令格式&#xff1a;CREATE LOGIN [用户名] WITH PASSWORD 密码; 例如&#xff0c;创建…

Vue项目中禁用ESLint的几种常见方法

1. 通过 vue.config.js 禁用 这是最直接且推荐的方式&#xff0c;因为它直接在Vue CLI的配置中禁用ESLint。通过在项目根目录下创建或修改 vue.config.js 文件&#xff0c;并设置 lintOnSave 为 false&#xff0c;可以彻底禁用保存时的ESLint检查。 // vue.config.js module…

FlinkErr:org/apache/hadoop/hive/ql/parse/SemanticException

在flink项目中跑 上面这段代码出现如下这个异常&#xff0c; java.lang.NoClassDefFoundError: org/apache/thrift/TException 加上下面这个依赖后不报错 <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId…

Python绘制相关系数热力图

相关系数热力图是一种可视化工具&#xff0c;用于展示变量之间的相关性。它在数据分析和统计中非常有用&#xff0c;尤其是在探索数据集的内在关系时。本文将介绍如何使用Python绘制相关系数热力图。 一、准备——导入库 使用Pandas来处理数据&#xff0c;Matplotlib和Seabor…

力扣第233题“数字1的个数”

在本篇文章中&#xff0c;我们将详细解读力扣第233题“数字1的个数”。通过学习本篇文章&#xff0c;读者将掌握如何计算从1到n的数字中出现的“1”的个数&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述 力…

redis笔记2

redis是用c语言写的,放不频繁更新的数据&#xff08;用户数据。课程数据&#xff09; Redis 中&#xff0c;"穿透"通常指的是缓存穿透&#xff08;Cache Penetration&#xff09;问题&#xff0c;这是指一种恶意或非法请求直接绕过缓存层&#xff0c;直接访问数据库或…

力扣 144题 二叉树的前序遍历 记录

题目描述 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]思路 辅助函数 traversal:- 参数: 接受两个参数&#xff0c;一个是指向树节点的指针 cur&#xff08;表示当前访问的节点&#xff09;&…

Qt | 绘制椭圆、弧、弦、扇形、圆角矩形

点击上方"蓝字"关注我们 01、简介 1、需要使用到的 QPainter 类中的函数 2、绘制椭圆的方法有 绘制给定矩形的内接椭圆和根据中心点与椭圆 x 方向和 y 方向的半径绘制,原理见下图 3、绘制弧、弦、扇形的原理: 1)、弧是椭圆上的一段曲线,因此其绘制方法就是首先…

STM32之八:IIC通信协议

目录 1. IIC协议简介 1.1 主从模式 1.2 2根通信线 2. IIC协议时序 2.1 起始条件和终止条件 2.2 发送一个字节 2.3 接收一个字节 2.4 应答信号 1. IIC协议简介 IIC协议是一个半双工、同步、一主多从、多主多从的串行通用数据总线。该通信模式需要2根线&#xff1a;SCL、…

ubuntu22.04安装SecureCRT8.7.3,完成顺利使用

材料准备 scrt-sfx安装包 &#xff0c; securecrt_linux_crack.pl 补丁脚本&#xff0c;和两个依赖库 其中securecrt_linux_crack.pl是找的专门适合 8.7.3版本的&#xff0c;网上很多版本的crack.pl只能打补丁以前的老版本。 而更老版本的SecureCRT对ubuntu22支持更不好&#…

【低照度图像增强系列(8)】URetinex-Net算法详解与代码实现(2022|CVPR)

前言 ☀️ 在低照度场景下进行目标检测任务&#xff0c;常存在图像RGB特征信息少、提取特征困难、目标识别和定位精度低等问题&#xff0c;给检测带来一定的难度。 &#x1f33b;使用图像增强模块对原始图像进行画质提升&#xff0c;恢复各类图像信息&#xff0c;再使用目标检…

hmallox勒索病毒科普:了解其威胁与防御策略

hmallox勒索病毒科普&#xff1a;了解其威胁与防御策略 一、引言 在数字化时代&#xff0c;网络安全威胁日益严峻&#xff0c;勒索病毒作为其中的一类恶意软件&#xff0c;给个人和企业带来了巨大损失。hmallox勒索病毒作为Mallox勒索软件家族的新变种&#xff0c;以其高度的…

求职学习笔记day1

自己一直算是一个内耗拖延的人&#xff0c;内耗着考了研&#xff0c;内耗着拖着不找工作&#xff0c;一直拖到了毕业。研究生没考上&#xff0c;工作没有&#xff0c;也羡慕着别人成功的生活&#xff0c;最后毕业的也不太开心。 一、最近总结 游戏 高考结束以来和大学期间作息…

数据结构之初始二叉树(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 二叉树的前置知识&#xff08;概念、性质、、遍历&#xff09; 通过上篇文章的学习&#xff0c;我们…

TCP/IP中的复用、分解和封装

TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;模型中&#xff0c;复用&#xff08;Multiplexing&#xff09;、分解&#xff08;Demultiplexing&#xff09;和封装&#xff08;Encapsulation&#xff09;是关键概念&#xff0c;它们帮助管理和传输数据在网络上的有效…

【Linux】centos7安装PHP7.4报错:libzip版本过低

问题描述 configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0) were not met: checking for libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0... no configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzi…

Java中线程启动:start()与run()方法的区别

Java中线程启动&#xff1a;start&#xff08;&#xff09;与run&#xff08;&#xff09;方法的区别 1. start()方法2. run()方法3、总结4、示例对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 线程是并发执行的基本单位&#xff0c;而…

Dubbo 的集群容错机制

在分布式系统中&#xff0c;服务的高可用性和容错性是关键因素。阿里巴巴开源的分布式服务框架 Dubbo 提供了强大的集群容错机制&#xff0c;以确保在服务调用过程中即使部分服务实例出现故障&#xff0c;系统依然能稳定运行。本文将详细介绍 Dubbo 的集群容错机制。 一、Dubb…