当前位置: 首页 > news >正文

containerd 之使用 ctr 和 runc 进行底层容器操作与管理

containerd 是目前业界标准的容器运行时,它负责容器生命周期的方方面面,如镜像管理、容器执行、存储和网络等。而 ctr 是 containerd 自带的命令行工具,虽然不如 Docker CLI 用户友好,但它提供了直接与 containerd API 交互的能力,非常适合调试和学习底层机制。runc 则是遵循 OCI (Open Container Initiative) 规范的最常用的容器运行时实现,containerd 默认使用 runc 来创建和运行容器。

本文将结合实际操作日志,带大家深入了解如何使用 ctr 和 runc 进行一些核心的容器操作,包括:

  1. 安装 runc:作为容器执行的基础。
  2. 使用 ctr 实现数据持久化:通过绑定挂载(Bind Mounts)。
  3. 使用 ctr 与私有镜像仓库(如 Harbor)交互:推送与拉取镜像。
  4. 探索 Docker 与 containerd 的关系:理解 Docker 如何利用 containerd

目标读者:对容器底层原理感兴趣的开发者、系统管理员、SRE、Kubernetes 管理员。

一、安装 runC:OCI 容器运行时的基石

runc 是一个轻量级的工具,用于根据 OCI 规范运行容器。containerd 利用 runc 来启动和管理容器进程。通常 containerd 安装时会自带或依赖 runc,但了解如何手动安装或更新它也很有用。

1. 下载 runC 二进制文件

您可以从 runc 的 GitHub Releases 页面找到最新的稳定版本。这里我们以下载 v1.1.12 版本为例:

# 切换到合适的工作目录,例如 /usr/local/bin 或 /tmp
# cd /usr/local/bin# 下载适用于 amd64 架构的 runc 二进制文件
[root@docker102 ~]# wget https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64

参考链接: https://github.com/opencontainers/runc/releases

2. 安装与配置 (最佳实践)

下载后,通常需要进行重命名、移动到系统 $PATH 路径下,并赋予执行权限:

# 重命名
mv runc.amd64 runc# 移动到推荐的路径 (如果不在 /usr/local/bin)
# mv runc /usr/local/bin/# 赋予执行权限
chmod +x runc# 验证安装
runc --version

生产环境提示:建议验证下载文件的 SHA256 校验和,确保文件未被篡改。

二、使用 ctr 实现容器数据持久化 (Bind Mount)

容器默认是无状态的,其文件系统是临时的。当容器被删除时,写入的数据也会丢失。为了持久化数据,需要使用卷(Volume)或绑定挂载(Bind Mount)。ctr 支持通过 --mount 参数实现绑定挂载,将宿主机上的目录或文件挂载到容器内部。

1. 准备镜像和 Namespace

containerd 使用 Namespace 来隔离资源。可以为特定的项目或环境创建 Namespace。

# 查看现有 Namespace
[root@docker102:~]# ctr ns ls
NAME    LABELS
default# 拉取镜像到指定的 Namespace (如果 Namespace 不存在,会自动创建)
# 我们将镜像拉取到 'oldboyedu-linux92' Namespace
[root@docker102:~]# ctr -n oldboyedu-linux92 image pull registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
# ... (省略拉取过程输出)
unpacking linux/amd64 sha256:3ac38ee6161e11f2341eda32be95dcc6746f587880f923d2d24a54c3a525227e...
done: 532.516825ms# 确认 Namespace 已创建
[root@docker102:~]# ctr ns ls
NAME              LABELS
default
oldboyedu-linux92# 查看 Namespace 下的镜像
[root@docker102:~]# ctr -n oldboyedu-linux92 images ls
REF                                                       TYPE                                                 DIGEST                                                                  SIZE    PLATFORMS   LABELS
registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2 application/vnd.docker.distribution.manifest.v2+json sha256:3ac38ee6161e11f2341eda32be95dcc6746f587880f923d2d24a54c3a525227e 9.6 MiB linux/amd64 -

2. 创建带有绑定挂载的容器

使用 ctr container create 命令创建容器定义,并通过 --mount 指定挂载。

# --mount 参数格式: type=bind,src=<host-path>,dst=<container-path>,options=<options>
# options=rbind:rw 表示递归绑定,且读写权限
[root@docker102:~]# ctr -n oldboyedu-linux92 container create \--mount type=bind,src=/oldboyedu/games,dst=/usr/local/nginx/html,options=rbind:rw \registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2 \xiuxian

注意:此时只是创建了容器的元数据,容器进程还未启动。

3. 准备宿主机目录并启动容器任务

绑定挂载需要宿主机上的源路径 (src) 确实存在。

# 创建宿主机上的挂载源目录
[root@docker102:~]# mkdir -pv /oldboyedu/games
mkdir: created directory '/oldboyedu/games'# 启动容器任务 (后台运行 -d)
[root@docker102:~]# ctr -n oldboyedu-linux92 task start -d xiuxian
# ... (容器启动日志)

