3.2 Puppet 和 Chef 的比较与应用

Puppet 和 Chef 的比较与应用

文章目录

    • Puppet 和 Chef 的比较与应用
    • Puppet 和 Chef 简介
    • 工作原理对比
    • **模块化的重要性**:

  1. Puppet 和 Chef 简介
    • 介绍 Puppet 和 Chef 这两个流行的配置管理工具的背景和用途。
    • 强调它们的共同目标:实现自动化的系统配置和管理。
  2. 工作原理对比
    • 解释 Puppet 和 Chef 的工作原理,包括代理-主控架构、主控节点和客户端的交互方式。
    • 对比两者的配置管理方式和任务执行模型。
  3. 语法和模块化
    • 对比 Puppet 和 Chef 的配置文件语法,包括 Puppet 的 Manifest 和 Chef 的 Cookbook。
    • 强调模块化的重要性,以及如何将配置和任务封装成可重用的模块。
  4. 扩展性和生态系统
    • 比较 Puppet 和 Chef 的扩展性,包括是否支持自定义模块、插件和资源。
    • 分析两者的生态系统,如社区支持、第三方模块和工具的丰富程度。
  5. 适用场景和选择策略
    • 分析 Puppet 和 Chef 在不同场景下的优势,如基础设施管理、云环境、应用部署等。
    • 提供选择配置管理工具的策略,考虑因素包括团队熟悉度、项目需求和生态系统支持。
  6. 使用案例
    • 通过实际案例,展示 Puppet 和 Chef 在不同场景下的应用。
    • 比较两者在解决特定问题时的优缺点,以及适用性。
  7. 最佳实践和经验分享
    • 提供使用 Puppet 和 Chef 的最佳实践,包括目录结构、变量管理等。
    • 分享经验,以帮助读者更好地利用 Puppet 和 Chef 提高配置管理的效率。
  8. 未来发展趋势
    • 探讨 Puppet 和 Chef 在持续集成、容器化、云原生等新技术发展中的地位和前景。
    • 引导读者关注未来技术趋势,以便做出更明智的技术选型。

通过本节的内容,读者将了解 Puppet 和 Chef 这两个重要的配置管理工具,包括它们的特点、工作原理、适用场景以及在实际应用中的比较。这将有助于读者根据项目需求和团队情况,选择合适的配置管理工具,提高运维效率并确保系统的可靠性。

Puppet 和 Chef 简介

Puppet 和 Chef 是两个备受欢迎的配置管理工具,它们都致力于实现自动化的系统配置和管理,可以大大简化运维工作,提高系统的稳定性和可维护性。

Puppet

Puppet 是一个基于模型的自动化工具,旨在帮助管理员自动化部署、配置和管理大规模的计算基础设施。它使用声明式语言来描述系统配置,管理员可以编写 Puppet 代码来定义所需的系统状态,Puppet 会自动根据这些代码来实现配置的一致性。Puppet 有一个丰富的资源库,称为 “Puppet Forge”,管理员可以在其中找到现成的模块来管理常见的应用、服务和资源。Puppet 还提供集中的控制面板,使管理员可以轻松地监控和管理配置状态。

Chef

Chef 是一个基于资源和行为的自动化框架,它允许管理员将系统配置定义为代码,以便自动化系统的部署和管理。Chef 使用一种叫做 “Cookbook” 的方式来组织配置,每个 Cookbook 定义了一系列资源和行为,以实现特定的系统配置。Chef 支持丰富的配置管理和自动化编排,管理员可以使用 Chef 来处理应用部署、系统更新、配置管理等任务。Chef 的强大之处在于其灵活性,管理员可以编写高度定制化的 Cookbook 来满足特定需求。

虽然 Puppet 和 Chef 在实现的方式上有些差异,但它们的共同目标都是通过自动化和代码化的方式来管理系统,降低配置错误和手动操作的风险,同时提高系统的可靠性和可维护性。这两个工具都有庞大的用户社区和丰富的资源库,使得管理员可以快速上手并应用于实际的运维工作。

工作原理对比

Puppet 的工作原理

