详解 Docker 启动 Windows 容器第二篇:技术原理与未来发展方向

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 所遇问题
    • 问题 1:Docker 容器启动的 Windows 实例调用了 KVM 驱动,但为什么用 `virsh list` 命令查不到虚拟机?这意味着它不是一个完整的虚拟机吗?
    • 问题 2:为什么通过 docker stats 查看时显示的是容器占用内存,而不是虚拟机的内存占用?
    • 问题 3:Linux 上使用 KVM 启动一个 Windows 虚拟机和通过容器启动一个虚拟机的区别(调用 KVM 驱动)
    • 问题 4:为什么在Linux上通过容器启动Windows(KVM)和Linux后,容器内部的网络表现不同?
  • 未来方向探讨
    • 1. 简化虚拟化管理:砍掉OpenStack和VMware
    • 2. Windows服务容器化部署
    • 3. Windows 容器结合 AD 实现私有云弹性使用
    • 4. 优化审计工具成本
    • 5. 网络管控统一化
    • 6. 简化高可用架构
  • 总结


前言

在通过 Docker 启动 Windows 容器的过程中,我对其调用 KVM 驱动的工作原理还不够了解。尤其是与传统虚拟化技术(如 libvirt)相比,这种方法的特殊性让我产生了许多疑问。在查阅了大量资料后,我整理出了一些问题及其解答,希望能帮助对这个话题感兴趣的朋友更好地理解 Docker 容器与虚拟化技术结合的独特之处。

所遇问题

问题 1:Docker 容器启动的 Windows 实例调用了 KVM 驱动,但为什么用 virsh list 命令查不到虚拟机?这意味着它不是一个完整的虚拟机吗?

解答:

  1. 为什么 virsh list 查不到虚拟机?
  • virsh list 的工作机制:
    virsh list 是用来管理和查看由 libvirt 管理的虚拟机的工具。如果虚拟机不是通过 libvirt 创建和管理的,virsh 是无法检测到它的。

  • - 
    

    在 Docker 容器中启动 Windows 实例时,通过挂载 /dev/kvm 与宿主机的 KVM 模块直接交互。这个过程绕过了 libvirt,而是可能通过 QEMU + KVM 的方式直接实现硬件虚拟化支持。

因此,virsh 无法列出这些由 Docker 启动的虚拟机实例,因为它们并未被 libvirt 管理。

  1. 这是不是一个完整的虚拟机?
    从严格意义上来说,它并不是传统的「完整虚拟机」,而是介于虚拟机和容器之间的一种轻量化虚拟化实现。
  • 容器化特性:

    • 使用 Docker 技术进行管理,具备容器的轻量化特性。
    • 配置文件中使用了 Docker 的 portscap_add 等功能,属于典型的容器管理方式。
  • 虚拟化特性:

    • 通过 /dev/kvm 使用硬件虚拟化技术,运行了一个独立的 Windows 操作系统实例。
    • 使用了 KVM 提供的虚拟化支持,底层依赖 QEMU 等虚拟化工具。
  • 综合判断:

    • 这类 Windows 容器可以视为一个「通过容器运行的轻量化虚拟机」,但它并没有完整的虚拟机管理功能(如快照、热迁移等)。
  1. 这种实现的工作原理是什么?

    QEMU + KVM 支持:

    • 容器内部可能使用了 QEMU,KVM 提供了硬件虚拟化的加速支持。QEMU 作为用户态应用,借助 /dev/kvm 完成高效的虚拟机运行。

    Docker 容器管理:

    • Docker 负责通过容器技术挂载宿主机的 /dev/kvm,使容器能够访问硬件虚拟化能力。
    • 容器的网络、端口映射、设备挂载等由 Docker 提供支持。
  2. 这种方式的优缺点是什么?

  • 优点:

    • 部署简单: 利用 Docker,能够快速启动和管理虚拟化实例。
    • 轻量化: 不需要额外安装 libvirt 或其他传统虚拟化管理工具。
    • 灵活性高: 可以结合 Docker 的生态系统,如镜像管理、自动化部署等功能。
  • 缺点:

    • 管理不便: 传统虚拟机管理工具(如 virsh 或 vSphere)无法直接管理这些实例。
    • 功能限制: 无法支持复杂的虚拟化场景,例如快照、热迁移等功能。
    • 性能可能受限: 与直接使用 KVM 或 libvirt 的传统虚拟机相比,可能会有一些性能开销。

