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

【Python】不一样的Ansible(一)

不一样的Ansible——进阶学习

  • 前言
  • 正文
    • 概念
      • Ansible Core
      • Plugins和Modules
    • 插件
      • 插件类型
      • 编写自定义插件
        • 基本要求
        • 插件选项
        • 文档标准
        • 编写插件
      • 添加一个本地插件
        • 注册为内置插件
        • 指定插件目录
    • 其他一些技巧
      • 更改Strategy
  • 结语

前言

Ansible 是一个极其简单的 IT 自动化引擎,可自动执行云配置、配置管理、应用程序部署、服务内编排和许多其他 IT 需求;基本上每一个运维工程师都会听过或者使用过Ansible(这是必然的,只要你需要管理超过2位数的服务器,Ansible基本是一个必备的工具),如果你还不知道Ansible是怎么用的,一定要找一个环境试试,这是一个真正让运维工作自动化并且事半功倍的工具。

Ansible不使用任何代理程序,也就是不需要部署agent,也不使用额外的自定义安全基础设施,因此很容易部署 - 最重要的是,使用yaml配置就能编写整个自动化流程,不需要学习太多额外的编程知识。

这一部分的内容,不是对Ansible做基本介绍的,而是对其中一些进阶的或者平时不会知道的东西做一个学习和记录的。比如各种插件的特殊用法、如何在我们自己的Python程序中去使用Ansible、以及一些其他的技巧或者知识点。

本系列文章的所有内容基于Ansible 9编写,Ansible 9使用Ansible-core 2.16

正文

概念

Ansible Core

Ansible Coreansible-coreAnsible的主要构件和架构,包含了许多的核心逻辑,比如:

  • CLI 工具,如 ansible-playbook、ansible-doc 等,用于驱动自动化并与之交互。
  • Ansible 语言使用 YAML 创建一套用于开发 Ansible Playbook 的规则,包括conditionals, blocks, includes, loops以及其他的一些内容。
  • 允许通过Ansible collections进行扩展的架构框架

总结来说,Ansible Core提供你目前所熟知的所有Ansible的基础能力,并且允许开发者在现有基础上拓展Ansible的功能。

Plugins和Modules

Ansible中非常重要的两个概念,插件和模块,那么他们有什么区别,以及怎么在自己实现拓展功能的时候选择使用哪个特性:

  • Plugins:扩展了Ansible Core的功能。大多数插件都在/usr/bin/ansible进程的控制节点上执行。插件为Ansible的核心功能提供选项和扩展:转换数据、记录输出、连接Inventory
  • Modules:本质也是一种Plugins,但是其特点在于能够在远程服务器上执行自动化任务。模块以独立脚本的形式运行,由Ansible在控制节点之外的进程中执行。模块与Ansible的接口主要是 json,接受参数并在退出前通过向stdout打印json字符串返回信息。与其他插件(必须用 Python 编写)不同,模块可以用任何语言编写;不过Ansible只提供PythonPowershell版本的模块。

这其实很好理解,Plugins是用来添加Ansible的核心代码逻辑的,因此需要Ansible能够把它加载进来,Ansible既然是Python编写的,自然也要求Plugins是要用Python编写,而Modules是通过ssh分发到受管节点执行的,那么他可以是任意程序,只要远程服务器能够运行它就可以了,默认Ansible的那些模块其实在受管节点也是调用了Python解释器来运行的

插件

插件类型