Puppet 采用了代理-主控架构,主要由以下几个组件组成:

  1. 主控节点(Puppet Master):主控节点是 Puppet 系统的中心,它包含了配置信息,以及要应用到客户端的 Puppet 代码(也称为 “Manifest”)。主控节点负责为每个客户端生成应用配置的指令。
  2. 客户端节点(Puppet Agent):客户端节点是需要受控的系统,运行着 Puppet 代理程序。这些代理程序周期性地连接到主控节点,获取最新的配置指令(Puppet Manifest),并根据指令执行配置操作。
  3. PuppetDB(可选):PuppetDB 是一个数据库,用于存储 Puppet 系统的状态信息。它可以帮助管理员跟踪系统配置状态和变化。

Puppet 的配置管理方式是声明式的,管理员编写 Puppet 代码来定义期望的系统状态,而不必关心具体的操作步骤。Puppet Agent 负责执行这些配置,将系统状态调整到与 Puppet Manifest 中描述的一致。

Chef 的工作原理

Chef 也采用了代理-主控架构,但与 Puppet 有一些不同之处:

  1. 主控节点(Chef Server):Chef Server 保存配置信息和 Chef Cookbook,它负责生成应用配置的指令,但这些指令被称为 “Recipes” 和 “Cookbooks”,不同于 Puppet 的 Manifest。
  2. 客户端节点(Chef Client):客户端节点运行 Chef 客户端,它连接到主控节点获取最新的 Cookbook,然后根据 Cookbook 中定义的资源和行为来执行配置操作。
  3. Chef Workstation:Chef 还包括一个 Chef Workstation 组件,用于开发和管理 Chef Cookbook。

Chef 的配置管理方式也是基于代码的,管理员编写 Cookbook 来定义资源和行为,Chef Client 根据 Cookbook 执行这些配置。Chef 的灵活性使管理员可以更细粒度地控制配置,但也需要一定的学习曲线。

在工作原理方面,Puppet 和 Chef 都采用了代理-主控模型,但在配置管理的具体方式和操作模型上存在差异。Puppet 更加注重声明式的配置,而 Chef 更加灵活,允许管理员编写详细的资源配置。选择哪个工具通常取决于团队的偏好、项目需求和所需的配置管理复杂度。

Puppet 的配置文件语法

Puppet 使用一种被称为 Manifest 的配置文件语法。Manifest 是以 .pp 扩展名的文本文件,其中定义了 Puppet Agent 要应用的配置。Manifest 的基本结构包括定义资源和设置参数。资源是要管理的系统组件(如文件、服务、用户等),而参数则指定资源的属性和配置。

示例 Puppet Manifest:

# 定义文件资源,创建 /etc/myapp.conf 文件
file { '/etc/myapp.conf':ensure => file,owner  => 'root',group  => 'root',mode   => '0644',content => "key=value\n",
}

Chef 的配置文件语法

Chef 使用一种被称为 Cookbook 的配置文件语法。Cookbook 是一个目录结构,包含了定义资源和行为的 Ruby 脚本、模板、文件等。每个 Cookbook 中都包括 Recipes 和 Attributes,其中 Recipes 定义了要执行的配置,Attributes 定义了资源的属性。

示例 Chef Cookbook(Recipe):

# 创建文件资源,在 /etc/myapp.conf 中写入内容
file '/etc/myapp.conf' doowner 'root'group 'root'mode '0644'content 'key=value\n'
end

模块化的重要性

无论是 Puppet 还是 Chef,模块化都是一个重要的概念。它可以帮助将配置和任务封装成可重用的模块,从而提高配置管理的效率和可维护性。模块可以包含特定的功能、组件或配置,使其能够在不同的场景中重复使用。

模块化的好处包括:

  1. 可重用性:将常见的配置和任务封装成模块,以便在不同项目中复用,减少重复劳动。
  2. 可维护性:模块化使配置更容易维护,因为更改只需在模块中进行,不必在整个配置中搜索。
  3. 组织性:模块化的配置更易于组织和管理,尤其是在大型和复杂的环境中。

Puppet 使用模块来组织配置,每个模块包含 Manifest 文件和其他资源。Chef 使用 Cookbook 来实现类似的概念,每个 Cookbook 包括多个 Recipes 和其他文件。模块和 Cookbook 的使用是 Puppet 和 Chef 中实现配置模块化的关键。

Puppet 的扩展性