Docker 容器中运行的 Windows 实例并非传统意义上的虚拟机,而是通过容器技术实现的轻量化虚拟化。它通过 KVM 提供硬件支持,同时利用 Docker 的容器生态完成管理和部署。

这种方式适用于轻量级需求,例如快速启动虚拟化实例或实验环境。但如果需要更强大的功能(如快照、热迁移或集中管理),建议使用 libvirt、vSphere 或 OpenStack 等专业虚拟化平台。

对于开发者来说,理解这种轻量化虚拟化技术的工作原理,可以更好地权衡性能与功能需求,在适合的场景中高效利用 Docker 与虚拟化技术结合的优势。

问题 2:为什么通过 docker stats 查看时显示的是容器占用内存,而不是虚拟机的内存占用?

docker stats 报告的是容器的内存占用,而非虚拟机(通过 KVM 驱动运行的 Windows 系统)的内存。这其中的关键就在于 Docker 的资源管理方式和虚拟化的底层原理。

  1. 为什么 docker stats 显示的是容器占用内存?
    Docker 通过 CGroup(控制组) 对容器的资源进行限制和统计管理。无论容器内部运行的是普通进程,还是像虚拟机这样的特殊应用,其资源消耗都会被归类到该容器中。更具体地说:
  • 容器中的 QEMU 进程: 用于运行虚拟机的 QEMU 本质上是一个普通的用户态进程,运行在 Docker 容器中。

  • 容器进程封装性: Docker 容器将 QEMU 等进程打包运行,而 docker stats 监控的正是这些容器中进程的资源消耗。

  • Docker 的监控逻辑: 容器并不知道它运行的是虚拟机,因此 docker stats 中显示的内存占用,实际上是:

    QEMU 分配的内存 + 容器内其他进程占用的内存

  1. 为什么虚拟机的内存消耗归类到容器中?
    虚拟机的运行依赖于 QEMU + KVM。其中:
  • KVM 的角色:

    • KVM 是一个 Linux 内核模块,用于提供硬件虚拟化支持。它本身不会主动分配内存,而是通过宿主机硬件支持 QEMU 来完成虚拟化任务。
    • 因此,KVM 的工作更多是“桥梁”,并不直接产生显性内存开销。
  • QEMU 的角色:

    • QEMU 是虚拟机运行的核心进程,负责实际分配内存和处理虚拟化指令。
    • QEMU 的内存分配会被 CGroup 统计为容器资源开销的一部分,所以我们在 docker stats 中看到的是容器的总内存占用。
  1. 内存占用的分配和流向

假设你为虚拟机分配了 2GB 内存,并通过 Docker 启动:

  • 容器进程的内存分配:

    • QEMU 进程分配了虚拟机的 2GB 内存;
    • 其他容器中运行的进程(如网络工具)也会消耗部分内存。
  • docker stats 的内存显示:

    • 显示的是容器中所有进程的内存消耗总和(包括 QEMU 和其他进程)。
  1. 如何验证虚拟机的实际内存占用?

如果你想具体查看虚拟机的内存使用情况,可以尝试以下方法:
方法 1:宿主机查看容器内进程的内存

在宿主机上,找到容器中的 QEMU 进程,并检查其内存消耗:

ps aux | grep qemu

然后使用 tophtop 工具,观察 QEMU 进程的实际内存占用。

方法 2:容器内部查看 QEMU 的内存

进入容器内部,使用类似 tophtop 的工具查看 QEMU 占用的内存:

docker exec -it <容器ID> bash
top

方法 3:虚拟机内部查看

登录虚拟机(例如通过 RDP),在虚拟机内查看内存使用情况:

  • Windows 虚拟机: 通过任务管理器查看分配的物理内存。
  • Linux 虚拟机: 使用 free -mtop 等工具查看内存分配。
  1. 优缺点分析