上面已经介绍了插件是什么,在Ansible中有多种插件类型,下面将官网的:

  • Action pluginsActionmodule一起执行playbook任务所需的动作,通常在后台自动运行,在模块实际运行前执行一些前期工作;
  • Become plugins:用于执行命令时进行提权或者用户切换,我们最常用的就是借助become完成sudo操作;
  • Cache pluginsCache插件允许Ansible存储收集到的受管节点信息或者inventory信息,避免因为从源数据检索而影响性能,这个最直观的体现就是我们执行playbook时如果没有关闭gather_fact,可能会等待很长时间,借助cache可以有效减少重复在受管节点执行操作时的这个步骤耗时;
  • Callback plugins:回调插件可以在Ansible响应事件时添加新的行为。默认情况下,回调插件可控制运行命令行程序时看到的大部分输出,但也可用于添加额外输出、与其他工具集成以及将事件汇聚到存储后端;对于想要对接Ansible做自动化管理的同学来说,这个插件很重要;
  • Cliconf pluginsCliconf插件是网络设备CLI接口的抽象。它们为Ansible在这些网络设备上执行任务提供了标准接口,主机维护不常用,我也没用过;
  • Connection pluginsConnection插件允许Ansible使用既定方式连接到目标主机,以便在上面执行任务,Ansible自身附带了许多连接插件,比如opensshparamiko,但每台主机一次只能使用一个;
  • Docs fragmentsDocs fragments可让使用者在一个地方记录多个插件或模块的通用参数;
  • Filter pluginsFilter插件也是一个功能常用的插件,他允许对数据进行特定的序列化或者其他自定义的处理,比如对字符串进行拆分和连接,默认Ansible使用的是jinja2提供的标准Filter功能,同时增加了一些特性;
  • Httpapi pluginsHttpapi 插件告诉Ansible如何与远程设备基于HTTPAPI交互,并在设备上执行任务;
  • Inventory pluginsInventory插件是一个允许用户指向仓库数据源的插件,也就是我们执行ad-hoc命令式的-i参数执行的逻辑;
  • Lookup pluginsLookup插件是Jinja2模板语言的Ansible特定扩展。用户可以使用该插件从外部来源(文件、数据库、key/value存储、API 和其他服务)访问playbook中的数据。与所有模板一样,LookupAnsible 控制节点上运行。Ansible使用标准模板系统提供查找插件返回的数据。你可以使用查找插件从外部资源加载变量或模板信息。
  • Modules:上文说过,Modules也是一种插件,所以这里也有它;
  • Module utilities:包含多个插件使用的共享代码,最好把它和Modules一起理解;
  • Netconf plugins:网络设备Netconf接口抽象,用于在网络设备上执行ansible任务;
  • Shell pluginsShell插件的作用是确保Ansible运行的基本命令格式正确,能够在目标计算机上运行,并允许用户配置与Ansible执行任务方式相关的某些行为,具体的情况可以跳转到
  • Strategy pluginsStrategy通过handles和受管节点的调度来控制playbook的执行流程,具体的策略可以查看:更改Strategy
  • Terminal pluginsTerminal插件包含有关如何正确初始化特定网络设备的SSH shell以配合Ansible使用的信息。这通常包括禁用自动分页、检测输出中的错误,以及在设备支持和需要的情况下启用特权模式。
  • Test pluginsTest插件可评估模板表达式并返回TrueFalse。有了测试插件,用户就可以创建条件(比如when关键字)来实现tasks、blocks、play、playbooks和roles的逻辑。Ansible使用作为Jinja一部分提供的标准测试,并添加了一些专门的测试插件
  • Vars pluginsVars插件拓展了一些变量的使用方式

上面所说的插件,其中一部分(ActionCacheCallbackConnectionFilterInventoryLookupTestVars)支持开发者进行自定义的编写,实现新的功能。

编写自定义插件

基本要求

让我们先来编写一个自定义的插件来为Ansible提供额外的核心能力,编写之前我们要知道一个Ansible插件必须要满足的条件:

  • 使用Python编写,这个在上一节已经说明原因
  • 对异常进行合适的处理,使用raise抛出异常
  • 返回值要是unicode编码的字符串
  • 符合Ansible的配置和文档标准

接下来针对上面的要求做一下分别的解释

使用Python编写

使用Python编写插件,这样它才能被PluginLoader加载,并作为任何模块都能使用的Python对象返回。由于插件将在控制节点上执行,因此必须使用兼容的 Python 版本编写插件

使用raise处理异常

在插件执行过程中遇到错误时,应通过引发AnsibleError()或类似类来返回错误信息。在将其他异常包装成错误信息时,应始终使用to_nativeAnsible函数,以确保不同Python版本的字符串兼容,下面是一个简单的样例:

from ansible.module_utils.common.text.converters import to_nativetry:cause_an_exception()
except Exception as e:raise AnsibleError('Something happened, this was original exception: %s' % to_native(e))

由于Ansible仅在需要时才会对变量进行解析,因此filter插件和test插件应使用jinja2.exceptions.UndefinedErrorAnsibleUndefinedVariable异常,以确保未定义变量仅在必要时才引起程序的Fatal