Puppet 具有良好的扩展性,支持自定义模块、插件和资源。Puppet 模块是一个用于封装代码、数据和文件的基本单位,可以轻松地创建自定义模块。Puppet 的资源提供了对不同系统组件的抽象,但如果没有现成的资源,你可以编写自己的自定义资源。

Puppet 生态系统

Puppet 生态系统非常丰富,拥有活跃的社区和大量的第三方模块。Puppet Forge 是 Puppet 社区的中央模块仓库,包含各种功能丰富的模块,用于管理不同类型的资源。此外,Puppet 社区提供了大量的文档、论坛和博客,帮助用户解决问题和分享经验。

Chef 的扩展性

Chef 也具有很强的扩展性,支持自定义资源、Cookbook 和插件。自定义资源可以通过编写 Ruby 代码来创建新的资源类型,从而更好地满足特定需求。Cookbook 是 Chef 的核心概念,它允许用户封装配置和任务,从而创建可重用的模块。

Chef 生态系统

Chef 社区同样非常强大,拥有丰富的第三方 Cookbook、插件和工具。Chef Supermarket 是 Chef 社区的中央模块仓库,用户可以在这里找到各种 Cookbook,从而快速实现配置。Chef 社区也提供了广泛的文档、社区支持和培训资源,帮助用户更好地理解和使用 Chef。

总体来说,Puppet 和 Chef 都拥有强大的扩展性和丰富的生态系统,用户可以根据自己的需求选择适合的模块、资源和工具,从而更好地实现自动化配置管理。

Puppet 和 Chef 在不同场景下的优势

  • 基础设施管理:Puppet 和 Chef 都适用于基础设施的自动化配置和管理。Puppet 的资源模型和丰富的模块使其能够更好地管理复杂的基础设施,而 Chef 的 Cookbook 和自定义资源使其在基础设施自动化方面同样表现出色。选择哪个取决于团队的偏好和经验。
  • 云环境:在云环境中,Puppet 和 Chef 都能够实现自动化部署和管理,包括自动扩展、配置一致性等。Puppet 的生态系统更加丰富,对于大规模的云基础设施管理更具优势。Chef 的自定义资源和强大的编程能力也适用于复杂的云场景。
  • 应用部署:在应用部署方面,Puppet 和 Chef 都可以通过 Cookbook 和模块来管理应用的安装和配置。Chef 更加灵活,可以编写更复杂的逻辑来实现应用的自动化部署。Puppet 则更注重资源管理的一致性,适用于需要强调统一配置的场景。

选择配置管理工具的策略

  1. 团队熟悉度:如果团队已经熟悉了 Puppet 或 Chef 中的一种工具,可以继续使用并深入发掘其特性。熟悉度将影响配置管理的效率和质量。
  2. 项目需求:根据项目的需求来选择工具。如果项目需要更大的灵活性和自定义性,Chef 可能更适合。如果项目更注重资源一致性和标准化,Puppet 可能更适合。
  3. 生态系统支持:考虑工具的生态系统,包括社区支持、模块的丰富程度、文档质量等。Puppet 和 Chef 都拥有强大的生态系统,但某些特定模块可能在一个工具中更丰富。
  4. 技术栈:考虑团队的技术栈,包括编程语言、操作系统等。Puppet 更侧重于声明式编程,而 Chef 更侧重于脚本化的编程风格,根据团队的技术背景来选择。

综上所述,选择 Puppet 还是 Chef 取决于具体的需求和团队情况。无论选择哪个工具,都需要深入学习和实践,以发挥其在自动化配置管理方面的优势。