优点缺点
部署简单:通过 Docker 管理虚拟机,快速启动和停止管理复杂:虚拟机内存统计需要跨层查看
资源整合:使用 Docker 的 CGroup 统一统计资源难以实现传统虚拟机功能(如快照、热迁移等)
部署简单:通过 Docker 管理虚拟机,快速启动和停止管理复杂:虚拟机内存统计需要跨层查看

总的来说:

  • docker stats 显示的内存占用,是 容器内所有进程的总和,包括 QEMU 等虚拟机相关进程的资源消耗。
  • KVM 本身不会直接占用内存,它只是虚拟机运行的硬件支持模块。
  • 如果需要精确统计虚拟机内存,可以通过容器或虚拟机内的工具进行具体分析。

这种 Docker 和虚拟化结合的方式,虽然不是传统意义上的完整虚拟机,但它在轻量化部署和资源管理上提供了很高的灵活性,非常适合场景化需求。

问题 3:Linux 上使用 KVM 启动一个 Windows 虚拟机和通过容器启动一个虚拟机的区别(调用 KVM 驱动)

它涉及两种不同虚拟化方式的架构、功能、性能和使用场景上的区别。以下从多个角度对比两种方式:直接使用 KVM 启动虚拟机通过容器启动虚拟机

  1. 架构区别
    直接使用 KVM 启动虚拟机
  • 架构

    • 利用 Linux 内核中的 KVM 模块和用户态的 QEMU 模拟器,在宿主机上直接运行虚拟机。
    • KVM 提供硬件加速,QEMU 负责虚拟机管理和硬件模拟。
  • 管理工具

    • 常用 virsh、virt-manager 等工具管理虚拟机,依赖 libvirt 提供标准化 API,支持快照、热迁移等高级功能。
  • 资源隔离

    • 资源由 KVM 和 QEMU 完全管理,宿主机的 CGroup 通常不直接作用于虚拟机。

通过容器启动虚拟机

  • 架构

    • 使用 Docker 容器运行虚拟化环境,容器内部运行 QEMU,利用 KVM 驱动启动虚拟机。
    • 容器本身提供资源隔离和运行环境封装,虚拟机运行在容器之内。
  • 管理工具

    • 使用 Docker 命令(如 docker-compose 或 docker run)管理虚拟机的生命周期,轻量级且无需 libvirt。
  • 资源隔离

    • 容器利用 CGroup 实现资源限制(如内存、CPU 等),虚拟机的资源分配受到容器的约束。
  1. 功能和性能对比
    功能对比
功能直接使用 KVM 启动虚拟机容器启动虚拟机
管理方式通过 virshvirt-manager 提供完整虚拟化功能(如快照、热迁移等)。使用 Docker 命令,管理简单但功能有限。
隔离性虚拟机拥有完整的硬件资源隔离,隔离性强。容器和虚拟机共享部分资源,隔离性稍弱。
扩展性可扩展性强,可与 OpenStack 等云平台集成。适合轻量级部署,扩展性依赖 Docker。
便捷性部署复杂,需要配置 libvirt 和 KVM 依赖。部署简单,快速与容器化应用整合。
网络配置支持复杂的网络配置(如多网卡、VLAN 隔离)。受限于 Docker 网络模式,网络功能稍弱。

性能对比

性能指标直接使用 KVM 启动虚拟机容器启动虚拟机
CPU 性能依赖 KVM 和 QEMU,性能接近裸机。性能相当,容器增加的开销很小。
内存管理内存直接由 KVM 和 QEMU 管理,效率更高。内存由容器分配,增加了一层抽象,但影响微小。
I/O 性能I/O 性能接近裸机,硬件直通能力强。略有性能损耗,受限于容器文件系统(如 overlayfs)。
启动速度启动稍慢,需要加载完整虚拟机环境。启动更快,受益于 Docker 的轻量化特性。
  1. 使用场景对比
    直接使用 KVM 启动虚拟机的适用场景
  • 传统虚拟化需求
    • 云平台(如 OpenStack)、生产环境中的高性能虚拟化部署。
    • 需要支持快照、热迁移、硬件直通等功能。
  • 性能优先场景
    • I/O 密集型任务(如数据库、大数据分析)需要接近裸机性能。
  • 复杂网络需求
    • 支持自定义网络配置(如多网卡、VLAN、桥接网络)。