现在,容器 xiuxian 正在运行,并且宿主机的 /oldboyedu/games 目录已经挂载到了容器内的 /usr/local/nginx/html

4. 验证数据持久化

我们可以在宿主机和容器内分别操作挂载点,验证数据是否同步和持久。

# 在宿主机上放入一个文件
[root@docker102:~]# cp /etc/os-release /oldboyedu/games/# 进入容器内部查看
# ctr task exec [options] <container-id> <command>
# --exec-id $RANDOM: 为 exec 进程指定一个随机 ID
# -t: 分配一个 TTY
[root@docker102:~]# ctr -n oldboyedu-linux92 tasks exec --exec-id $RANDOM -t xiuxian sh
/ # ls -l /usr/local/nginx/html  # 查看挂载点内容,应包含 os-release
total 4
-rw-r--r--    1 root     root           382 Jul 27 08:42 os-release# 在容器内写入数据
/ # echo haha > /usr/local/nginx/html/haha.log
/ # ls -l /usr/local/nginx/html  # 确认写入成功
total 8
-rw-r--r--    1 root     root             5 Jul 27 08:45 haha.log
-rw-r--r--    1 root     root           382 Jul 27 08:42 os-release
/ # exit# 返回宿主机,检查宿主机目录,数据应已同步
[root@docker102:~]# ll /oldboyedu/games/
total 16
drwxr-xr-x 2 root root 4096 Jul 27 16:45 ./
drwxr-xr-x 5 root root 4096 Jul 27 16:40 ../
-rw-r--r-- 1 root root    5 Jul 27 16:45 haha.log  # 容器内写入的文件
-rw-r--r-- 1 root root  382 Jul 27 16:42 os-release # 宿主机放入的文件

5. 清理容器并验证数据保留

删除容器及其任务,验证宿主机上的数据是否依然存在。