使用案例

  1. 基础设施自动化
    • Puppet案例:一家大型云服务提供商使用Puppet来自动化其大规模的服务器配置和管理。他们通过编写Puppet模块,定义了所有服务器的配置,确保每台服务器都具有一致的软件包、配置文件和用户权限。这种一致性大大降低了配置错误和安全漏洞的风险。
    • Chef案例:一家跨国金融公司采用Chef来管理其分布式基础设施。他们使用Chef Cookbook来描述不同服务器角色的配置,并通过Chef来动态地管理服务器的数量,以适应业务的需求变化。这种灵活性和动态性使他们能够快速响应市场需求。
  2. 应用部署
    • Puppet案例:一家电子商务公司使用Puppet来自动化其应用的部署。他们编写了Puppet模块,描述了不同环境中应用的安装和配置,包括数据库连接、Web服务器配置等。这种模块化的方式让他们能够快速部署新的应用实例。
    • Chef案例:一家科技初创公司使用Chef来实现容器化应用的部署。他们使用Chef的自定义资源和Cookbook来定义Docker容器的配置,然后通过Chef来启动和管理容器。这种方法让他们能够轻松地部署和扩展应用。
  3. 配置管理
    • Puppet案例:一家制造公司使用Puppet来确保所有服务器都遵循统一的安全配置策略。他们编写了Puppet模块,包括防火墙规则、用户权限、安全补丁等。通过Puppet的自动化配置,他们能够保证所有服务器的安全性。
    • Chef案例:一家医疗保健公司使用Chef来管理其应用的配置。他们将应用的配置信息放在Chef Cookbook中,通过版本管理和自动化部署来确保配置的一致性。这种方法使他们能够快速恢复到之前的配置状态。

比较

  • Puppet强调一致性和声明式配置,适用于需要严格控制配置一致性的场景,尤其在大规模环境中表现出色。
  • Chef更灵活,允许更多的编程逻辑和脚本化配置,适用于需要高度定制化配置和较小规模环境的场景。

选择策略

  • 如果团队更善于声明式配置和需要一致性,Puppet可能更适合。
  • 如果需要更大的灵活性和编程能力,Chef可能更适合。
  • 考虑团队的经验和偏好,以及项目的需求,来选择合适的配置管理工具。

最佳实践和经验分享

  1. 目录结构的组织
    • 对于Puppet和Chef,良好的目录结构对于管理配置非常重要。建议使用模块化的方式,将配置分为不同的模块或Cookbook,以便于复用和管理。
    • 在模块或Cookbook内部,可以按功能或服务划分子目录,更好地组织配置文件和脚本。
  2. 版本控制
    • 使用版本控制工具(如Git)来管理Puppet模块或Chef Cookbook的代码。这有助于跟踪配置的变化、回滚操作以及多人协作开发。
    • 为每个版本添加有意义的注释,以便了解每个版本的变更和目的。
  3. 变量管理
    • 在Puppet中,可以使用Hiera来管理变量,将变量值与具体配置分离,使得配置更具灵活性。
    • 在Chef中,可以使用attributes和data bags来管理变量。合理组织变量,以便在不同环境中复用。
  4. 自动化测试
    • 在Puppet和Chef中,都支持自动化测试来确保配置的正确性。编写单元测试和集成测试,以验证配置的预期行为。
    • 使用测试框架(如rspec、serverspec等),覆盖主要功能和关键配置。
  5. 文档和注释
    • 对于复杂的配置和脚本,编写清晰的文档和注释。说明每个模块或Cookbook的作用、变量的含义以及配置的逻辑。
    • 维护良好的文档有助于团队协作和项目维护。
  6. 社区参与
    • 利用Puppet和Chef的丰富社区资源,寻找解决方案、共享经验。参与社区讨论、查看文档、阅读博客等。
  7. 持续学习
    • Puppet和Chef的版本和特性不断更新,保持学习的态度,关注最新的功能和最佳实践。

以上实践和经验可以帮助你更好地使用Puppet和Chef来管理和维护配置,提高效率、降低错误率,同时促进团队协作。

未来发展趋势

  1. 持续集成与持续交付:Puppet和Chef在持续集成和持续交付(CI/CD)中的地位将更加重要。随着企业追求更高的交付速度和质量,配置管理工具在自动化部署和系统一致性保障方面的作用将不断增强。将Puppet和Chef与CI/CD工具(如Jenkins、GitLab CI等)集成,实现自动化测试、配置管理和持续部署,有望成为未来的趋势。
  2. 容器化与云原生:随着容器化技术的普及,Puppet和Chef在容器编排(如Kubernetes)中的应用将变得更加重要。配置管理工具可以负责容器中的配置和应用部署,同时与云原生技术结合,更好地支持云环境的弹性和自动化管理。未来,Puppet和Chef将不仅仅管理虚拟机,还会涵盖容器和云资源的管理。
  3. 多云管理:随着多云策略的普及,企业在不同云服务商(如AWS、Azure、Google Cloud等)之间进行资源管理和应用部署的需求不断增加。Puppet和Chef有望发展出更强大的多云管理能力,能够支持在多个云环境中实现统一的配置管理和自动化部署。
  4. 自动化智能运维:未来智能化运维趋势下,Puppet和Chef有望融入人工智能和自动化决策。通过分析系统数据和性能指标,自动调整配置、预测问题,并采取自动化的响应措施,从而实现更智能的运维。
  5. 可视化和报表:随着对系统状态和性能的监控要求不断增加,Puppet和Chef可能会朝着更强大的可视化和报表方向发展。提供更丰富的仪表盘、自定义报表和告警机制,帮助管理员更好地理解系统状态,及时做出决策。