容器启动虚拟机的适用场景

  • 轻量化需求
    • 运行特定版本的 Windows 系统以完成简单测试任务。
    • 快速部署和销毁虚拟机实例。
  • 容器化生态
    • 集成到现有容器化应用中,享受容器生态的便利性(如镜像管理、快速部署)。
  • 开发与测试环境
    • 通过 Docker Compose 等工具快速管理虚拟机的生命周期。
  1. 优缺点总结
优缺点直接使用 KVM 启动虚拟机容器启动虚拟机
优点高性能,功能全面,支持复杂场景。部署轻量、管理简单,符合容器生态。
缺点部署复杂,依赖更多工具(如 libvirt)。功能有限,不适合复杂需求场景。

总的来说:

  • 直接使用 KVM 启动虚拟机: 适合需要完整虚拟化功能、高性能和复杂场景的应用,如企业级云平台部署、I/O 密集型任务和复杂网络配置。
  • 容器启动虚拟机: 适合轻量化需求、快速部署和测试环境,尤其是在容器生态中集成虚拟机的场景。

选择的关键在于场景需求。如果需要快速实验或轻量管理,容器启动虚拟机更方便;而对于复杂功能和高性能要求,直接使用 KVM 是更优选择。

问题 4:为什么在Linux上通过容器启动Windows(KVM)和Linux后,容器内部的网络表现不同?

在容器中启动 Windows,使用 docker inspect 命令显示 Windows 容器获取的 IP 地址是127.19.0.2,Web 或 远程方式访问 Windows 容器显示 IP 地址却是 20.20.20.21,网关是20.20.20.1
用同样的方式容器中启动 Linux,使用 docker inspect 命令显示 IP 地址是127.19.0.3,进入 Linux 容器显示的 IP 地址也是 127.19.0.3

两容器内部均能 ping 通宿主机 IP,但是宿主机不能 ping 通 20.20.20.21 和 20.20.20.1 ,可以ping通 127.19.0.3(Linux) 和 127.19.0.2(Windows)

  1. 网络结构差异
  • Linux 容器: 使用的是 Docker 的网络模式(例如 bridge 模式),容器的虚拟网络接口直接桥接到 Docker 的虚拟网桥(docker0)上,默认情况下与宿主机连通。
  • Windows 容器(虚拟机): 由 KVM 使用 QEMU 创建虚拟机,虚拟机内部的网卡由 QEMU 模拟,虚拟机网络默认是隔离的,宿主机与虚拟机之间需要额外配置转发或桥接才能通信。
  1. 容器和宿主机的通信情况
行为Windows 容器Linux 容器
宿主机能否 ping 通容器否(需要手动配置桥接或 NAT)是(默认连通)
容器能否 ping 通宿主机是(QEMU 提供 NAT 转发)是(默认连通)
  • 宿主机无法 ping 通虚拟机(Windows 容器):

    • 原因在于虚拟机使用的是独立的虚拟网络(QEMU 提供),默认没有配置从宿主机到虚拟机的流量转发。
    • 而 Linux 容器的网络则直接使用 Docker 分配的网络,因此宿主机可以直接与容器通信。
  • 容器都能 ping 通宿主机:

    • Windows 容器 通过 QEMU 的 NAT 转发机制,将虚拟机内流量映射到宿主机网络上。
    • Linux 容器 通过 Docker 网桥直接与宿主机网络相连,因此可以通信。
  1. 为什么进入 Windows 容器看到的 IP 是不同的?
  • Windows 容器(虚拟机)由 QEMU 创建的独立虚拟网络提供 IP 地址(例如 20.20.20.21),与 Docker 的网络配置无关。
  • 而 Linux 容器使用 Docker 管理网络,因此看到的 IP 地址与 Docker 分配的地址一致。
  1. 让宿主机可以 ping 通 Windows 容器

