Ansible PlayBook实践案例

一、PlayBook介绍

1.什么是playbook

        playbook 顾名思义,即剧本,现实生活中演员按照剧本表演,在 ansible 中,由被控计算机表演,进行安装,部署应用,提供对外的服务等,以及组织计算机处理各种各样的事情。
        playbook 是 ansible 用于配置,部署,和管理节点的剧本通过 playbook 的详细描述,执行其中的-些列 tasks,可以让远端的主机达到预期的状态。playbook 就像 ansible 控制器给被控节点列出的一系列 to-do-list,而且被控节点必须要完成。

2.Ansible playbook 使用场景

        执行一些简单的任务,使用 ad-hoc 命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作的时候,执行的 ad-hoc 命令是不合适的,这时候最好使用 playbook。
        就像执行 shell 命令与写 shell脚本一样,也可以理解为批处理任务,不过 playbook 有自己的语法格式使用 playbook 可以方便的重复使用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。在你使用 Ansible 的过程中,你也会发现,你所处理的大部分操作都是编写 playbook。可以把常见的应用都编写为 playbook,之后管理服务器会变得很简单。

二、Playbook的组成

        Playbook 是由一个或多个”play”组成的列表,主要功能在于通过将 task 定义好的角色归并为组进行统一管理,也就是通过 Task 调用 Ansible 的模板将多个“play”组织在一个 Playbook 中运行。

        Playbook 本身由以下几部分组成:

  • Tasks:任务,即调用模块完成的某操作;
  • Variables:变量;
  • Templates:模板;
  • Handlers:处理器,某条件满足时,触发执行的操作; ['hendla(r)]
  • Roles:角色。

下面是一个Playbook的简单实例:

[root@ansible-node1 ~]# vim a.yaml---
- hosts: webremote_user: roottasks:- name: create useruser:name: zhangsanpassword: "{{ 'aptech' | password_hash('sha512') }}"state: presenttags:- ccc...
 (1)执行playbook,进行语法检查
[root@ansible-node1 ~]# ansible-playbook --syntax-check a.yaml playbook: a.yaml
 (2)预测试
[root@ansible-node1 ~]# ansible-playbook -C a.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [create user] *****************************************************************
changed: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
 (3)列出主机
[root@ansible-node1 ~]# ansible-playbook --list-hosts a.yaml playbook: a.yamlplay #1 (web): web	TAGS: []pattern: [u'web']hosts (1):192.168.10.102
 (4)列出任务
[root@ansible-node1 ~]# ansible-playbook --list-tasks a.yaml playbook: a.yamlplay #1 (web): web	TAGS: []tasks:create user	TAGS: [ccc]
(5)列出标签 
[root@ansible-node1 ~]# ansible-playbook --list-tags a.yaml playbook: a.yamlplay #1 (web): web	TAGS: []TASK TAGS: [ccc]
(6)执行任务 
[root@ansible-node1 ~]# ansible-playbook a.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [create user] *****************************************************************
changed: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 1.Hosts 和Users 介绍

        Playbook 的设计目的是为了让某个或某些主机以某个用户身份去执行完成相应的任务。其中用于指定要执行指定任务的主机用 hosts 定义,可以是一个也可以是由冒号分隔的多个主机组;用于指定被管理主机上执行任务的用户用 remote user 来定义,如下面示例中所示。

- hosts: webremote_user: zhangsan

        remote user 也可定义指定用户通过 sudo 的方法在被管理主机上运行指令,甚至可以在使用sudo 时用 sudo user 指定 sudo 切换的用户。 

[root@ansible-node1 ~]# vim b.yaml---
- hosts: webremote_user: zhangsantasks:- name: test connectionping:...
[root@ansible-node1 ~]# ansible-playbook -C b.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [create user] *****************************************************************
changed: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@ansible-node1 ~]# ssh-copy-id zhangsan@192.168.10.102
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
zhangsan@192.168.10.102's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh 'zhangsan@192.168.10.102'"
and check to make sure that only the key(s) you wanted were added.
[root@ansible-node1 ~]# ansible-playbook b.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [test connection] *************************************************************
ok: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 2.任务列表和 action 介绍

        “Play”的主体是任务列表(Tasks list)。任务列表中的任务按照次序逐个在 hosts 中指定的所有主机上执行,在顺序执行这些任务时,如果发生错误会将所有已执行任务回滚。因此,需要在更正Playbook 中的错误后重新执行这些任务。
        Task 的任务是按照指定的参数去执行模块。每个 task 使用 name 输出 Playbook 的运行结果,一般输出内容为描述该任务执行的步骤。如果没有提供将输出 action 的运行结果。
        定义 task 的格式可以用”action:module options”或“module:options”都可,其中后者可以实现向后兼容。如果 action 的内容过多,可在行首使用空白字符进行换行。