综上所述,Puppet和Chef作为配置管理的佼佼者,将继续在自动化运维领域发挥重要作用。随着新技术的发展和业务需求的变化,它们也会不断演进,以满足企业的需求,并将更多的智能化和自动化特性融入到配置管理过程中。对于技术选型,需要根据具体场景、团队熟悉度和项目需求进行综合考量。
能会朝着更强大的可视化和报表方向发展。提供更丰富的仪表盘、自定义报表和告警机制,帮助管理员更好地理解系统状态,及时做出决策。

综上所述,Puppet和Chef作为配置管理的佼佼者,将继续在自动化运维领域发挥重要作用。随着新技术的发展和业务需求的变化,它们也会不断演进,以满足企业的需求,并将更多的智能化和自动化特性融入到配置管理过程中。对于技术选型,需要根据具体场景、团队熟悉度和项目需求进行综合考量。

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

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

相关文章

Spring Cloud Stream 4.0.4 rabbitmq 发送消息多function

使用 idea 创建 Springboot 项目 添加 Spring cloud stream 和 rabbitmq 依赖 pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchem…

基于Java SSM人力资源管理系统

人力资源管理系统实现对企业人力资源的科学管理。企业有多个部门&#xff0c;每个部门有——名经理和多名员工&#xff0c;公司设置多级岗位&#xff0c;对应不同薪酬标准&#xff0c;员工日常工作进行考勤&#xff0c;岗位变动需要进行登记。系统管理的对象及操作主要有&#…

学生信息管理系统

摘 要 学生成绩管理系统是典型的信息管理系统(MIS)&#xff0c;其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。经过分析&#xff0c;我们使用Microsoft公司的C语言开发工具&#xff0c;将与C语言技术与数据库SQL2008相结合进行设计。首先&#xff0c;…

【多线程】线程的三种常见创建方式

文章目录 线程创建方式1——Thread线程创建方式2——Runnable线程创建方式2——匿名内部类线程创建方式3——Callable、FutureTask,带返回值 线程其实是程序中的一条执行路径。 那怎样的程序才是多线程程序呢&#xff1f; 例如12306网站就是支持多线程的&#xff0c;因为同时可…

一下午终于配好:如何用vs code连接远程主机jupyter server(notebook/lab)

因为教研室的机器有2060&#xff0c;笔记本只有集成显卡&#xff0c;虽然也可用浏览器访问&#xff0c;但是vs code不论从界面还是扩展功能来说&#xff0c;都有更好的编程体验&#xff0c;所以想通过vs code远程连接jupyter server。 要实现该需求总体需要三个步骤&#xff1…

Python推导式详细讲解

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;推导式是一种简洁而强大的语法特性&#xff0c;可以用来创建列表、集合、字典等数据结构。本文将深入探讨Python中的三种推导式&#xff1a;列表推导式、集合推导式和字典推导式&#xff…

@Component 和 @Bean 和 @configuration的区别

从位置上确定了每个注解的区别 从注解的位置上来确定这三个注解的区别&#xff0c;我们可以看到它们的应用场景和作用不同。 Component注解&#xff1a; Component注解是标记在类级别上的注解&#xff0c;用于将一个类标识为Spring容器的组件。通过组件扫描&#xff08;compon…

JavaScript中处理时间差