以下是几种可行的调整方式:
方案 1:配置桥接模式

将虚拟机的网络直接桥接到宿主机的物理网卡,使虚拟机与宿主机使用相同的物理网络。

示例命令(调整为你的网络环境):

qemu-system-x86_64 \-net nic \-net bridge,br=br0 \...

注意:需要确保宿主机上已创建桥接接口(例如 br0),并正确配置物理网卡桥接到该接口。

方案 2:配置 NAT 转发规则

使用 iptables 将宿主机流量转发到虚拟机的 IP 地址:

# 假设 tap 设备为 tap0,虚拟机 IP 为 20.20.20.21
iptables -t nat -A PREROUTING -d 20.20.20.21 -j DNAT --to-destination tap0

注意:需要确认虚拟机的网络接口(tap 设备)名称。

方案 3:使用 QEMU 用户网络

启用 QEMU 提供的 -net user 模式,QEMU 会自动配置 NAT,使宿主机可以访问虚拟机。 示例命令:

qemu-system-x86_64 \-net nic \-net user,hostfwd=tcp::2222-:22 \...

解释:hostfwd=tcp::2222-:22 将宿主机 2222 端口的 SSH 流量转发到虚拟机的 22 端口。

  1. 补充说明
  • 为什么设计成这样?

    • 虚拟机 的网络隔离性更强,适合需要独立网络环境的场景,例如模拟独立主机环境或隔离安全风险。
    • 容器 的网络更贴近宿主机,便于轻量化通信和快速部署。
  • 如何选择配置方案?

    • 如果需要让宿主机与虚拟机频繁通信,推荐使用 桥接模式。
    • 如果仅需要简单访问,可以使用 NAT 转发 或 用户网络模式。
  • 性能与安全性权衡

    • 桥接模式 性能较高,但需要确保宿主机网络配置安全。
    • NAT 模式 或 用户网络模式 更安全,但可能会有一定的性能损耗。

未来方向探讨

1. 简化虚拟化管理:砍掉OpenStack和VMware

除非有快照等特殊需求必须要使用到虚拟机,否则可以直接采用 Ceph + Kubernetes + Windows容器 的组合方案。Windows容器中的数据可以通过持久化存储(Ceph)来管理,减少对复杂虚拟化平台的依赖。

2. Windows服务容器化部署

对于必须部署在 Windows 上的服务(如 SQL Server、IIS 等),可以通过 Windows 容器进行部署。这样只需维护 Windows 容器的持久化数据即可,服务可以实现一键式部署和启动,降低运维复杂度。

3. Windows 容器结合 AD 实现私有云弹性使用

  • Windows 容器接入 Windows AD 后,可以将容器直接分配给用户使用,实现私有云办公环境。
  • 在需要时,通过启动新的 Windows 容器为用户分配资源,支持弹性升级配置,用户数据通过持久化存储保证安全可靠。
  • 不需要时,可以关闭容器以减少资源消耗,提高系统效率。

4. 优化审计工具成本

如果公司引入了审计工具(如 IPG),该方案可以在一定程度上减少 IPG License 的数量需求。原因是部分用户处于等待状态时无需立即分配 Windows 容器,只需在使用时动态启动。

5. 网络管控统一化

通过 Kubernetes 接管 Windows 容器的网络管理,消除 VLAN 的概念,网络管理更加高效和简洁。

6. 简化高可用架构

最终的高可用架构只需重点管理 Ceph 和 Kubernetes 两个核心系统即可,极大地减少了管理的复杂度和运维工作量。

目前尚未进行实际环境搭建测试,但根据上述方案,构建一套全新的 HCI 高可用架构,在网络、性能和稳定性方面应该是可行的。

总结

这篇博文我们讨论了如何通过 Ceph + Kubernetes + Windows 容器 来优化现有的虚拟化和容器化架构。相比传统的 OpenStack 和 VMware,使用 Kubernetes 管理 Windows 容器不仅能减少不必要的资源浪费,还能简化整个系统的运维。