返回值符合unicode编码

这个要求是为了保证过程中的字符串str能够在Jinja2中正常运行和解析,Ansible提供了响应的方法进行转换:

from ansible.module_utils.common.text.converters import to_text
result_string = to_text(result_string)
插件选项

为了给我们自己的插件定义可配置选项,我们需要在Python文件的DOCUMENTATION部分进行描述和声明,这种规范可以确保我们插件响应选项的文档时钟保持正确和最新,以下是格式定义:

options:option_name:description: describe this config optiondefault: default value for this config optionenv:- name: NAME_OF_ENV_VARini:- section: section_of_ansible.cfg_where_this_config_option_is_definedkey: key_used_in_ansible.cfgvars:- name: name_of_ansible_var- name: name_of_second_varversion_added: X.xrequired: True/Falsetype: boolean/float/integer/list/none/path/pathlist/pathspec/string/tmppathversion_added: X.x

我们来看一个样例,这里以自带的Callback插件中的json.py演示:

# (c) 2016, Matt Martz <matt@sivel.net>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = typeDOCUMENTATION = '''callback: jsonshort_description: Ansible screen output as JSONversion_added: "2.2"description:- This callback converts all events into JSON output to stdouttype: stdoutrequirements:- Set as stdout in configoptions:show_custom_stats:version_added: "2.6"name: Show custom statsdescription: 'This adds the custom stats set via the set_stats plugin to the play recap'default: Falseenv:- name: ANSIBLE_SHOW_CUSTOM_STATSini:- key: show_custom_statssection: defaultstype: boolnotes:- When using a strategy such as free, host_pinned, or a custom strategy, host results willbe added to new task results in ``.plays[].tasks[]``. As such, there will exist duplicatetask objects indicated by duplicate task IDs at ``.plays[].tasks[].task.id``, each with anindividual host result for the task.
'''

ok,现在假设我们设定好了自己的配置项,如果要在插件内部使用对应的配置项,一般使用self.get_option(<option_name>)进行获取,不过有些插件的处理方式会有些不同;

配置部分遵循了Ansible中值的优先原则,当在同一个类别下定义多个值时,最后一个值优先,比如上述样例的这部分:

    vars:- name: name_of_ansible_var- name: name_of_second_var

此时option_name选项的值使用name_of_second_var,如果要对option值进行设置,则要使用self.set_option()方法;

文档标准

支持嵌入式文档(参见 ansible-doc 列表)的插件应包含格式良好的文档字符串,如果我们继承一个插件,则必须在文档中记录被继承插件的选项;

编写插件

Action plugin为例,编写一个插件,首先,编写的插件应该继承自对应的Base类,比如:

from ansible.plugins.action import ActionBaseclass ActionModule(ActionBase):pass

允许使用_execute_module方法来调用内置的Module并获取返回结果:

module_return = self._execute_module(module_name='<NAME_OF_MODULE>',module_args=module_args,task_vars=task_vars, tmp=tmp)

我们以官方文档中的示例为准,进行讲解,这里添加了一个通过setup模块获取的内容进行服务器时间差异的比对动作的action

from __future__ import (absolute_import, division, print_function)
__metaclass__ = typefrom datetime import datetime
from ansible.plugins.action import ActionBaseclass ActionModule(ActionBase):"""Action"""def run(self, tmp=None, task_vars=None):super().run(tmp, task_vars)module_args = self._task.args.copy()module_return = self._execute_module(module_name='setup',module_args=module_args,task_vars=task_vars, tmp=tmp)ret = {}remote_date = Noneif not module_return.get('failed'):for key, value in module_return['ansible_facts'].items():if key == 'ansible_date_time':remote_date = value['iso8601']if remote_date:remote_date_obj = datetime.strptime(remote_date, '%Y-%m-%dT%H:%M:%SZ')time_delta = datetime.utcnow() - remote_date_objret['delta_seconds'] = time_delta.secondsret['delta_days'] = time_delta.daysret['delta_microseconds'] = time_delta.microsecondsreturn {"ansible_facts": dict(ret)}

在上述代码中,调用了内部的setup模块,拉取受管节点的信息,在其返回值中,有这样的数据结构:

        "ansible_date_time": {"date": "2024-01-08","day": "08","epoch": "1704704528","epoch_int": "1704704528","hour": "17","iso8601": "2024-01-08T09:02:08Z","iso8601_basic": "20240108T170208306063","iso8601_basic_short": "20240108T170208","iso8601_micro": "2024-01-08T09:02:08.306063Z","minute": "02","month": "01","second": "08","time": "17:02:08","tz": "CST","tz_dst": "CST","tz_offset": "+0800","weekday": "Monday","weekday_number": "1","weeknumber": "02","year": "2024"},

随后在自定义插件逻辑中我们比对了iso8061的值,计算出时间的差异值,然后返回,这个插件的返回值类似以下的格式:

172.18.0.25 | SUCCESS => {"ansible_facts": {"delta_days": 0,"delta_microseconds": 152565,"delta_seconds": 0},"changed": false
}

如果想要进一步修改插件,满足自己的需求,只需要在刚才编写的ActionModule中进行变更即可。

添加一个本地插件

上面我们已经编写了一个自定义的插件,但是只是把代码写好是没法按照预期的方式通过ad-hoc的方式使用的,大概率会出现以下的报错:

172.18.0.25 | FAILED! => {"msg": "The module myaction was not found in configured module paths"
}

而想要直接便利的使用自定义的插件,有以下几种方式进行配置:

注册为内置插件

这种方法不建议,只做介绍,直接将编写好的python文件拷贝到ansible的安装目录下,比如我们使用虚拟环境,通过pip安装的ansible,那么我们的ansible安装目录ANSIBLE_INSTALL_DIR大概是这样的:$ENV_HOME/lib/python3.9/site-packages/ansible,那么只需要把我们的插件放在$ANSIBLE_INSTALL_DIR/plugins/目录下对应的插件类型下:

image-20240108173808183

不建议使用这种方法的原因主要是因为我们个人编写的代码在规范性上和官方的多少有些差异,最好还是做一些区分,这样在出问题的时候排查也会变得容易一些

指定插件目录

这个方式是比较规范的,当我们编写的插件是一个提供给全局使用的插件时,我们就这样做就可以了,编辑ansible的配置文件/etc/ansible/ansible.cfg,添加action_plugins配置项:

[defaults]
# ...
# 可以自定义为自己需要的目录
action_plugins     =  /usr/share/ansible/plugins/action 

然后把我们的插件放在上面配置的目录下,就能正常使用了

这种配置便于我们对插件进行管理,且配置一次后,所有人都能使用

除此之外,插件也可以放在Collection中,这个在讲到Collection时再单独写

其他一些技巧

更改Strategy

默认情况下,Ansible使用linear strategy进行任务的调度,除此之外,Ansible还提供了以下集中Strategy plugins

  • debug strategy – 在debug模式下运行Task.
  • free strategy – 不等待其他受管节点完成当前状态,直接运行Task
  • host_pinned strategy – 尽可能快的在每个受管节点执行play(按照serial定义的批次执行,默认为全部),除非一个play可以在不被其他主机Task中断的情况下完成,否则Ansible不会给一个新的主机启动play,即:拥有执行中的play的受管节点数量不超过forks规定的数量
  • linear strategy – 默认的策略,线性执行,这个线性是指Task,也是我们熟知的,一个 Task会在所有服务器执行完后再执行下一个Task

假设我们希望每个节点都能速度拉满,我们可以把策略改成free,通过在playbook中指定或者更改配置文件都可以实现,先看更改playbook:

- hosts: allstrategy: freetasks:# ...

或者更改ansible.cfg

[defaults]
strategy = free

结语

本篇文章主要抛砖引玉,说明了Ansible中模块和插件的区别,以及如何自己编写一个简单的Action Ansible插件,接下来会再多讲解一些其他类型的插件编写方法。

相关文章:

【Python】不一样的Ansible(一)

不一样的Ansible——进阶学习 前言正文概念Ansible CorePlugins和Modules 插件插件类型编写自定义插件基本要求插件选项文档标准编写插件 添加一个本地插件注册为内置插件指定插件目录 其他一些技巧更改Strategy 结语 前言 Ansible 是一个极其简单的 IT 自动化引擎&#xff0c…...

分布式图文详解!

分布式理论 1. 说说CAP原则&#xff1f; CAP原则又称CAP定理&#xff0c;指的是在一个分布式系统中&#xff0c;Consistency&#xff08;一致性&#xff09;、 Availability&#xff08;可用性&#xff09;、Partition tolerance&#xff08;分区容错性&#xff09;这3个基本…...

Unity SRP 管线【第五讲:自定义烘培光照】

文章目录 一、自定义烘培光照1. 烘培光照贴图2. 获取光照贴图3. 获取物体在光照贴图上的UV坐标4. 采样光照贴图 二、自定义光照探针三、 Light Probe Proxy Volumes&#xff08;LPPV&#xff09;四、Meta Pass五、 自发光烘培 一、自定义烘培光照 细节内容详见catlikecoding.c…...

CentOS快速安装Mysql5.7(Alibaba Cloud Linux兼容)

1、安装 在线下载 http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 下载rpm安装包 [roottheo bin]# cd /usr/local [roottheo local]# wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm安装rpm [roottheo local]# rpm -iv…...

【css】快速实现鼠标悬浮变色效果

<div class"nav-item"><div class"ic-img"></div><div>切换</div> </div>.nav-item {width: 100rem;height: 45rem;line-height: 45rem;display: flex;text-align: center;justify-content: center;align-items: cent…...

21. Mysql 事件或定时任务,解放双手,轻松实现自动化

文章目录 概念常见操作事件调度器操作查看事件创建事件删除事件启动与关闭事件 精选示例构造实时数据定时统计数据 总结参考资料 概念 Mysql 事件是一种在特定时间点自动执行的数据库操作&#xff0c;也可以称呼为定时任务&#xff0c;它可以自动执行更新数据、插入数据、删除…...

Apache Doris 2.0.2 安装步骤 Centos8

Linux 操作系统版本需求 Linux 系统版本当前系统版本CentOS7.1 及以上CentOS8Ubuntu16.04 及以上- 软件需求 软件版本当前版本Java1.81.8.0_391GCC4.8.2 及以上gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) 1、查看操作系统版本 方法 1&#xff1a;使用命令行 打开终端或…...

Java学习苦旅(二十五)——哈希表

本篇博客将详细讲解哈希表。 文章目录 哈希表概念冲突概念避免冲突哈希函数设计常见哈希函数 负载因子调节解决冲突闭散列开散列&#xff08;哈希桶&#xff09; 和java类集的关系 结尾 哈希表 概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关…...

性能分析与调优: Linux 实现 CPU剖析与火焰图

目录 一、实验 1.环境 2.CPU 剖析 3.CPU火焰图 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系统 prometheus、node_exporter 192.168.204.18grafana监测GUIgrafana192.168.204.19agent 监测 主机 node_exporter192…...

leetcode动态规划问题总结 Python

目录 一、基础理论 二、例题 1. 青蛙跳台阶 2. 解密数字 3. 最长不含重复字符的子字符串 4. 连续子数组的最大和 5. 最长递增子序列 6. 最长回文字符串 7. 机器人路径条数 8. 礼物的最大价值 一、基础理论 动态规划其实是一种空间换时间的基于历史数据的递推算法&…...

strtok函数的介绍

_str指被分解的字符串 delim指分隔符字符串 返回类型是指针 strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串&#xff0c;参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符…...

CF1909_C. Heavy Intervals题解

CF1909_C. Heavy Intervals题解 题目传送门&#xff08;Problem - C - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1909/problem/C&#xff09;。 题目翻译如下&#xff1a;&#xff08;图片来源&a…...

【Python机器学习】理论知识:决策树

决策树是广泛用于分类和回归任务的模型&#xff0c;本质上是从一层层if/else问题中进行学习&#xff0c;并得出结论。这些问题类似于“是不是”中可能问到的问题。 决策树的每个结点代表一个问题或一个包含答案的终结点&#xff08;叶结点&#xff09;。树的边奖问题的答案与将…...

天软特色因子看板 (2024.01 第2期)

该因子看板跟踪天软特色因子A04001(当日趋势强度)&#xff0c;该因子为反映股价走势趋势强弱&#xff0c;用以反映股价走势趋势强弱&#xff0c;abs(值)越接近1&#xff0c;趋势 性越强&#xff0c;符号代表涨跌方向 今日为该因子跟踪第2期&#xff0c;跟踪其在SH000905 (中证5…...

java智慧医院互联网智慧3D导诊系统源码,经由智慧导诊系统多维度计算,准确推荐科室

什么是智慧导诊系统? 简单地说&#xff0c;智慧导诊系统是一种利用人工智能技术&#xff0c;为医生提供帮助的系统。它可以通过分析患者的症状和病史为医生提供疾病诊断和治疗方案的建议。 系统介绍&#xff1a; 医院智慧导诊系统是在医院中使用的引导患者自助就诊挂号&…...

WiFi7: MLD寻址

原文:MLD使用MLD MAC address唯一的标识本MLD。 MLD下的STA(s)使用与之不同的MAC address。 NOTE MLD MAC address可以和其下的某个STA的MAC address相同或者不同于任一MAC Address。 原文:对于individually addressed 帧。以下规则适用: Address 2(TA)设置为STA的MAC Add…...

laravel-admin之 浏览器自动填充密码(如果需要渲染数据库密码的话,首先确认数据库密码是否可以逆向解密)

参考 https://blog.51cto.com/u_10401840/5180106 为什么浏览器端保存的密码一直自动写入到$form->password 解决办法 2、在页面进入的时候&#xff0c;默认表单的type值为text&#xff1b;推荐指数&#xff1a;2颗星 5、设置表单的readonly属性;推荐指数&#xff1a;4颗…...

jquery图形验证码

效果展示 js图形随机验证码&#xff08;表单验证&#xff09; html代码片段 <form class"formwrap"><div class"item"><input type"text" id"code_input" value"" placeholder"请输入验证码"/>…...

dp专题10 目标和

本题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 根据这道题&#xff0c;可以通过暴力的方法进行取 号或者 - 号 两个操作&#xff0c;通过当刚好得到 target 的时候 答案 1&#xff0c;但是通过长度是 20 &#xff0c;操…...

详解 docker 镜像制作的两种方式

概要 制作Docker镜像一般有2种方法&#xff1a; 通过Dockerfile&#xff0c;完成镜像的创建使用仓库中已有的镜像&#xff0c;安装自己使用的软件环境后完成新镜像创建 docker 常用命令 docker build: 用于构建 Docker 镜像。该命令可以从 Dockerfile 构建镜像&#xff0c;…...

selenium元素单击不稳定解决方法

selenium自动化测试过程中&#xff0c;经常会发现某一元素单击&#xff0c;很不稳定&#xff0c;有时候执行了点击没有反映。 以下总结两种解决方法&#xff1a;都是通过js注入的方式去点击。 1.F12查一看&#xff0c;要点击的按钮&#xff0c;或连接&#xff0c;有没有οncl…...

vue3中vite使用sass

引用&#xff1a;https://blog.csdn.net/weiliang_66/article/details/132469597 npm install sass -d配置vite.config.js: css: {preprocessorOptions: {scss: {additionalData:import "/assets/styles/main.scss";}}}创建对应的 main.sass...

centos 8.0 安装sysbench 1.0.17

序号步骤说明执行命令执行结果备注1 下载并解压sysbench-1.0.17.zip sysbench-1.0.17.zip2安装依赖文件 yum install automake libtool -y yum install /usr/include/libpq-fe.h 3安装sysbench cd sysbench-1.0.17 ./autogen.sh ./configure \ --prefix/sysbench \ --with-pgsq…...

LabVIEW开发分布式光纤油气管道泄漏检测及预警系统

LabVIEW开发分布式光纤油气管道泄漏检测及预警系统 随着油气工业的发展&#xff0c;管道泄漏成为一个严峻的安全问题。本文介绍了一种基于LabVIEW的分布式光纤油气管道泄漏检测及预警系统的设计思路和组成结构。系统包括硬件和软件两部分&#xff0c;其中硬件部分详细阐述了分…...

Go后端开发 -- Go Modules

Go后端开发 – Go Modules 文章目录 Go后端开发 -- Go Modules一、什么是Go Modules?二、GOPATH的工作模式1.GOPATH模式2.GOPATH模式的弊端 三、Go Modules模式创建项目1.go mod命令2.go mod环境变量3.使用Go Modules初始化项目4.修改模块的版本依赖关系 四、Go Modules下impo…...

基于det_keypoint_unite的ROS功能包(jetson部署)

文章目录 硬件软件FastDeploy编译CMakeLists.txt头文件源代码硬件 Jetson AGX Orin 64GB 软件 gcc/g++ >= 5.4(推荐8.2)cmake >= 3.10.0jetpack >= 4.6.1opencv=4.2.0FastDeploy编译 git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy mkdi…...

TS 36.211 V12.0.0-下行(8)-调制和上变频

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。...

基于SSM酒店后台管理系统【源码】【最详细运行文档】

基于SSM酒店后台管理系统【源码】【最详细运行文档】 功能简介技术描述运行准备♝项目运行访问项目 演示图✅源码获取 &#x1f4a1; 「分享」 大家好&#xff0c;最近几年在酒店后台管理系统非常流行&#xff0c;无论是上课的项目或者是一些毕设都会以酒店后台管理系统举例说…...

利用Python实现每日新闻早报推送

本文将介绍如何使用Python编写简单的逻辑&#xff0c;通过调用API接口实现每日新闻推送功能。 步骤&#xff1a; 导入所需的库&#xff1a; 在代码的开头&#xff0c;我们需要导入所需的库。通常&#xff0c;我们会使用requests库来发送HTTP请求&#xff0c;以获取新闻数据。 …...

图像分割-Grabcut法

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 本文的C#版本请访问&#xff1a;图像分割-Grabcut法(C#)-CSDN博客 GrabCut是一种基于图像分割的技术&#xff0c;它可以用于将图像…...

怎么在网站挂黑链接/seo网站排名优化培训教程

题目 原题链接 问题描述 鸡蛋硬度定义&#xff1a;如果一只母鸡的鸡蛋从高楼的第aaa层摔下来没摔破&#xff0c;但是从a1a1a1层摔下来时摔破了&#xff0c;那么就说这只母鸡的鸡蛋的硬度是aaa。 现给定楼层nnn&#xff0c;硬度相同的mmm个鸡蛋&#xff0c;问采取最优策略在最…...

用墨刀做视频网站/网站推广在线

2019独角兽企业重金招聘Python工程师标准>>> java注解使用是相当频繁&#xff0c;特别是在搭建一些框架时&#xff0c;用到类的反射获取方法和属性&#xff0c;用的尤其多。&#xff08;特喜欢鬼刀的画风&#xff09; java中元注解有四个&#xff1a; Retention Tar…...

网站怎样恶意刷/北京seo培训机构

虚拟局域网VLAN(Virtual LAN)是交换机端口的逻辑组合。VLAN 工作在OSI 的第2 层&#xff0c;一个VLAN 就是一个广播域&#xff0c;VLAN 之间的通信是通过第3 层的路由器来完成的。 VLAN 有以下优点&#xff1a; (1) 控制网络的广播问题&#xff1a;每一个VLAN是一个广播域&…...

华为官方手表网站/天津网络广告公司

上一回&#xff0c;咱们实现了从后台传递数据&#xff0c;在图表中展现&#xff0c;而图表的大部分配置都实在JS中控制的&#xff0c;javascript我的有个想法&#xff0c;咱们应该能够将图表的配置都拿到后台去&#xff0c;没有在实际开发中使用过&#xff0c;不知道是否好用&a…...

建筑模板厂家联系方式/360搜索引擎优化

相信经常关注网站优化SEO的人都发现&#xff0c;google算法在改变&#xff0c;百度也是。以前的一些网站优化SEO方法在目前来说已经失效不管用了&#xff0c;或者没什么大影响了。首先我们分析一下&#xff0c;要想百度更新自己的站&#xff0c;首先要让百度爬到自己的站。但是…...

派出所网站源码/知名网站

守护进程介绍 守护进程&#xff08;Daemon Process&#xff09;&#xff0c;也就是通常说的 Daemon 进程&#xff08;精灵进程&#xff09;&#xff0c;是 Linux 中的后台服务进程。它是一个生存期较长的进程&#xff0c;通常独立于控制终端并且周期性地执行某种任务或等待处理…...