[root@ansible-node1 ~]# vim a.yaml ---
- hosts: webremote_user: roottasks:- name: create useruser:name: zhangsanpassword: "{{ 'aptech' | password_hash('sha512') }}"state: presenttags:- ccc- hosts: dbremote_user: roottasks:- name: copy file to webcopy: src=/etc/passwd dest=/opttags:- ddd...
[root@ansible-node1 ~]# ansible-playbook -C a.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [create user] *****************************************************************
changed: [192.168.10.102]PLAY [db] **************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.103]TASK [copy file to web] ************************************************************
changed: [192.168.10.103]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.103             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
[root@ansible-node1 ~]# ansible-playbook a.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [create user] *****************************************************************
changed: [192.168.10.102]PLAY [db] **************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.103]TASK [copy file to web] ************************************************************
changed: [192.168.10.103]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.103             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

        如果多次去执行修改的 Playbook 时,涉及到一些没有变化的代码,可以使用 tages 让用户选择跳过没有变化代码,只运行 Playbook中发生变化的部分代码。可以在Playbook中为某个或某些任务定义“标签”,在执行此Playbook 时通过ansible-playbook 命令的--tags 选项能实现仅运行指定的 tasks 而非所有的 tasks。

3.Handlers 介绍

        Handlers 用于当关注的资源发生变化时所采取的操作。在 notify 中列出的操作便称为 handler,也就是 notify 中需要调用 handler 中定义的操作。 而 notify 这个动作用于在每个“play”的最后被触发,仅在所有的变化发生完成后一次性地执行指定操作。
示例:当拷贝模板文件为/etc/foo.conf 文件时,重新启动 memcached 和 apache 服务,如下所示。

简单示例如下所示。

(1)安装apache
[root@ansible-node1 ~]# mkdir conf
[root@ansible-node1 ~]# yum -y install httpd
[root@ansible-node1 ~]# cp /etc/httpd/conf/httpd.conf conf
[root@ansible-node1 ~]# vim conf/httpd.conf
Listen 8080//修改端口号
[root@ansible-node1 ~]# vim a.yaml - hosts: webremote_user: roottasks:- name: install httpd packageyum: name=httpd state=latest- name: install configuration file or httpdcopy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf- name: start httpd serviceservice: enabled=true name=httpd state=started
[root@ansible-node1 ~]# ansible-playbook a.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [install httpd package] *******************************************************
changed: [192.168.10.102]TASK [install configuration file or httpd] *****************************************
changed: [192.168.10.102]TASK [start httpd service] *********************************************************
changed: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
 (2)登录被管理主机 ansible-node2 进行查看执行结果。
[root@ansible-node2 ~]# rpm -qa httpd
httpd-2.4.6-99.el7.centos.1.x86_64
[root@ansible-node2 ~]# grep "Listen" /etc/httpd/conf/httpd.conf | grep -v "#" 
Listen 8080
[root@ansible-node2 ~]# systemctl status httpd
 (3)设置handlers

        如果配置文件有改动,如:Apache 端口号改变,则需要定义 notify 和 handlers,关执行操作。

[root@ansible-node1 ~]# vim conf/httpd.conf
Listen 808
[root@ansible-node1 ~]# vim b.yaml ---
- hosts: webremote_user: roottasks:- name: change portcopy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.confnotify:- restart httpdhandlers:- name: restart httpdservice: name=httpd state=restarted...
[root@ansible-node1 ~]# ansible-playbook b.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [change port] *****************************************************************
ok: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 注意:
node2 上要关闭 selinux,否则,同步配置会出错,

(4)登录被管理主机 ansible-node2 进行查看。
[root@ansible-node2 ~]# netstat -anpt | grep httpd

 4.Templates 介绍

        Jinia 是基于 Pvthon 的模板引擎。Template 类似 Jinia 的另一个重要组件,可以看作是一个编译过的模板文件。用来产生目标文本,传递 Python 的变量给模板去替换模板中的标记。