通过这种方式,我们可以轻松地将 SQL Server、IIS 等 Windows 服务容器化,并实现一键式部署和启动,确保数据持久化。对于需要接入 Windows AD 的企业环境,还能方便地进行用户管理,并按需启动、关闭容器,节省资源。

此外,使用 Kubernetes 来管理容器网络,也不再需要复杂的 VLAN 配置,让网络管理更加简单高效。而且,随着 Ceph 和 Kubernetes 提供的高可用解决方案,未来我们只需要管理这两个系统,就能实现更高的可靠性和扩展性。

总体来说,这个方案不仅提高了效率,还能有效降低企业的运维成本,是未来 IT 基础设施发展的一个不错方向。

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

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

相关文章

E10.【C语言】练习:编写一个猜数字游戏

目录 1.规则 2.准备 3.游戏代码 1.规则 1.程序生成1-100间的随机数 2.用户猜数字 猜对了&#xff1a;游戏结束 猜错了&#xff1a;程序会告知猜大了或猜小了&#xff0c;继续进行游戏&#xff0c;直到猜对 3.游戏可以一直玩除非退出游戏 2.准备 1.框架&#xff1a;循…

【HTML+CSS+JS+VUE】web前端教程-31-css3新特性

圆角 div{width: 100px;height: 100px;background-color: saddlebrown;border-radius: 5px;}阴影 div{width: 200px;height: 100px;background-color: saddlebrown;margin: 0 auto;box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.5);}

【高阶数据结构】位图

位图 一.位图相关面试题二.位图的设计及实现三.C库中的位图bitset四.位图的优缺点五.位图相关考察题目 一.位图相关面试题 问题&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中&#xff08;本…

解决Qt打印中文字符出现乱码

在 Windows 平台上&#xff0c;默认的控制台编码可能不是 UTF-8&#xff0c;这可能会导致中文字符的显示问题。 下面是在 Qt 应用程序中设置中文字体&#xff0c;并确保控制台输出为 UTF-8 编码&#xff1a; 1. Qt 应用程序代码 在 Qt 中&#xff0c;我们可以使用 QApplic…

hutool糊涂工具通过注解设置excel宽度