# 停止并删除容器任务 (-f 强制删除)
[root@docker102:~]# ctr -n oldboyedu-linux92 tasks rm -f xiuxian
WARN[0000] task xiuxian exit with non-zero exit code 137# 确认任务已删除
[root@docker102:~]# ctr -n oldboyedu-linux92 tasks ls
TASK    PID    STATUS# 删除容器定义
[root@docker102:~# ctr -n oldboyedu-linux92 container rm xiuxian# 确认容器已删除
[root@docker102:~# ctr -n oldboyedu-linux92 container ls
CONTAINER    IMAGE    RUNTIME# 检查宿主机目录,数据仍然存在
[root@docker102:~# ll /oldboyedu/games/
total 16
drwxr-xr-x 2 root root 4096 Jul 27 16:45 ./
drwxr-xr-x 5 root root 4096 Jul 27 16:40 ../
-rw-r--r-- 1 root root    5 Jul 27 16:45 haha.log
-rw-r--r-- 1 root root  382 Jul 27 16:42 os-release

结论:通过绑定挂载,容器的数据成功持久化到了宿主机上,即使容器被删除,数据也不会丢失。这对于需要持久化存储的应用(如数据库、Web 服务器日志、配置文件等)非常关键。

三、使用 ctr 与私有仓库 (Harbor) 交互

在生产环境中,我们通常使用私有镜像仓库(如 Harbor)来存储和分发内部镜像。ctr 也可以配置与这些私有仓库进行交互。

1. 配置 containerd 以信任私有仓库

如果您的私有仓库使用自签名证书或通过 HTTP 提供服务,需要配置 containerd 以信任它。

编辑 containerd 的配置文件 (/etc/containerd/config.toml):

# /etc/containerd/config.toml
# version = 2 # 确保配置格式版本正确# ... 其他配置 ...# [plugins] # 可能在外层或内层,取决于你的 config.toml 结构
#   [plugins."io.containerd.grpc.v1.cri"]
#     [plugins."io.containerd.grpc.v1.cri".registry]
#       [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
#         # 为特定的仓库配置镜像和端点
#         [plugins."io.containerd.grpc.v1.cri".registry.mirrors."10.0.0.101"]
#           # endpoint 指定仓库地址,如果是 HTTP,需要明确写出 http://
#           endpoint = ["http://10.0.0.101"] # 使用 HTTP 协议# 注意: 如果仓库需要认证,还需要配置 auth 部分,例如:
#       [plugins."io.containerd.grpc.v1.cri".registry.configs]
#         [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.101".auth]
#           username = "your_username"
#           password = "your_password"
# 或者使用 Docker 配置文件 (~/.docker/config.json) 中的凭证# ... 其他配置 ...

重要提示

  • 生产环境中强烈建议使用 HTTPS。如果必须使用 HTTP,需要像上面那样配置 endpoint
  • 路径 plugins."io.containerd.grpc.v1.cri" 是针对 CRI 插件的配置,直接使用 ctr 时,可能需要配置在不同的路径下,或者使用更通用的方式,例如:
    [plugins."io.containerd.internal.v1.cri".registry.configs."10.0.0.101".tls]insecure_skip_verify = true
    # 或者对于 registry host 本身
    [plugins."io.containerd.internal.v1.remote".registry.mirrors."10.0.0.101"]endpoint = ["http://10.0.0.101"]
    
    请根据您的 containerd 版本和具体 config.toml 结构调整。最简单的方式通常是在 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 下配置。

2. 重启 containerd 服务

修改配置后,需要重启 containerd 使其生效。

[root@docker102:~]# systemctl restart containerd

3. 标记 (Tag) 镜像

将本地已有的镜像标记为目标私有仓库的地址格式。

# ctr image tag <source-image> <target-image>
# 这里我们将之前拉取的 apps:v1 标记为推送到 Harbor 的路径
# 假设 Harbor 地址是 10.0.0.101,项目是 oldboyedu-games,镜像名是 xiuxian,标签是 v1
[root@docker102:~]# ctr i tag registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 10.0.0.101/oldboyedu-games/xiuxian:v1
10.0.0.101/oldboyedu-games/xiuxian:v1 # 注意:日志中显示 'already exists',可能是之前操作过。正常应无此提示或直接成功。

4. 推送 (Push) 镜像到 Harbor

使用 ctr image push 命令推送镜像。

# --plain-http: 如果仓库使用 HTTP,需要此参数
# -u <username>:<password>: 如果仓库需要认证,需要此参数 (日志中未显示,但通常是必需的)
[root@docker102:~]# ctr i push --plain-http 10.0.0.101/oldboyedu-games/xiuxian:v1 # -u user:pass (如果需要认证)
# ... (省略推送过程输出)
elapsed: 15.1 s  total:  9.4 Mi (636.6 KiB/s)

5. 从 Harbor 拉取 (Pull) 镜像

验证是否可以从私有仓库拉取镜像。

# 先删除本地的对应镜像,以便测试拉取
[root@docker102:~]# ctr i rm 10.0.0.101/oldboyedu-games/xiuxian:v1
# ...# 从 Harbor 拉取
[root@docker102:~]# ctr i pull --plain-http 10.0.0.101/oldboyedu-games/xiuxian:v1 # -u user:pass (如果需要认证)
# ... (省略拉取过程输出)
unpacking linux/amd64 sha256:d9c54b04f7131c9f4e2e18e8d8b438f688533f5df57bce408186f44f01f1f91f...
done

总结:通过修改 containerd 配置并使用 ctr i push/pull 命令,我们可以方便地与私有镜像仓库(包括使用 HTTP 或需要认证的仓库)进行交互。

四、探索 Docker 与 containerd 的关系

现代版本的 Docker 引擎实际上是构建在 containerd 之上的。当我们使用 Docker 命令创建和管理容器时,Docker Daemon 会调用 containerd API 来完成实际的容器生命周期管理。containerd 将这些 Docker 创建的容器放在一个名为 moby 的特定 Namespace 下。

1. 使用 Docker 运行容器

[root@docker102:~]# docker run -d --name c1 registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v3
dd6a8fe737b21c55ce7b86f374e56c25391724f9240ce0ad2dfc7c78e772424f

2. 在 containerd 的 moby Namespace 中观察

我们可以使用 ctr 查看 moby Namespace 中的容器和任务。

# 查看 containerd 的所有 Namespace,确认 'moby' 存在
[root@docker102:~]# ctr ns ls
NAME              LABELS
default
moby
oldboyedu-linux92# 查看 'moby' Namespace 下的容器 (Container ID 通常是 Docker 的长 ID)
[root@docker102:~]# ctr -n moby container ls
CONTAINER                                                           IMAGE    RUNTIME
dd6a8fe737b21c55ce7b86f374e56c25391724f9240ce0ad2dfc7c78e772424f    -        io.containerd.runc.v2# 查看 'moby' Namespace 下的运行中任务 (Task)
[root@docker102:~]# ctr -n moby task ls
TASK                                                                PID       STATUS
dd6a8fe737b21c55ce7b86f374e56c25391724f9240ce0ad2dfc7c78e772424f    633467    RUNNING

3. 验证 PID 和网络

可以看到 ctr 列出的 Task PID 与 docker inspect 获取的容器主进程 PID 是一致的。我们甚至可以用 ctr task exec 进入 Docker 管理的容器。

# 获取 Docker 容器的 PID
[root@docker102:~]# docker inspect -f "{{.State.Pid}}" c1
633467# 使用 ctr 进入 Docker 容器执行命令,查看 IP 地址
[root@docker102:~]# ctr -n moby task exec --exec-id $RANDOM dd6a8fe737b21c55ce7b86f374e56c25391724f9240ce0ad2dfc7c78e772424f ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:14:00:01inet addr:172.20.0.1  Bcast:172.20.0.255  Mask:255.255.255.0...# 使用 docker exec 查看 IP 地址 (结果应相同)
[root@docker102:~]# docker exec c1 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:14:00:01inet addr:172.20.0.1  Bcast:172.20.0.255  Mask:255.255.255.0...

4. Docker 删除容器与 containerd 同步

当使用 Docker 删除容器时,containerd 中对应的 Task 和 Container 也会被清理。

# 使用 Docker 删除容器
[root@docker102:~# docker container rm -f c1
c1# 再次查看 containerd 'moby' Namespace
[root@docker102:~# ctr -n moby task ls
TASK    PID    STATUS
[root@docker102:~# ctr -n moby c ls
CONTAINER    IMAGE    RUNTIME

理解这一点的好处

  • 调试 Kubernetes 节点:Kubernetes (使用 Containerd 作为 CRI 时) 管理的 Pod 和容器也可以通过 ctr 在节点的 k8s.io Namespace 下观察到。这对于排查节点上的 Pod 问题非常有帮助。
  • 理解架构:清晰地看到 Docker 如何作为 containerd 的一个客户端,有助于理解容器生态系统的分层架构。

五、Docker 数据持久化 (Volume) 与 containerd 观察

Docker 提供了卷(Volume)机制来实现数据持久化,这是比绑定挂载更推荐的方式,因为它由 Docker 管理,更易于备份、迁移和跨平台。

1. 使用 Docker 创建带 Volume 的容器

# -v /oldboyedu-data: 这会创建一个 Docker 管理的匿名卷,并挂载到容器的 /oldboyedu-data 目录
# 注意:这不同于 -v /host/path:/container/path (绑定挂载)
[root@docker102:~]# docker run -d --name c1 -p 81:80 -v /oldboyedu-data registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v3
6e29d2aa3fdb4781487712a59d80331c0bf07b30488188c6bd0a1dfd8ef40080

2. 在 containerd 中观察 Task

[root@docker102:~]# ctr -n moby task ls
TASK                                                                PID       STATUS
6e29d2aa3fdb4781487712a59d80331c0bf07b30488188c6bd0a1dfd8ef40080    634196    RUNNING

3. 查找 Docker Volume 在宿主机上的实际路径

Docker Volume 的数据实际存储在宿主机的特定目录下(通常是 /var/lib/docker/volumes/)。

[root@docker102:~]# docker inspect -f "{{range .Mounts}}{{.Source}}{{end}}" c1
/var/lib/docker/volumes/32022aa9c9904e65a7d37c7ae49e48b73118f3b9795c277576cb1cfad15a589e/_data

4. 验证数据持久化 (通过宿主机和 ctr)

# 在宿主机上向 Volume 目录写入文件
[root@docker102:~]# cp /etc/fstab /var/lib/docker/volumes/32022aa9c9904e65a7d37c7ae49e48b73118f3b9795c277576cb1cfad15a589e/_data# 使用 ctr 进入容器,查看挂载点 /oldboyedu-data
[root@docker102:~]# ctr -n moby task exec -t --exec-id $RANDOM 6e29d2aa3fdb4781487712a59d80331c0bf07b30488188c6bd0a1dfd8ef40080 sh
/ # ls /oldboyedu-data/
fstab
/ # exit

对比:虽然最终效果都是持久化,但 Docker Volume 由 Docker 统一管理,与宿主机文件系统耦合度更低;而 ctr 的绑定挂载则直接将宿主机路径映射进容器,更直接但也需要手动管理宿主机路径。

总结

通过本文的实践,我们深入了解了:

  • 如何安装和验证 OCI 运行时 runc
  • 如何使用 ctr 命令行工具,结合 containerd 的 Namespace 概念,管理镜像和容器。
  • 如何利用 ctr 的 --mount 参数实现基于绑定挂载的数据持久化。
  • 如何配置 containerd 并使用 ctr 与私有 HTTP 镜像仓库(如 Harbor)进行交互,包括推送和拉取镜像。
  • Docker 与 containerd 之间的协作关系,以及如何使用 ctr 在 moby Namespace 下观察和操作由 Docker 管理的容器。
  • Docker Volume 持久化方式及其在宿主机上的体现。

虽然 ctr 被定位为面向开发和调试的工具,不如 Docker CLI 或 Podman 那样用户友好,但它提供了一种直接、底层的方式来与 containerd 交互。掌握 ctr 对于理解容器运行时的工作原理、排查 Kubernetes 集群节点问题(当 CRI 为 containerd 时)、或进行特定的底层操作非常有价值。

相关文章:

containerd 之使用 ctr 和 runc 进行底层容器操作与管理

containerd 是目前业界标准的容器运行时&#xff0c;它负责容器生命周期的方方面面&#xff0c;如镜像管理、容器执行、存储和网络等。而 ctr 是 containerd 自带的命令行工具&#xff0c;虽然不如 Docker CLI 用户友好&#xff0c;但它提供了直接与 containerd API 交互的能力…...

IMU 技术概述

IMU&#xff08;惯性测量单元&#xff0c;Inertial Measurement Unit&#xff09;是一种通过传感器组合测量物体运动状态和姿态的核心设备&#xff0c;广泛应用于导航、控制、智能设备等领域。以下从原理、组成、应用和发展趋势展开说明&#xff1a; 一、核心定义与本质 IMU …...

talk-centos6之间实现

在 CentOS 6.4 上配置和使用 talk 工具&#xff0c;需要注意系统版本较老&#xff0c;很多配置可能不同于现代系统。我会提供 详细步骤 自动化脚本&#xff0c;帮你在两台 CentOS 6.4 机器上实现局域网聊天。 ⸻ &#x1f9f1; 一、系统准备 假设你有两台主机&#xff1a; …...

hivesql是什么数据库?

HiveSQL并非指一种独立的数据库&#xff0c;而是指基于Apache Hive的SQL查询语言接口&#xff0c;Hive本身是一个构建在Hadoop生态系统之上的数据仓库基础设施。 以下是对HiveSQL及其相关概念的详细解释&#xff1a; 一、Hive概述 定义&#xff1a; Hive是由Facebook开发&…...

(1)python开发经验

文章目录 1 安装包格式说明2 PySide支持Windows7 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;python开发 &#x1f448; 1 安装包格式说明 PySide下载地址 进入下载地址后有多种安装包&#xff0c;怎么选择&#xff1a; …...

[论文翻译]PPA: Preference Profiling Attack Against Federated Learning

文章目录 摘要一、介绍1、最先进的攻击方式2、PPA3、贡献 二、背景和相关工作1、联邦学习2、成员推理攻击3、属性推理攻击4、GAN攻击5、联邦学习中的隐私推理攻击 三、PPA1、威胁模型与攻击目标&#xff08;1&#xff09;威胁模型&#xff08;2&#xff09;攻击目标 2、PPA 概述…...

北三短报文数传终端:筑牢水利防汛“智慧防线”,守护江河安澜

3月15日我国正式入汛&#xff0c;较以往偏早17天。据水利部预警显示&#xff0c;今年我国极端暴雨洪涝事件趋多趋频趋强&#xff0c;叠加台风北上影响内陆的可能性&#xff0c;灾害风险偏高&#xff0c;防汛形势严峻复杂。面对加快推进“三道防线”建设&#xff0c;提升“四预”…...

函数加密(Functional Encryption)简介

1. 引言 函数加密&#xff08;FE&#xff09;可以被看作是公钥加密&#xff08;PKE&#xff09;的一种推广&#xff0c;它允许对第三方的解密能力进行更细粒度的控制。 在公钥加密中&#xff0c;公钥 p k \mathit{pk} pk 用于将某个值 x x x 加密为密文 c t \mathit{ct} c…...

思维链实现 方式解析

思维链的实现方式 思维链的实现方式除了提示词先后顺序外,还有以下几种: 增加详细的中间步骤提示:通过提供问题解决过程中的详细中间步骤提示,引导模型逐步推导和思考。例如,在解决数学证明题时,提示词可以具体到每一步需要运用的定理、公式以及推理的方向,帮助模型构建…...

深入学习Zookeeper的知识体系

目录 1、介绍 1.1、CAP 理论 1.2、BASE 理论 1.3、一致性协议ZAB 1、介绍 2、角色 3、ZXID和myid 4、 历史队列 5、协议模式 6、崩溃恢复模式 7、脑裂问题 2、zookeeper 2.1、开源项目 2.2、功能 2.3、选举机制 3、数据模型 3.1、介绍 3.2、znode分类 4、监听…...

电商平台一站式安全防护架构设计与落地实践

引言&#xff1a;安全即业务&#xff0c;防御即增长 国际权威机构 Forrester 最新报告指出&#xff0c;2024 年全球电商平台因安全防护不足导致的直接营收损失高达 $180 亿&#xff0c;而采用一体化防护方案的头部企业客户留存率提升 32%。本文基于 10 万 节点防护实战数据&a…...

【Pandas】pandas DataFrame cummin

Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每个元素的绝对值DataFrame.all([axis, bool_only, skipna])用于判断 DataFrame 中是否所有元素在指定轴上都为 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判断…...

奇妙小博客

import matplotlib.pyplot as plt# 定义顶点坐标 A [0, 0] B [6, 1] C [4, 6] P [4, 3]# 绘制三角形 ABC plt.plot([A[0], B[0], C[0], A[0]], [A[1], B[1], C[1], A[1]], b-, labelTriangle ABC) # 绘制点 P plt.scatter(P[0], P[1], colorr, labelPoint P(4,3))# 标注顶点…...

嵌入式学习笔记 - HAL_ADC_ConfigChannel函数解析

贴函数原型&#xff1a; 一 首先配置规则通道序列 其实所有的配置函数都是在对寄存器进行操作&#xff0c;要想看懂Hal库底层函数驱动就先把寄存器如何配置看懂&#xff0c;以下是配置规则通道寄存器的介绍&#xff0c;以ADC_SQR3为例&#xff0c;也就是通道序列1到序列6&…...

Java反射详细介绍

的反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时动态获取类的信息、操作类的成员&#xff08;属性、方法、构造器&#xff09;&#xff0c;甚至修改类的行为。它是框架开发&#xff08;如 Spring、MyBatis&#xff09;、单元测试工具&a…...

2025年土木建筑与水利工程国际会议(ICCHE 2025)

2025 International Conference on Civil and Hydraulic Engineering (ICCHE 2025) &#xff08;一&#xff09;会议信息 会议简称&#xff1a;ICCHE 2025 大会地点&#xff1a;中国银川 投稿邮箱&#xff1a;icchesub-paper.com 收录检索&#xff1a;提交Ei Compendex,CPCI,C…...

适应性神经树:当深度学习遇上决策树的“生长法则”

1st author: Ryutaro Tanno video: Video from London ML meetup paper: Adaptive Neural Trees ICML 2019 code: rtanno21609/AdaptiveNeuralTrees: Adaptive Neural Trees 背景 在机器学习领域&#xff0c;神经网络&#xff08;NNs&#xff09;凭借其强大的表示学习能力&…...

IBM BAW(原BPM升级版)使用教程第十四讲

续前篇&#xff01; 一、流程设计中的编程 在 IBM Business Automation Workflow (BAW) 中&#xff0c;编程部分涵盖了多种技术、工具和策略&#xff0c;帮助用户定制和扩展流程。BAW 主要通过脚本、集成、服务和自定义代码来实现流程的灵活性和定制化。下面将详细讲解 BAW …...

【计算机网络 第8版】谢希仁编著 第四章网络层 题型总结3 SDN OpenFlow

SDN OpenFlow题型 这题其实&#xff0c;认真看书P196-197的例子也不难理解。我个人认为所谓防自学设计主要就是你没看懂这张图的时候就是天书&#xff0c;你知道怎么读这张图的时候就很简单。不过我相信这个用心一点应该也都是能懂的。 题目 4.66-4.69 4-66 我最大的一个问题…...

【React中函数组件和类组件区别】

在 React 中,函数组件和类组件是两种构建组件的方式,它们在多个方面存在区别,以下详细介绍: 1. 语法和定义 类组件:使用 ES6 的类(class)语法定义,继承自 React.Component。需要通过 this.props 来访问传递给组件的属性(props),并且通常要实现 render 方法返回 JSX…...

多线程代码案例-1 单例模式

单例模式 单例模式是开发中常见的设计模式。 设计模式&#xff0c;是我们在编写代码时候的一种软性的规定&#xff0c;也就是说&#xff0c;我们遵守了设计模式&#xff0c;代码的下限就有了一定的保证。设计模式有很多种&#xff0c;在不同的语言中&#xff0c;也有不同的设计…...

langChain存储文档片段,并进行相似性检索

https://python.langchain.ac.cn/docs/how_to/document_loader_pdf/#vector-search-over-pdfs 这段代码展示了如何使用LangChain框架中的InMemoryVectorStore和OpenAIEmbeddings来存储文档片段&#xff0c;并基于提供的查询进行相似性搜索。下面是对每一行代码的详细解释&…...

MQTT协议技术详解:深入理解物联网通信基础

MQTT协议技术详解&#xff1a;深入理解物联网通信基础 1. MQTT协议概述 MQTT (Message Queuing Telemetry Transport) 是一种轻量级的发布/订阅消息传输协议&#xff0c;专为资源受限设备和低带宽、高延迟或不可靠网络环境设计。作为物联网通信的核心协议之一&#xff0c;MQTT…...

python中的进程锁与线程锁

在Python中&#xff0c;线程和进程使用锁的机制有所不同&#xff0c;需分别通过threading和multiprocessing模块实现。以下是具体用法及注意事项&#xff1a; 一、线程锁&#xff08;Thread Lock&#xff09; 基本用法 线程锁用于多线程环境下保护共享资源&#xff0c;防止数据…...

导出导入Excel文件(详解-基于EasyExcel)

前言&#xff1a; 近期由于工作的需要&#xff0c;根据需求需要导出导入Excel模板。于是自学了一下下&#xff0c;在此记录并分享&#xff01;&#xff01; EasyExcel&#xff1a; 首先我要在这里非常感谢阿里的大佬们&#xff01;封装这么好用的Excel相关的API&#xff0c;真…...

仿正点原子驱动BMP280气压传感器实例

文章目录 前言 一、寄存器头文件定义 二、设备树文件中添加节点 三、驱动文件编写 四、编写驱动测试文件并编译测试 总结 前言 本文驱动开发仿照正点原子的iic驱动实现&#xff0c;同时附上bmp280的数据手册&#xff0c;可访问下面的链接&#xff1a; BMP280_Bosch(博世…...

Java 反射机制(Reflection)

一、理论说明 1. 反射的定义 Java 反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法的功能称为 Jav…...

每日Prompt:发光线条解剖图

提示词 一幅数字插画&#xff0c;描绘了一个 [SUBJECT]&#xff0c;其结构由一组发光、干净且纯净的蓝色线条勾勒而成。画面设定在深色背景之上&#xff0c;以突出 [SUBJECT] 的形态与特征。某个特定部位&#xff0c;如 [PART]&#xff0c;通过红色光晕加以强调&#xff0c;以…...

从新手到高手:全面解析 AI 时代的「魔法咒语」——Prompt

引言&#xff1a;AI 时代的「语言炼金术」 在人工智能技术突飞猛进的今天&#xff0c;我们正在经历一场堪比工业革命的生产力变革。从聊天机器人到图像生成&#xff0c;从数据分析到自动化写作&#xff0c;AI 模型正在重塑人类与信息交互的方式。而在这一切背后&#xff0c;隐…...

【SpringBoot】集成kafka之生产者、消费者、幂等性处理和消息积压

目录 配置文件 application.properties启动类 ApplicationKafka 配置Message 消息实体类MessageRepository 消息处理消息积压监控服务Kafka消息消费者服务Kafka消息生产者服务API控制器提供测试接口关键特性说明生产环境建议 配置文件 application.properties # 应用配置 serv…...

[SAP] 通过事务码Tcode获取程序名

如何通过事务码查找对应的程序名&#xff1f; 方法一&#xff1a;直接运行事务码&#xff0c;跳转至功能详情页面&#xff0c;点击【系统】|【状态】即可获取对应事务码的程序名 从上面可以了解到自定义的事务码"ZMM01"对应的程序名为"ZYT36_ZMM001_01"&a…...

蓝桥杯12届国B 纯质数

题目描述 如果一个正整数只有 1 和它本身两个约数&#xff0c;则称为一个质数&#xff08;又称素数&#xff09;。 前几个质数是&#xff1a;2,3,5,7,11,13,17,19,23,29,31,37,⋅⋅⋅ 。 如果一个质数的所有十进制数位都是质数&#xff0c;我们称它为纯质数。例如&#xff1…...

国产大模型「五强争霸」,决战AGI!

来源 | 新智元 DeepSeek的横空出世&#xff0c;已经彻底改变了全球的AI局势。 从此&#xff0c;不仅中美大模型竞争格局改变&#xff0c;国产大模型的产业版图&#xff0c;也被一举打破&#xff01; 纵观中国基础大模型的市场&#xff0c;可以看到&#xff0c;如今的基础大模…...

C++修炼:继承

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞&#xff0c;关注&am…...

Mysql新增

插入一个记录需要的时间由下列因素组成&#xff0c;其中的数字表示大约比例&#xff1a; 连接&#xff1a;(3)发送查询给服务器&#xff1a;(2)分析查询&#xff1a;(2)插入记录&#xff1a;&#xff08;1x记录大小&#xff09;插入索引&#xff1a;&#xff08;1x索引&#x…...

华秋2025电子设计与制造技术研讨会(华东站)成功举办!

“探索科技前沿&#xff0c;共筑创新未来”——华秋“2025电子设计与制造技术研讨会第一站&#xff1a;华东站”在江苏苏州圆满落幕。 随着电子信息产业的持续增长和数字化经济的加速转型&#xff0c;数字化电子供应链的作用愈发显著。本届研讨聚焦EDA设计、DFM软件分析、多层…...

[学习] RTKLib详解:qzslex.c、rcvraw.c与solution.c

RTKLib详解&#xff1a;qzslex.c、rcvraw.c与solution.c 本文是 RTKLlib详解 系列文章的一篇&#xff0c;目前该系列文章还在持续总结写作中&#xff0c;以发表的如下&#xff0c;有兴趣的可以翻阅。 [学习] RTKlib详解&#xff1a;功能、工具与源码结构解析 [学习]RTKLib详解…...

【Ubuntu】neovim Lazyvim安装与卸载

安装neovim # 下载 AppImage wget https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.appimage# 添加执行权限 chmod ux nvim-linux-x86_64.appimage# 移动到系统路径&#xff0c;重命名为 nvim sudo mv nvim-linux-x86_64.appimage /usr/local/b…...

数据结构(一) 绪论

一. 时间复杂度: (1)定义: 时间复杂度是衡量算法执行时间随输入规模(通常用n表示)增长的变化趋势的指标,时间复杂度用O符号表示 用于描述算法在最坏情况下或平均情况下的时间需求 时间复杂度关注的是操作次数的增长率&#xff0c;而非具体执行时间 常见的时间复杂度由小到大依次…...

数据库事务并发问题

目录 脏读 幻读 不可重复读 三者的区别 脏读、幻读和不可重复读是在数据库并发操作中可能出现的问题&#xff0c;以下是对它们的详细介绍&#xff1a; 脏读 定义&#xff1a;指一个事务读取了另一个未提交事务修改的数据。示例&#xff1a;事务 A 修改了一条数据&#xf…...

Android之横向滑动列表

文章目录 前言一、效果图二、使用步骤1.xml布局2.代码3.HomeHxBean3.adapter4.item布局5.两个drawable 总结 前言 横向滑动列表有多种实现方式&#xff0c;也可以用tablayout&#xff0c;也可以用recyclerview&#xff0c;今天主要介绍recyclerview。 一、效果图 二、使用步骤…...

系统稳定性之上线三板斧

&#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》&#xff08;基础篇&#xff09;、&#xff08;进阶篇&#xff09;、&#xff08;架构篇&#xff09;清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…...

aardio - godking.vlistEx.listbar + win.ui.tabs 实现多标签多页面切换

方法一&#xff1a; import win.ui; import godking.vlistEx.listbar; import fonts.fontAwesome; /*DSG{{*/ mainForm win.form(text"vlistEx - table adapter";right895;bottom503) mainForm.add({ custom{cls"custom";text"自定义控件";lef…...

鸿蒙 核心与非核心装饰器

HarmonyOS NEXT 版本中完整的 ArkTS 装饰器分类整理&#xff08;含核心与非核心装饰器&#xff0c;已剔除废弃特性&#xff09; 一、核心装饰器&#xff08;Essential Decorators&#xff09; 1. 组件基础 装饰器功能Entry应用入口组件&#xff0c;每个模块必须且仅有一个&am…...

TypeScript 知识框架

一、TypeScript 基础 1. 类型系统 基本类型: number, string, boolean, null, undefined, symbol, bigint 引用类型: object, array, function, class 特殊类型: any, unknown, void, never 类型推断与类型注解 类型断言 (as 语法和 <Type> 语法) 2. 接口与类型别名 接口…...

web-ui开源程序是建立在浏览器使用的基础上,旨在使 AI 代理可以访问网站

​一、软件介绍 文末提供程序和源码下载 web-ui开源程序是建立在浏览器使用的基础上&#xff0c;旨在使 AI 代理可以访问网站。WebUI&#xff1a;基于 Gradio 构建&#xff0c;支持大部分 browser-use 功能。此 UI 设计为用户友好型&#xff0c;并支持与浏览器代理轻松交互。扩…...

【ns3】TCP三次握手源码解析

文章目录 TCP三次握手过程三次握手源码 TCP三次握手过程 三次握手源码 下面是ns3里三次握手整体过程的源码&#xff0c;和上面图解一一对应&#xff1a; TCP socket的状态枚举&#xff1a; 整体过程&#xff1a; 客户端首先connect&#xff1a;tcp-socket-base::connect调用Do…...

【YOLO模型】参数全面解读

使用YOLO模型时&#xff0c;需要调节各种参数&#xff0c;网络文章和官方文档有点不方便&#xff0c;整理了下面的内容备用&#xff1a; 获取最全最新的参数列表: Ultralytics官方文档: 这是获取YOLOv11&#xff08;以及YOLOv8等&#xff09;最权威、最详细参数信息的地方。通…...

跨境电商定价革命:亚马逊“逆向提价“策略背后的价值重构逻辑

导言&#xff1a;打破价格魔咒的销量奇迹 2024年Q3亚马逊平台上演商业悖论&#xff1a;在TOP5000卖家中&#xff0c;12%实施5%-15%温和提价的商户&#xff0c;41%实现单量30.4%的季度增长。这一现象颠覆"低价即流量"的电商铁律&#xff0c;揭开新消费时代"价值定…...

Kafka、RabbitMQ、RocketMQ的区别

以下是 RabbitMQ、RocketMQ、Kafka 的核心区别对比&#xff1a; 一、架构设计差异 ‌Kafka‌ 基于分布式日志的发布-订阅模型&#xff0c;通过分区&#xff08;Partition&#xff09;实现水平扩展&#xff0c;依赖 ZooKeeper 管理集群消费者通过消费者组&#xff08;Consumer G…...