(1)创建模板文件
[root@ansible-node1 ~]# mkdir templates
[root@ansible-node1 ~]# cp conf/httpd.conf templates/httpd.conf.j2
[root@ansible-node1 ~]# vim templates/httpd.conf.j2
Listen {{ http_port }}
ServerName {{ ansible_fqdn }}
 (2)为远程主机添加变量
[root@ansible-node1 ~]# vim /etc/ansible/hosts
[web]
192.168.10.102 http_port=8888
[db]
192.168.10.103
(3)编写playbook文件 
[root@ansible-node1 ~]# vim apache.yaml- hosts: webremote_user: rootvars:- package: httpd- service: httpdtasks:- name: install httpdyum: name={{ package }} state=latest- name: install configuration file for httpdtemplate: src=/root/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.confnotify:- restart httpd- name: start httpd serviceservice: enabled=true name={{ service }} state=startedhandlers:- name: restart httpdservice: name={{ service }} state=restarted
[root@ansible-node1 ~]# ansible-playbook apache.yaml PLAY [web] *************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.102]TASK [install httpd] ***************************************************************
ok: [192.168.10.102]TASK [install configuration file for httpd] ****************************************
changed: [192.168.10.102]TASK [start httpd service] *********************************************************
changed: [192.168.10.102]RUNNING HANDLER [restart httpd] ****************************************************
changed: [192.168.10.102]PLAY RECAP *************************************************************************
192.168.10.102             : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
 (4)登录被管理主机 ansible-node2,执行查看命令
[root@ansible-node2 ~]# grep -i listen /etc/httpd/conf/httpd.conf | grep -v "#"
Listen 8888
[root@ansible-node2 ~]# grep -i servername /etc/httpd/conf/httpd.conf | grep -v "#"
ServerName ansible-node2

三、Roles 介绍

1.什么是 Roles

        Ansible 为了层次化、结构化地组织 Playbook,使用了角色(roles),可以根据层次结构自动装载变量文件、tasks 以及 handlers 等。只需要在 Playbook 中使用 include 指令便可使用 roles。简单来讲, roles 就是分别将变量、文件、任务、模块及处理器设置于单独的目录中,便捷地使用它们。

2.案例--利用 Roles 部署 mariadb

(1)被管理主机配置 yum 源
(2)配置数据库角色

[root@ansible-node1 ~]# cd /etc/ansible/
[root@ansible-node1 ansible]# ls
ansible.cfg  hosts  roles
[root@ansible-node1 ansible]# cd roles/
[root@ansible-node1 roles]# ls
[root@ansible-node1 roles]# mkdir mariadb
[root@ansible-node1 roles]# ls
mariadb
[root@ansible-node1 roles]# cd mariadb/
[root@ansible-node1 mariadb]# mkdir files
[root@ansible-node1 mariadb]# mkdir tasks
[root@ansible-node1 mariadb]# mkdir handlers
 (3)编写主文件
[root@ansible-node1 tasks]# vim main.yaml ---
- name: install mariadbyum: name=mariadb-server state=present
- name:install MySQL-pythonyum: name=MySQL-python state=present
- name: bak config fileshell: "[ -e /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.bak"
- name: copy new config filecopy: src=my.cnf dest=/etc/my.cnf
- name: restart mariadbshell: systemctl restart mariadb
- name: init mysqlshell: mysql -u root -e "create database testdb;grant all on testdb.* to test@'%' identified by 'pwd123';flush privileges;"notify:- restart mariadb
...
 (4)编写触发器文件
[root@ansible-node1 mariadb]# cd handlers/
[root@ansible-node1 handlers]# vim main.yaml---
- name: restart mariadbservice: name=mariadb state=restarted
...
  (5)编写角色文件
[root@nodel tasks]# cd /etc/ansible/roles/mariadb/files
[root@node1 files]# ls
my.cnf    ##将编辑好的 my.cnf 文件拷贝在此处
[root@ansible-node1 ansible]# vim mariadb.yaml---
- hosts: dbremote_user: rootroles:- mariadb
...
 (6)测试角色文件
[root@ansible-node1 ansible]# ansible-playbook --syntax-check mariadb.yaml playbook: mariadb.yaml
 (7)执行yml文件