ES6版本 function countdown(endTime, includeSeconds true) {// 获取当前时间let now new Date();// 将传入的结束时间字符串转换为日期对象let endDateTime new Date(endTime);// 检查传入的时间字符串是否只包含日期&#xff08;不包含时分秒&#xff09;if (endTime.tr…

喜讯:麦田(苏州)医学科技有限公司立项项目获得2024年度浙江省医药卫生科技计划资助的公告

喜讯&#xff1a;麦田&#xff08;苏州&#xff09;医学科技有限公司立项项目获得2024年度浙江省医药卫生科技计划资助的公告 我们麦田&#xff08;苏州&#xff09;医学科技有限公司非常荣幸地宣布&#xff0c;由我们联合浙江省人民医院、杭州市红十字会医院、杭州师范大学共同…

Docker-多容器应用

一、概述 到目前为止&#xff0c;你一直在使用单个容器应用。但是&#xff0c;现在您将 MySQL 添加到 应用程序堆栈。经常会出现以下问题 - “MySQL将在哪里运行&#xff1f;将其安装在同一个 容器还是单独运行&#xff1f;一般来说&#xff0c;每个容器都应该做一件事&#x…

强化学习——简单解释

一、说明 最近 OpenAI 上关于 Q-star 的热议激起了我温习强化学习知识的兴趣。这是为强化学习 (RL) 新手提供的复习内容。 二、强化学习的定义 强化学习是人类和其他动物用来学习的学习类型。即&#xff0c;通过阅读房间来学习。&#xff08;从反馈中学习&#xff09;。让我解…

在C#中,PropertyInfo.SetValue方法用于设置属性值

在C#中&#xff0c;PropertyInfo.SetValue方法用于设置属性值。该方法接受两个参数&#xff1a;对象实例和属性值。下面是一个示例代码&#xff0c;演示如何使用PropertyInfo.SetValue方法设置属性值&#xff1a; using System; using System.Reflection; public class Per…

基于深度学习CRNN的水表读数识别系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 随着科技的不断发展&#xff0c;深度学习技术在各个领域都取得了显著的成果。其中&#xff0c;基于深度学习的图像识别技术在计算机视觉领域具有重要的应用价值。…

Linux环境搭建(Ubuntu22.04)+ 配置共享文件夹(Samba)

Linux开发环境准备 搭建Linux开发环境所需要的软件如下&#xff1a; VMware虚拟机&#xff1a;用于运行Linux操作系统的虚拟机软件之一&#xff0c;VMware下载安装在文章中不做说明&#xff0c;可自行百度谢谢Ubuntu光盘镜像&#xff1a;用于源代码编译&#xff0c;有闲置计算…

maven生命周期回顾

目录 文章目录 **目录**两种最常用打包方法&#xff1a;生命周期&#xff1a; 两种最常用打包方法&#xff1a; 1.先 clean&#xff0c;然后 package2.先 clean&#xff0c;然后install 生命周期&#xff1a; 根据maven生命周期&#xff0c;当你执行mvn install时&#xff0c…

大数据Hadoop-HDFS_架构、读写流程

大数据Hadoop-HDFS 基本系统架构 HDFS架构包含三个部分&#xff1a;NameNode&#xff0c;DataNode&#xff0c;Client。 NameNode&#xff1a;NameNode用于存储、生成文件系统的元数据。运行一个实例。 DataNode&#xff1a;DataNode用于存储实际的数据&#xff0c;将自己管理…

Python (二) 读写excel文件

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

妈妈和老婆掉进水里,孟子认为先救老婆是禽兽

妈妈和老婆同时掉进水里先救谁&#xff1f; 多数男人不敢回答&#xff0c;怕得罪老婆。孟子认为&#xff0c;必须先救妈妈。因为父母都照顾不好&#xff0c;是不孝。先救妈妈&#xff0c;再救老婆。 中国人的信仰是天&#xff0c;以及孔孟之道。中国人不信宗教。 孟子&#x…

【普中开发板】基于51单片机温度报警器设计( proteus仿真+程序+实物演示+讲解视频)

这里写目录标题 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 实物烧录和现象5. 程序代码6. 设计资料内容清单&&下载链接资料下载链接&#xff1a; 【普中开发板】基于51单片机温度报警器设计( proteus仿真程序实物演示讲解视频&#xff09; Proteus 仿真…

java-使用poi时报错Method org/apache/poi/xssf/usermodel/XSSFWorkbook.close()V is abst

报错信息1 AbstractMethodError: Method org/apache/poi/xssf/usermodel/XSSFWorkbook.close()V is abstract 解决&#xff1a;是因为poi 3.11才有close&#xff0c;升级pom文件的版本就可以了 报错信息2 Package should contain a content type part [M1.13] 报错信息3 tried…