import java.lang.annotation.*;Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) public interface ExcelStyle {int width() default 0; }/*** 聊天记录*/ Data public class DialogContentInfo {/**…

【算法学习】——整数划分问题详解(动态规划)

&#x1f9ee;整数划分问题是一个较为常见的算法题&#xff0c;很多问题从整数划分这里出发&#xff0c;进行包装&#xff0c;形成新的题目&#xff0c;所以完全理解整数划分的解决思路对于之后的进一步学习算法是很有帮助的。 「整数划分」通常使用「动态规划」解决&#xff0…

【Elasticsearch7.11】postman批量导入少量数据

JSON 文件内的数据格式&#xff0c;json文件数据条数不要过多&#xff0c;会请求参数过大&#xff0c;最好控制再10000以内。 {"index":{"_id":"baec07466732902d22a24ba01ff09751"}} {"uuid":"baec07466732902d22a24ba01ff0975…

Mysql--架构篇--体系结构(连接层,SQL层,存储引擎层,文件存储层)

MySQL是一种广泛使用的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;其体系结构设计旨在提供高效的数据存储、查询处理和事务管理。MySQL的体系结构可以分为多个层次&#xff0c;每个层次负责不同的功能模块。 MySQL的体系结构主要由以下几个部分组成&#…

ue5 蒙太奇,即上半身动画和下半身组合在一起,并使用。学习b站库得科技

本文核心 正常跑步动画端枪动画跑起来也端枪 正常跑步动画 端枪动画的上半身 跑起来也端枪 三步走&#xff1a; 第一步制作动画蒙太奇和插槽 第二步动画蓝图选择使用上半身动画还是全身动画&#xff0c;将上半身端枪和下半身走路结合 第三步使用动画蒙太奇 1.开始把&a…

Linux下部署Redis(本地部署超详细)

非docker 1、下载Redis 历史版本&#xff1a; http://download.redis.io/releases 我的&#xff1a; http://download.redis.io/releases/redis-7.0.5.tar.gz 2.安装教程 1.Redis是基于c语言编写的需要安装依赖&#xff0c;需要安装gcc yum install gcc-c 2.查看gcc版…

java -jar启动项目报错:XXX.jar中没有主清单属性

XXX.jar中没有主清单属性 1、错误复现2、错误原因3、解决方案 java -jar启动项目报错&#xff1a;XXX.jar中没有主清单属性 1、错误复现 今天使用springboot给项目打了jar包&#xff0c;使用命令启动时报错&#xff0c;截图如下&#xff1a; 2、错误原因 项目的pom文件配置如…

贪心算法详细讲解(沉淀中)

文章目录 1. 什么是贪心算法&#xff1f;&#xff08;贪婪鼠目寸光&#xff09;经典例题1.1.1 找零问题1.1.2最小路径和1.1.3 背包问题 2.贪心算法的特点2.1 证明例1 3.学习贪心的方向心得体会 1. 什么是贪心算法&#xff1f;&#xff08;贪婪鼠目寸光&#xff09; 贪心策略&a…

【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件

Logstash 过滤 Filter 插件 数据从源传输到存储库的过程中&#xff0c;Logstash 过滤器能够解析各个事件&#xff0c;识别已命名的字段以构建结构&#xff0c; 并将它们转换成通用格式&#xff0c;以便进行更强大的分析和实现商业价值。 Logstash 能够动态地转换和解析数据&a…

unity打包sdk热更新笔记

基础打包需要知识&#xff1a; 安装包大小不要超过2G&#xff0c;AB包数量过多会影响加载和构建&#xff0c;多次IO&#xff0c;用Gradle打包&#xff0c;要支持64位系统&#xff0c;不同的渠道包&#xff1a;让做sdk的人支持&#xff0c;提供渠道包的打包工具 配置系统环境变量…

论文笔记(六十一)Implicit Behavioral Cloning

Implicit Behavioral Cloning 文章概括摘要1 引言2 背景&#xff1a;隐式模型的训练与推理3 隐式模型与显式模型的有趣属性4 policy学习成果5 理论见解&#xff1a;隐式模型的通用逼近性6 相关工作7 结论 文章概括 引用&#xff1a; inproceedings{florence2022implicit,titl…

【Rust自学】12.3. 重构 Pt.1:改善模块化

12.3.0. 写在正文之前 第12章要做一个实例的项目——一个命令行程序。这个程序是一个grep(Global Regular Expression Print)&#xff0c;是一个全局正则搜索和输出的工具。它的功能是在指定的文件中搜索出指定的文字。 这个项目分为这么几步&#xff1a; 接收命令行参数读取…

Vue2+OpenLayers调用WMTS服务初始化天地图示例(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、WMTS服务详解 四、完整代码 五、Gitee源码 一、案例截图 二、安装OpenLayers库 npm install ol 三、WMTS服务详解 WMTS&#xff08;Web Map Tile Service&#xff09;是一种标准的网络地图服务协议&#xff0c;用于提供基于…

【STM32-学习笔记-6-】DMA

文章目录 DMAⅠ、DMA框图Ⅱ、DMA基本结构Ⅲ、不同外设的DMA请求Ⅳ、DMA函数Ⅴ、DMA_InitTypeDef结构体参数①、DMA_PeripheralBaseAddr②、DMA_PeripheralDataSize③、DMA_PeripheralInc④、DMA_MemoryBaseAddr⑤、DMA_MemoryDataSize⑥、DMA_MemoryInc⑦、DMA_DIR⑧、DMA_Buff…

lerna使用指南

lerna版本 以下所有配置命令都是基于v8.1.9&#xff0c;lerna v5 v7版本差别较大&#xff0c;在使用时&#xff0c;注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的&#xff0c;小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…

html辅助标签与样式表

一、HTML其它常用标签 1.meta标签 &#xff08;1&#xff09;meta标签是一个特殊的HTML标签&#xff0c;提供有关网页的信息&#xff0c;如作者姓名、公司名称和联系信息等 &#xff08;2&#xff09;许多搜索引擎都使用meta标签 <head> <meta name"keyword…