[root@ansible-node1 ansible]# ansible-playbook mariadb.yaml PLAY [db] **************************************************************************TASK [Gathering Facts] *************************************************************
ok: [192.168.10.103]TASK [install mariadb] *************************************************************
changed: [192.168.10.103]TASK [mariadb : install MySQL-python] **********************************************
changed: [192.168.10.103]TASK [mariadb : bak config file] ***************************************************
changed: [192.168.10.103]TASK [mariadb : copy new config file] **********************************************
changed: [192.168.10.103]TASK [restart mariadb] *************************************************************
changed: [192.168.10.103]TASK [mariadb : init mysql] ********************************************************
changed: [192.168.10.103]RUNNING HANDLER [restart mariadb] **************************************************
changed: [192.168.10.103]PLAY RECAP *************************************************************************
192.168.10.103             : ok=8    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
 (8)检查远程服务器上数据库

查看数据库信息,看看有没有创建制定的数据库

四、利用 Ansible 管理数据库

1.用 ansible 查看数据库

[root@ansible-node1 ansible]# ansible db -m shell -a 'mysql -u root -e "show databases;"'
192.168.10.103 | CHANGED | rc=0 >>
Database
information_schema
mysql
performance_schema
test
testdb

2.创建账户并授权 

[root@ansible-node1 ansible]# ansible db -m yum -a "name=MySQL-python state=present" 
192.168.10.103 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "", "rc": 0, "results": ["MySQL-python-1.2.5-1.el7.x86_64 providing MySQL-python is already installed"]
}
[root@ansible-node1 ansible]# ansible db -m mysql_user -a "name==zhangsan password=pwd123 host=192.168.10.% priv=*.*:ALL"
[WARNING]: Module did not set no_log for update_password
192.168.10.103 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "msg": "User added", "user": "=zhangsan"
}
[root@ansible-node1 ansible]# ansible db -m mysql_user -a "name=lisi password=pwd123 priv=*.*:ALL"
[WARNING]: Module did not set no_log for update_password
192.168.10.103 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "msg": "User added", "user": "lisi"
}

注意:
张三能够远程登录,但李四不能

 要想使用 mysql user 模块,需要在客户端安装MySQL-python,安装时注意大小写

3.为老用户授权(语法和创建用户并授权的语法是相同的)

[root@ansible-node1 ansible]# ansible db -m mysql_user -a "name=root password=pwd123 host=192.168.10.% priv=*.*:ALL"
[WARNING]: Module did not set no_log for update_password
192.168.10.103 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "msg": "User added", "user": "root"
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

快速生成应用:AI大模型与低代码平台如何无缝结合提升效率?

引言:数字化时代的开发挑战 在数字化转型的浪潮中,快速响应市场需求已成为企业的核心竞争力。AI大模型与低代码平台的结合,为应用开发提供了一条更加智能、快速的路径。通过自动代码生成、智能推荐和持续优化,这一无缝结合大幅提升…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-19

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-19 1. SAM4MLLM: Enhance Multi-Modal Large Language Model for Referring Expression Segmentation Authors: Yi-Chia Chen, Wei-Hua Li, Cheng Sun, Yu-Chiang Frank Wang, Chu-Song Chen SAM4MLLM: 增强多模…

21 基于51单片机的隧道车辆检测系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 以AT89C51单片机为控制核心,实现对隧道环境的监测。采用模块化设计, 共分以下几个功能模块: 单片机最小系统模块、电源模块、气体传感模块、和显示模块等。 通过…

在电脑中增加一个新盘

找到此电脑右击找到管理点进去 找到磁盘管理点进去 找到D盘,点击D盘然后右击找到压缩卷点击,之后按照自己的意愿分盘容量 然后就一直点下一页 返回去就能看到新加卷F盘了 在此电脑中也可以查看 完成

ToB项目身份认证(一):基于目录的用户管理、LDAP和Active Directory简述

在ToB的项目里,公司部门之间是树状的关系,成员结构也类似。由于windows的使用范围很广,尤其是在企业里,所以它集成的Active Directory域服务往往企业应用需要兼容的。 什么是基于目录的用户管理? 基于目录的用户管理…

双十一快来了!什么值得买?分享五款高品质好物~

双十一大促再次拉开帷幕,面对众多优惠是否感到选择困难?为此,我们精心筛选了一系列适合数字生活的好物,旨在帮助每一位朋友都能轻松找到心仪之选。这份推荐清单,不仅实用而且性价比高,是您双十一购物的不二…

cc2530使用(SmartRF Flash Programmer)烧录hex固件

1图标 2IAR生成HEX文件 2-1勾选他 2-2生成对应的文件(勾选他并改后缀) (选择他) 点击OK即可 3(选择文件,插入板子(会显示对应的板子),烧录即可)

LeetcodeTop100 刷题总结(二)

LeetCode 热题 100:https://leetcode.cn/studyplan/top-100-liked/ 文章目录 八、二叉树94. 二叉树的中序遍历(递归与非递归)补充:144. 二叉树的前序遍历(递归与非递归)补充:145. 二叉树的后序遍…

注册商标的有关流程

注册商标的有关流程 在商业活动中,商标作为企业品牌的重要组成部分,不仅代表着企业的形象和信誉,更是企业资产的重要部分。因此,了解并遵循注册商标的流程,对于保护企业的合法权益至关重要。 一、确定商标注册范围并进…

大模型学习方向不知道的,看完这篇学习思路好清晰!!

入门大模型并没有想象中复杂,尤其对于普通程序员,建议采用从外到内的学习路径。下面我们通过几个步骤来探索如何系统学习大模型: 1️⃣初步理解应用场景与人才需求 大模型的核心应用涵盖了智能体(AI Agent)、微调&…

【TPAMI 2024】告别误差,OPAL算法如何让光场视差估计变得轻而易举?

题目:OPAL: Occlusion Pattern Aware Loss for Unsupervised Light Field Disparity Estimation OPAL:面向无监督光场视差估计的遮挡模式感知损失 作者:Peng Li; Jiayin Zhao; Jingyao Wu; Chao Deng; Yuqi Han; Haoqian Wang; Tao Yu 摘要…

一个永久的.NET渗透工具和知识仓库

01前言 为了更好地应对基于.NET技术栈的风险识别和未知威胁,.NET安全攻防帮会从创建以来一直聚焦于.NET领域的安全攻防技术,定位于高质量安全攻防社区,也得到了许多师傅们的支持和信任,通过帮会深度连接入圈的师傅们,…

计算机毕业设计推荐-基于PHP的律所预约服务管理系统

精彩专栏推荐订阅:在下方主页👇🏻👇🏻👇🏻👇🏻 💖🔥作者主页:计算机毕设木哥🔥 💖 文章目录 一、基于PHP的律…

61.【C语言】数据在内存中的存储

1.前置知识 整数在内存中以补码形式存储 有符号整数三种码均有符号位,数值位 正整数:原码反码补码 负整数:原码≠反码≠补码 2.解释 int arr[] {1,2,3,4,5}; VSx86Debug环境下,内存窗口输入&arr VSx64Debug环境下,内存窗口输入&arr 存放的顺序都一样,均是小端序…

路由基础--路由引入

路由引入的主要作用是实现路由信息在不同路由协议之间的传递和学习。在大型企业网络中,多种路由协议共存是常态,为了实现全网互通,需要通过路由引入来传递路由信息。此外,执行路由引入时还可以部署路由控制,从而实现对…

Leetcode 2464. 有效分割中的最少子数组数目

1.题目基本信息 1.1.题目描述 给定一个整数数组 nums。 如果要将整数数组 nums 拆分为 子数组 后是 有效的,则必须满足: 每个子数组的第一个和最后一个元素的最大公约数 大于 1,且 nums 的每个元素只属于一个子数组。 返回 nums 的 有效 子数组拆分中…

【数据结构】Java的HashMap 和 HashSet 大全笔记,写算法用到的时候翻一下,百度都省了!(实践篇)

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

ESP32Cam人工智能教学22

ESP32Cam人工智能教学22 在线车牌识别装置 在第十六课《tencent-OCR》中,已经学会了使用腾讯在线识别车牌,但是用的是电脑中的Python程序,读取一张车牌图片内容,然后发送给腾讯服务器进行识别,并获取返回的识别结果。…

基于yolov5滑块识别破解(一)

由于内容较长,将分为两个部分来说明,本文讲解yolov5的部署与训练。 1.YOLOv5部署 云端部署(训练) 服务器创建 如果自己的显卡算力不是很好的,或者是核显电脑,可以租用算力,价格还行一块钱左右就…

教你一招:在微信小程序中为用户上传的图片添加时间水印

在微信小程序开发过程中,我们常常需要在图片上添加水印,以保护版权或增加个性化元素。本文将为大家介绍如何在微信小程序中为图片添加时间水印,让你的小程序更具特色。 实现步骤: 1. 创建页面结构 在pages目录下创建一个名为upl…