ansible自动化运维(二)playbook模式详解
一.Ansible中的playbook模式
Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。
Playbook还是会用到ad-hoc模式中的模块及参数,只不过Playbook与ad-hoc的写法不一样
1.1playbook的优势
- 功能比ad-hoc更全
- 能很好的控制先后执行顺序,以及依赖关系
- 语法展现更加直观
- ad-hoc无法持久使用,playbook可以持久使用
1.2playbook的组成
Plsy:一个完整的部署任务,并且必须包含以下前两项:
Hosts:定义对哪些主机进程操作
tasks:定义的是具体执行的任务
Become:表示是否要以特权用户(通常是root)身份执行任务。如果设置为yes,则任务回以特权身份执行。
Playbook:由一个或多个play组成,一个play可以包含多个task任务
说明:Ansible中的playbook文件结尾为。yml格式
示例httpd.yml:安装httpd:
[root@server ~]# cat 1.yml --- - name: apache hosts: web become: yes tasks: - name: Install httpd Server yum: name: httpd state: present |
[root@server ~]# ansible-playbook 1.yml |
如上就在node1节点安装完毕
解析:
name:定义一个playbook的名称,用于标识playbook的用途;
Hosts:指定要在哪个主机上执行,也是写主机或主机组名,需提前在/etc/ansible/hosts中配置好:
beacome:yes表示使用特权用户;
tasks:属于一个任务列表,主要写具体执行什么的(可以有多个);
name:每个任务的名称,用于描述干什么的;上述yml中则是安装httpd服务;
Yum:表示使用哪个模块来进行操作:模块的参数可以看ad-hoc中的,用的都是一样的,写法不一样就是:
name:要安装的服务名称,我们这里是httpd;
state:要进行的操作,可以是安装、卸载、更新;
其实tasks就是Ansible的模块以YAML语法写入到playbook中。
生产环境中为了可读性与可维护性通常一个playbook中只编写一个play,如果某些主机需要执行多个play,那么可以使用including关键字在一个playbook中导入playbook,
1.3playbook命令
格式:
ansible-playbook [选项] playbook.yml |
常用选项:
选项/参数 | 选项/参数 解析 |
-T | 建立SSH连接的超时时间 |
-i | 指定inventory文件 |
-r | 并发执行的进程数,默认为5 |
- -list-hosts | 匹配服务器列表 |
- -list-tasks | 列出任务列表 |
- -step | 每执行一个任务后停止,等待用户确认 |
- -syntax-check | 语法检测 |
- -list-tage | 列出此yml文件中的所有tag标签 |
- -skip-tage | 执行-skip-tags之外的标签任务 |
-C | 检查当前这个playbook是否会修改受控端,模拟执行 |
1.4playbook的语法
权限
remot_user指定playbook运行时的用户身份,可以写在hosts下,也可以每个tasks做定义;
become该选项为布尔值,当等于yes表示以管理员身份通常与become_method一起使用;
become_method:su或sudo
# 指定使用哪个用户执行此任务 remote_user: root # 是否使用特权用户 become: yes |
通知与触发
notify如果指定的操作执行了,会触发handlers的操作,指定的是handler的名称;
handlers和notify指定的名称必须相同,否则无法触发。
handlers中需要-name 指定名称,handlers只会在所有的tasks执行完后执行,并且,即便一个handlers被触发多次,也会执行一次。handlers是一种特殊的tasks。
handlers(触发事件)
notify: 触发 handlers:触发的动作 # 两者的名称一定要相同,否则无法触发。 |
使用上场景:一般都是修改配置文件时
正常情况时handlers是不会执行的,除非触发任务,才会执行
[root@server ~]# cat 2.yml - hosts: node1 remote_user: root become: yes tasks: - name: install redis yum: name: redis state: present - name: copy file template: src: redis.conf dest: /etc/redis.conf tags: copyfile notify: restart # 触发:触发名称 - name: start service: name: redis state: started enabled: yes handlers: # 触发动作 - name: restart service: name: redis state: restarted |
[root@server ~]# ansible-playbook 2.yml |
以为节点没放redis所以没有找到软件包
1.5playbook中的变量
变量提供了便捷的方式来管理Ansible playbook 的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其他地方或许会反复使用,那么如果将此值设置为变量,然后再在其他的playbook中调用,会方便许多。如此一来还方便维护,减少维护的成本。 |
- 变量的定义方式
- 通过命令行进行变量定义
- 在play文件中进行变量定义
- 通过inventory主机信息文件中进行变量定义
变量读取的优先级为:命令行>playbook文件>inventory文件
通过vars定义变量
[root@server ~]# cat LAMP.yml --- - name: LAMP hosts: web vars: packages_name: - httpd - mariadb-server - php - php-mysql tasks: - name: install LAMP yum: name: "{{packages_name}}" state: present |
执行此yml:
# 语法校验 ansible-playbook --syntax-check LAMP.yml # 执行yml ansible-playbook LAMP.yml(定义的yml文件名) |
通过vars_files定义变量
当变量较少时,使用vars定义没有问题,当变量较多时,可以将变量保存到一个独立的文件中;
需要多个yml文件,一个主文件,需要调用其他yml独立文件,主要是最后运行的;其他是定义包名的yml文件。
#定义阶段 # my_vars.yml --- httpd_package: httpd mariadb_package: mariadb-server #调用阶段 # apache.yml --- - name: apache hosts: web become: yes vars_files: - my_vars.yml # 引入变量文件 tasks: - name: Install httpd yum: name: "{{ httpd_package }}" state: present become: yes - name: Install mariadb-server yum: name: "{{ mariadb_package }}" state: present become: yes |
上面是两个文件
执行此yml:
# 语法校验 ansible-playbook --syntax-check apache.yml # 执行yml ansible-playbook apache.yml(定义的yml文件名) |
官方推荐定义变量方法
之前的几种变量定义都不是很好用,比较好用的是在Ansible项目目录下船舰两个变量目录;
host_vars
group_vars
目录名字一定要一致,不能做任何修改
理解如何设置和使用host_vars和group_vars可以使你的Ansible管理更加灵活和有组织。以下是更详细的步骤,从设置目录结构到创建playbook的执行:
1.目录结构
在你的Ansible项目目录下,确保设置以下目录结构;
your_ansible_project/ ├── group_vars/ │ └── web-servers.yml ├── host_vars/ │ └── web-server.yml ├── playbook.yml └── inventory.ini |
- group_vars目录用于存放组级别的变量定义。
- Host_vars目录用于存放主机级别的变量定义。
- Playbook.yml是你的Ansible Playbook。
- Inventory.ini是Ansible的主机清单文件,其中列出了你的主机和主机组。
2.清单文件(inventory.ini)
确保在清单文件中定义了你的主机和主机组。例如:
vi /etc/ansible/inventory.ini |
[web-servers]
172.16.11.209 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh-pass=’123123’
3. **组级别变量 (`group_vars/web-servers.yml`)**: 在`group_vars`目录下创建一个YAML文件,例如`web-servers.yml`,并在其中定义组级别的变量,如: `mkdir -p /etc/ansible/group_vars && vim /etc/ansible/group_vars/web-servers.yml` ```yaml # group_vars/web-servers.yml --- httpd_package: httpd mariadb_package: mariadb-server |
3.主机级别变量(host_vars/web-server.yml)
在host_vars目录下创建一个YAML文件,例如web-server.yml,并在其中定义主机级别的变量,如:
mkdir -p /etc/ansible/host_vars && vi /etc/ansible/host_vars/web-servers.yml # host_vars/web-server.yml --- http_port: 80 |
4.playbook(playbook.yml)
创建你的Ansible Playbook,例如:
vi /etc/ansible/playbook.yml
--- - name: Configure Web Server hosts: web-servers become: yes tasks: - name: Install HTTPd yum: name: "{{ httpd_package }}" state: present - name: Start HTTPd service: name: httpd state: started |
5.运行playbook
使用以下命令运行你的Playbook:
ansible-playbook -i inventory.ini playbook.yml |
此时,Ansible会自动加载group_vars和host_vars目录中的变量,你的Playbook将使用这些变量来配置主机。
通过这种方式,你可以更加有组织地管理变量,特别是对于多主机和多组的环境。你可以为不同的组或主机设置特定的变量,而不必在Playbook中硬编码这些值,提高了可维护和可读性。
- 命令行定义变量
Ansible-playbook命令提供-e选项,用于在命令行定义变量,命令行定义变量的优先级最高。
[root@localhost yml]# cat /etc/ansible/hosts [web] 172.16.11.209 [web:vars] ansible_ssh_pass='123123' # 执行:命令行定义变量 [root@localhost yml]# vim test.yml --- - name: apache hosts: web become: yes vars: httpd_package: - httpd tasks: - name: install httpd service yum: name: "{{ httpd_package }}" state: present #定义阶段 [root@ansible ~]# ansible-playbook test.yml -e "web_server=vsftpd" |
1.6变量注册
当ansible的模块在运行之后,其实都会返回一些result结果,就像是执行脚本,我们有时候需要脚本给我们一些return返回值,我们才知道,上一步是否可以执行成功,但是默认情况下,ansible'的result并不会显示出来,所以,我们可以把这些返回值‘存储’到变量中,这样我们就能通过‘调用’对应的变量名,从而获取到这些result,这种将模块的返回值,写入到变量中的方法称为变量注册。
[root@ansible ~]# vim register.yml --- - hosts: web tasks:
- name: define a var1 shell: "whoami" register: user_name - name: get msg debug: msg: "{{ user_name }}" - name: get stdout msg debug: msg: "{{ user_name.stdout_lines }}"
# 执行 [root@localhost yml]# ansible-playbook register.yml [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details PLAY [node1] *************************************************************************************************************************** TASK [Gathering Facts] ***************************************************************************************************************** ok: [host1] TASK [define a var1] ******************************************************************************************************************* changed: [host1] TASK [get msg] ************************************************************************************************************************* ok: [host1] => { "msg": { "changed": true, "cmd": "whoami", "delta": "0:00:00.004007", "end": "2024-12-03 15:28:02.002016", "failed": false, "rc": 0, "start": "2024-12-03 15:28:01.998009", "stderr": "", "stderr_lines": [], "stdout": "root", "stdout_lines": [ "root" ] } } TASK [get stdout msg] ****************************************************************************************************************** ok: [host1] => { "msg": [ "root" ] } PLAY RECAP ***************************************************************************************************************************** host1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
说明:
debug:模块常用参数
msg:#调试输出的消息
var:#将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出
verbosity:#debug的级别(默认是0级,全部显示)
1.7debug模块:将上一步任务执行的结果打印出来
将上一步任务执行的结果打印出来,不管成功还是失败都会返回;
--- - name: debug测试 hosts: all remote_user: root
tasks: - name: 查看root目录下的文件 command: ls /root register: root_directory_contents # 存储命令输出 - name: 输出的结果 debug: var: root_directory_contents.stdout_lines |
1.8facts缓存
[root@localhost yml]# ansible nginx -m setup 172.16.11.209 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.17.0.1", "172.16.11.209" ], "ansible_all_ipv6_addresses": [ "fe80::20c:29ff:feaf:dbfa" ], 以下省略… |
在playbook中引用facts变量
二.playbook中的流程控制
2.1条件
在所有的编程语言控制语句中,条件语句是必不可少的,在使用Ansible的过程中,条件判断的使用频率及其高。
例如:
- 使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
- 在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play。会影响效率。
- 在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。
playbook中的条件判断语句使用when
tasks: #官方案例 - name: "shut down Debian flavored systems" command: /sbin/shutdown -t now when: ansible_facts['os_family'] == "Debian" # note that all variables can be used directly in conditionals without double curly braces - hosts: web_group tasks: - name: Install CentOS Httpd yum: name: httpd state: present #官方 when: ansible_facts['os_family'] == "CentOS" #非官方 when: ansible_distribution == "CentOS" - name: Install Ubuntu Httpd apt: name: apache2 state: present when: ansible_facts['os_family'] == "Ubuntu" |
还可以使用括号对条件进行分组
tasks: - name: "shut down CentOS 6 and Debian 7 systems" command: /sbin/shutdown -t now when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7") |
也可以指定多条件为列表
tasks: - name: "shut down CentOS 6 systems" command: /sbin/shutdown -t now when: - ansible_facts['distribution'] == "CentOS" - ansible_facts['distribution_major_version'] == "6" |
条件运算
tasks: - shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_facts['os_family'] == "RedHat" and ansible_facts['distribution_major_version ']|int >= 6 |
实例:
[root@server ~]# cat when.yml - hosts: node1 remote_user: root #代表用root用户执行,默认是root,可以省略 tasks: - name: createfile copy: content="test3" dest=/etc/ansible/yml/when.yml when: a=='3' - name: createfile copy: content="test4" dest=/etc/ansible/yml/when.yml when: a=='4' |
如果啊“3”,就将“test3”,写入到web组下被管控机的/etc/ansible/yml/when.uml
如果啊“4”,就将“test4”,写入到web组下被管控机的/etc/ansible/yml/when.uml
执行:
[root@server ~]# ansible-playbook -e a=3 when.yml |
2.2循环
1.标准循环使用场景-批量安装软件
[root@server ~]# cat with_items.yml --- - hosts: all remote_user: root tasks: - name: Installed packages yum: name: "{{ item }}" state: present
with_items: - wget - tree - lrzsz |
执行:
[root@server ~]# ansible-playbook with_items.yml |
2.标准循环使用场景批量创建用户
[root@server ~]# cat item2.yml --- - name: 批量创建用户 hosts: all remote_user: root tasks: - name: 配置创建用户操作 user: name: "{{ item }}" state: present with_items: - cs1 - cs2 - cs3 |
执行:
[root@server ~]# ansible-playbook item2.yml |
查看:
[root@server ~]# tail -3 /etc/passwd cs1:x:1000:1000::/home/cs1:/bin/bash cs2:x:1001:1001::/home/cs2:/bin/bash cs3:x:1002:1002::/home/cs3:/bin/bash |
3.循环嵌套使用场景-批量创建用户并给用户添加用户组
root@server ~]# cat item3.yml --- - name: 批量创建用户名及用户组 hosts: all remote_user: root tasks: - name: create group group: name={{ item }} state=present with_items: - group1 - group2 - group3 - name: create user user: name={{ item.name }} group={{ item.groups }} state=present with_items: - {'name': cs1,'groups': group1} - {'name': cs2,'groups': group2} - {'name': cs3,'groups': group3} |
执行:
[root@server ~]# ansible-playbook item3.yml |
4.循环嵌套使用场景-批量删除用户及用户组
[root@server ~]# cat item4.yml --- - name: 批量删除用户及用户组 hosts: all remote_user: root
tasks: - name: drop user user: name: "{{ item.name }}" group: "{{ item.group }}" remove: yes state: absent with_items: - {'name': cs1,'group': group1} - {'name': cs2,'group': group2} - {'name': cs3,'group': group3} - name: drop group group: name: "{{ item }}" state: absent with_items: - group1 - group2 - group3 |
执行:
[root@server ~]# ansible-playbook item4.yml |
5.标准循环使用场景-批量拷贝多个文件
[root@server ~]# cat item5.yml - name: 批量拷贝文件 hosts: all remote_user: root tasks: - name: bulk copy copy: src=/home/test/{{ item.src }} dest=/home/cs/{{ item.dest }} mode={{ item.mode }} with_items: - {src: "a.sh", dest: "a.sh", mode: "0777"} - {src: "tongji.sh", dest: "tongji.sh", mode: "0777"}
# -------------------------------此为分界线,上下互不相干---------------------------------
- name: 批量拷贝文件到不同的路径 hosts: all remote_user: root tasks: - name: bulk copy copy: src=/home/test/{{ item.src }} dest={{ item.dest }} mode={{ item.mode }} with_items: - {src: "a.sh", dest: "/home/cs/a.sh", mode: "0777"} - {src: "tongji.sh", dest: "/home/cs1/tongji.sh", mode: "0777"} |
执行:
[root@server ~]# ansible-playbook item5.yml |
2.3异常处理
默认Playbook会检查命令和模块的返回状态,如遇到错误中断playbook的执行
加入参数:ignore_errors:yes#忽略错误
[root@server ~]# cat expect.yml --- - name: 忽略错误演示 hosts: all remote_user: root tasks: - name: 使用一个未知的命令 command: a ignore_errors: yes - name: 创建一个文件 file: path=/home/cs/yichang state=touch |
执行:
[root@server ~]# ansible-playbook expect.yml |
代码解析:
如上代码,执行到command的a,命令时,服务器是没有这个命令的,就会报错,报错了之后,下面的服务就不会继续执行了;
我们现在添加了一个ignore_reeors:yes,这样就可以跳过这个报错,继续执行下面的内容:
2.4tage标签
默认情况下,Ansible在执行一个playbook中定义的所有任务;Ansible playbook中的tag标签是一种用于选择性运行特定任务或任务集的机制。通过为每个任务指定标签,您可以在运行playbook时选择只运行带有特定标签的任务吧,而不运行其他任务。这对于控制和管理Ansible playbook的执行非常有用,特别是当您的playbook包含许多其他任务时。
- 1.打标签的方式
对一个对象打一个标签
对一个对象打多个标签
对多个对象打一个标签
- 2.标签使用,通过tags和任务对象进行捆绑,控制部分或者指定的task执行
-t:执行指定的tag标签任务
--list-tags:列出此yml文件中的所有tag标签
--skip-tags:执行-skip-tags之外的标签任务
- 3.以下是tag标签的作用:
1.选择性运行任务:可以使用--tags参数在运行ansible-playbook命令时指定一个或多个标签,只有带有指定标签的任务会运行。这对于在大型playbook中只运行特定任务非常有用,而不是运行整个playbook
- 排除任务:您可以使用--skip-tags参数来排除具有特定标签的任务,从而运行除带有指定标签的任务之外的所有其他任务 。这对于在大型playbook中排除不需要运行的任务非常有用。
- 组织任务:标签可以帮助您组织和分类任务。例如,您可以为配置任务添加一个config标签,为安装任务添加一个install 标签,以便更容易了解每个任务的用途。
4.文档和注释:标签还可以作为任务的文档和注释。您可以将标签用作描述任务的方式,以便其他人更容易理解每个任务的目的。
下面是一些示例,演示如何在运行ansible-playbook.yml时使用的标签:
- 仅运行带有install标签的任务:
[root@server ~]# ansible-playbook your_playbook.yml --tags install |
- 排除带有test标签的任务
[root@server ~]# ansible-playbook your_playbook.yml --skip-tags test |
- 运行带有多个标签的任务
[root@server ~]# ansible-playbook your_playbook.yml --tags "install,config" |
- 列出yml文件中所有的标签
[root@server ~]# ansible-playbook your_playbook.yml --list-tags |
标签功能有助于增加Ansible playbook的可维护性,使您能够更精细地控制任务的执行。
- 4.【实例】部署apache服务并启动,中间可以自行设置tags标签。
[root@server ~]# cat tags.yml --- - name: 部署apache服务 hosts: node2 remote_user: root vars: - http_port: 8080 tasks: - name: Install Http Server yum: name: httpd state: present tags: - install_httpd - httpd_server - name: configure httpd server copy: src: /httpd.conf dest: /etc/httpd/conf/httpd.conf mode: 0777 notify: Restart Httpd Server tags: - config_httpd - httpd_server - name: start httpd server service: name: httpd state: started enabled: yes tags: start_httpd
- name: stop httpd server service: name: httpd state: stopped tags: stop_httpd - name: uninstall httpd server yum: name: httpd state: absent tags: uninstall_httpd handlers: - name: Restart Httpd Server service: name: httpd state: restarted |
执行:
[root@server ~]# ansible-playbook tags.yml |
这是一个Ansible playbook的YAML文件,用于部署Apache HTTP服务器。YAML文件解析:
1.name: 部署apache服务:这是整个Ansible playbook的名称或描述。
2.hosts: web:这指定了该playbook将在名为web的主机组上执行。您需要在您的Ansible inventory文件中定义主机组web,或者在命令行上指定主机。
3.remote_user: root:指定了运行任务时使用root用户身份执行。
4.vars::这是一个变量部分,用于定义变量。在这里,定义了一个名为http_port的变量,其值为8080。
5.tasks::这是实际任务部分,其中包含一系列任务,每个任务都有一个名称和相应的操作。以下是每个任务的解释:
- 第一个任务:Install Http Server:这个任务使用yum模块来安装httpd软件包,确保Apache HTTP服务器已经安装在主机上。此任务有两个tags:install_httpd和httpd_server,以便后续可以选择性地运行这些任务。
- 第二个任务:configure httpd server:这个任务使用copy模块将本地文件httpd.conf复制到目标主机的/etc/httpd/conf/httpd.conf位置,并给目标文件设置执行权限,从而配置Apache HTTP服务器。此任务有两个tags:config_httpd和httpd_server。(为什么要多余移动这个呢,因为这个配置里我们自己写的,同时也修改了httpd的端口为:8080)。notify: Restart Httpd Server意味着当该任务的状态发生变化时(通常是成功完成任务),它将触发名为 “Restart Httpd Server” 的处理程序handlers。
- 第三个任务:start httpd server:这个任务使用service模块来启动并启用Apache HTTP服务器。此任务有一个tag:start_httpd。
- 第四个任务:stop httpd server:停止HTTP服务器。它使用 service 模块将 httpd 服务停止。此任务有一个标签 stop_httpd。
- 第五个任务:uninstall httpd server:卸载HTTP服务器。它使用 yum 模块卸载 httpd 软件包。此任务有一个标签 uninstall_httpd。
6.handlers::这部分定义了处理程序,这是一些在任务中使用的命名动作,通常与通知一起使用。在这里,定义了一个名为Restart Httpd Server的处理程序,当copy任务完成后,可以通知它。此处理程序使用systemd模块来重新启动httpd服务。
这个Playbook允许您执行与Apache HTTP服务器有关的各种操作,如安装、配置、启动、停止和卸载。使用不同的标签可以选择性地运行特定任务或任务组。
这个Playbook允许您执行与Apache HTTP服务器有关的各种操作,如安装、配置、启动、停止和卸载。使用不同的标签可以选择性地运行特定任务或任务组。
执行:
#查看此yml文件中的所有tags标签 [root@server ~]# ansible-playbook tags.yml --list-tags [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details playbook: tags.yml play #1 (node2): 部署apache服务 TAGS: [] TASK TAGS: [config_httpd, httpd_server, install_httpd, start_httpd, stop_httpd, uninstall_httpd] # 执行 install_httpd,config_httpd(安装、移动配置文件)标签;执行移动配置文件会触发处理程序,所以会自动启动服务; [root@server ~]# ansible-playbook tags.yml -t install_httpd,config_httpd # 执行 uninstall_httpd(卸载httpd服务) 标签 root@server ~]# ansible-playbook tags.yml -t uninstall_httpd # 执行 httpd_server 标签 [root@server ~]# ansible-playbook tags.yml -t httpd_server # httpd_server标签包含(Install Http Server、configure httpd server、Restart Httpd Server) # 所以会直接执行这三个任务,也就是安装、移动配置文件(因为使用移动文件触发了处理程序notify,所以就会执行Restart Httpd Server重启服务) # 总结就是:执行httpd_server标签,会安装服务并启动服务。 # 跳过 httpd_server,start_httpd(安装加启动,启动)标签 [root@server ~]# ansible-playbook tags.yml --skip-tags httpd_server,start_httpd # 执行结果为,关闭httpd服务并卸载httpd服务;因为已经跳过 httpd_server ,所以不会执行安装和启动; |
上面是查看tags.yml中所有的标签
都看到这了留个您宝贵的一键三呗谢谢你们啦
相关文章:
ansible自动化运维(二)playbook模式详解
一.Ansible中的playbook模式 Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。 Playbook还是会用到ad-h…...
基于Springboot社团管理系统【附源码】
基于Springboot社团管理系统 效果如下: 系统登录页面 用户管理页面 社团信息管理页面 社团活动管理页面 经费信息管理页面 新闻信息管理页面 系统主页面 社团信息页面 研究背景 在当今高校与社区环境中,学生社团蓬勃发展,成为学生课余生活…...
CSS:html中,.png的动态图,怎么只让它显示部分,比如只显示右上部分的,或右边中间部分
目录 背景 方法 1: 使用 background-image 和 background-position 示例代码 解释 方法 2: 使用 clip-path 裁剪图像 示例代码 解释 方法 3: 使用 object-fit 和 overflow 示例代码 解释 示例 总结 背景 在HTML中,如果你有一个 .png 的动态图(例如一个 GIF 动画或…...
解读CVPR2024-论文分享|RepViT: Revisiting Mobile CNN From ViT Perspective
论文标题 RepViT: Revisiting Mobile CNN From ViT Perspective 论文链接: https://arxiv.org/abs/2307.09283 论文作者 Ao Wang, Hui Chen, Zijia Lin, Jungong Han, Guiguang Ding 内容简介 这篇论文探讨了在资源受限的移动设备上,轻量级视觉变…...
linux部署安装wordpress
一、环境准备 首先我们先介绍下环境和实验中所需要的包 环境: 我使用的是centos7.6的系统 建议关掉selinux和影响到80端口的防火墙策略 selinux永久有效 修改 /etc/selinux/config 文件中的 SELINUX"" 为 disabled ,然后重启。 selinux即…...
[Java] 配置Powershell 的 Maven 环境变量
目录 前言单独为 Powershell 设置 Maven 环境变量 前言 安装使用 maven 的时候发现,明明已经配置好了环境变量。但是在 powershell 中还是无法识别 mvn 命令。原来这货需要另外配置。 单独为 Powershell 设置 Maven 环境变量 要在 PowerShell 中永久配置 Maven 环…...
Android -- [SelfView] 自定义弹窗式颜色选择器
Android – [SelfView] 自定义弹窗式颜色选择器 PS: 1. 弹框式显示; 2. 支持透明度设置; 3. 支持拖动控件选择颜色; 4. 支持 ARGB | HEX 数值填写预览颜色并返回; 5. 输出支持Hex 和 Int 两种格式;效果 使用方法&…...
vue-echarts高度缩小时autoresize失效
背景 项目中采用动态给x-vue-echarts style赋值width,height的方式实现echarts图表尺寸的改变 <v-chart...autoresize></v-chart>给v-chart添加autoresize后,在图表宽度变化,高度增加时无异常,高度减小时图表并未缩…...
rabbitMq的rabbitmqctl status报错
Error: unable to perform an operation on node rabbitASUS-PC. Please see diagnostics information and suggestions below. 遇到上图这个错大部分问题可能是由于 RabbitMQ CLI 工具的 Erlang Cookie 与服务器上的不匹配而导致连接问题。Erlang Cookie 在 RabbitMQ 节点之间…...
linux c++ uuid编译时的问题
linux c uuid编译时的问题 写在前面可能编译过和不能编译过的可以编译和link过的不能编译过的 写在前面 几次翻车与uuid相关,超出我认知。 所以,把一些遇到的相关问题写在这里。 可能编译过和不能编译过的 可以编译和link过的 cmake_minimum_require…...
【STM32】RTT-Studio中HAL库开发教程九:FLASH中的OPT
文章目录 一、概要二、内部FLASH排布三、内部FLASH主要特色四、OTP函数介绍五、测试验证 一、概要 STM32系列是一款强大而灵活的微控制器,它的片内Flash存储器可以用来存储有关代码和数据,在实际应用中,我们也需要对这个存储器进行读写操作。…...
[SWPUCTF 2021 新生赛]crypto9
[MoeCTF 2021]Web安全入门指北—GET 意思是GET传参,moeflag 就可以得到falg 输入?moeflag flag为: NSSCTF{ff26110b-8793-403c-990e-15c7f1820596} [SWPUCTF 2021 新生赛]crypto9 #gpt写的代码 from itertools import product letter_list ABCDEFG…...
vue中常用的指令
v - if 指令 功能详细解释 它是一种真正的条件渲染指令。在 Vue 实例初始化以及数据更新过程中,Vue.js 会对v - if指令中的表达式进行求值。这个表达式可以是简单的布尔变量,也可以是一个复杂的计算表达式,只要最终结果是布尔值就行。当表达式…...
Docker Compose实战三:轻松部署PHP
通过前面的文章(Docker Compose基础语法与MySQL部署),你已经掌握了Docker Compose的基本语法和常用指令,并成功部署了一个MySQL数据库服务器。今天,我们将继续深入探索Docker Compose的强大功能,介绍如何使…...
数据分析实战—房价特征关系
1.实战内容 (1) 读取房价特征关系表(house_price.npz)绘制离地铁站的距离与单位面积的房价的散点图,并对其进行分析; import pandas as pd import numpy as np import warnings warnings.filterwarnings(&…...
云和恩墨 zCloud 与华为云 GaussDB 完成兼容性互认证
近日,云和恩墨(北京)信息技术有限公司(以下简称:云和恩墨)的多元数据库智能管理平台 zCloud 与华为云计算技术有限公司(以下简称:华为云)的 GaussDB 数据库完成了兼容性互…...
【大语言模型LangChain】 ModelsIO OutputParsers详解
【大语言模型LangChain】 ModelsIO OutputParsers详解 一、简介二、OutputParsers 的优势三、解析器类型四、实战示例1、String 解析器2、Json 解析器3、Pydantic 解析器4、结构化输出解析器5、OpenAI 函数输出解析器5.1、JsonOutputFunctionsParser5.2、JsonKeyOutputFunction…...
PaddleSpeech本地部署文档
windows安装paddlespeech步骤: 1. 安装vs c编译环境 对于 Windows 系统,需要安装 Visual Studio 来完成 C 编译环境的安装。 Microsoft C Build Tools - Visual Studio 2. 安装conda conda create -y -p paddlespeech python3.8 conda activate pad…...
Android 第三方框架:RxJava:源码分析:责任链模式
文章目录 责任链模式RxJava中的责任链总结 责任链模式 RxJava中的责任链 链式调用的使用过程中形成了两个单向链表 第一个单向链表是Observable链表 它的形成过程: 1.首先调用Observable的静态方法创建第一个Observable对象,作为Observable链表的表…...
网络安全 与 加密算法
计算机中的网络安全 在本篇中介绍了以下几个方面: 机密性 密码学 对称加密算法(DES, 3DES, AES) 公开秘钥算法 RSA大素数的获取 完整性 散列函数(MD5, SHA-1, 并没有提及算法实现) 报文鉴别(MAC) 数字签名 端点鉴别 应用 SSL(TCP网络安全) 运行时安全 防火墙的基本知识 …...
UE4_贴花_贴花基础知识二
五、多表面投射 在本示例中,你将了解贴花如何在多个表面上进行投射。请注意,如果表面朝向与投射方向较为平行,贴花投射时必然会产生一些拉伸。另外,请记住,贴花可以在包括骨骼网格体在内的静态和动态网格体上进行投射。…...
ElasticSearch 搜索、排序、分页功能
一、DSL 查询文档 ElasticSearch 的查询依然是基于 json 风格的 DSL 来实现的。 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/8.15/query-dsl.html 1.1 DSL 查询分类 常见的查询类型包括: 查询所有:查询出所有数…...
MySQL-9.1.0 实现最基础的主从复制
目录 1 实验介绍 2 实验准备 2.1 创建目录为MySQL挂载使用 2.2 编写 docker-compose.yml 文件 2.3 启动容器 3 主从复制操作 3.1 MASTER 操作指令 3.2 SLAVE1 操作指令 3.3 SLAVE2 操作指令 4 验证是否实现主从 4.1 导入sql脚本查看是否正常主从复制 4.2 检验从库是否看见复制…...
Java中的“泛型“
泛型(Generics)是Java中的一种重要特性,它允许在定义类、接口和方法时使用类型参数(type parameters)。泛型的主要目的是提高代码的类型安全性和重用性。下面我将详细讲解Java中的泛型。 1. 泛型的基本概念 泛型允许我…...
前端(五)css属性
css属性 文章目录 css属性一、字体属性二、文本属性三、背景属性四、盒子模型 一、字体属性 font-weight:文字粗细,在100到900之间,normal(400),bord(700),inherit(继承父类) font-style:文字风格,normal表示正常(默认…...
总结拓展十七:SAP 采购订单行项目“交货“页签解析
《 SAP采购订单行项目“交货”页签字段解析》 在 SAP 系统的采购流程中,采购订单行项目的“交货”页签承载着关键的信息,其中的字段更是对整个交货环节的精准描述和把控的重要元素。理解和正确解析这些字段,对于确保采购流程的顺利进行、优化…...
分布式日志系统设计
一、分布式日志系统定义 分布式日志系统是一种用于收集、存储和分析大规模分布式系统日志的系统。它可以帮助开发人员和系统管理员实时监控和调试系统,提高系统可靠性和可用性,同时也可以用于日志分析和故障排查。 二、简单设计思路 日志收集ÿ…...
DApp开发如何平衡性能与去中心化?
DApp的核心价值在于信任、透明和去中心化,但这些特点往往伴随着性能的瓶颈和高成本。在DApp开发中,如何在保证去中心化的前提下提升性能,成为开发者面临的重要挑战。如何实现性能与去中心化的平衡是一个重要课题。 一、为什么去中心化影响性…...
RK3588开发笔记-Buildroot编译Qt5WebEngine-5.15.10
目录 前言 一、Qt5WebEngine简介 二、Qt5WebEngine编译 总结 前言 Rockchip RK3588是一款强大的多核处理器,广泛应用于边缘计算、人工智能、嵌入式系统等领域。为了在RK3588上运行自定义的Linux系统,并使用Qt5WebEngine进行Web内容渲染,Buildroot是一个非常合适的工具。本…...
2024年12月GESPC++三级真题解析
一、单选题(每题2分,共30分) 题目123456789101112131415答案 B D A A D B C A A D D C D C A 1.下列二进制表示的十进制数值分别是( )[10000011]原( ) [10000011]补ÿ…...
做购物网站怎么赚钱/seo和sem的区别与联系
NOIP2018 复盘 前言 在这里立一个可能无法实现的flag: 把NOIP从古至今(luogu上有)的每一年都写一篇复盘!!! 伏拉格综合征开始了 在复盘就不讲那些伤心的话了。 D1T1 铺设道路 考试时居然不知道这道题是原题…...
最容易做的门户网站/新网络营销
随着互联网的普及,即时通讯软件也渗透到了人们的日常生活和工作当中,而市面上的即时通讯软件现在有分为两种,一种是个人社交沟通软件,另外一种则是企业即时通讯。企业即时通讯软件是为了让企业内部方便沟通、管理及办公࿰…...
案例模板我的网站/优化网站排名解析推广
偷渡用户直接更新是无法更新的 3.0.1.57 :https://www.123pan.com/s/VZiA-gvBVh 提取码:ig5D 3.0.2.68:https://pan.quark.cn/s/3e169c4e40d4 下载最新版安装包放到桌面,然后打开cmd,输入命令: start 文件路径 /I st…...
外贸淘宝网站建设/文件关键词搜索工具
作者简介古映杰,携程研发高级经理,负责前端框架和基础设施的设计、研发与维护。开源项目react-lite和react-imvc作者。尤雨溪6月份发布了 Vue Function-based API RFC,说是 3.0 最重要的 RFC。文章发布后,引起了许多人的讨论和争执…...
凡科做网站关键词/百度快照官网
xargs与find经常结合来进行文件操作,平时删日志的时候只是习惯的去删除,比如 # find . -type f -name "*.log" | xargs rm -rf *就将以log结尾的文件删除了,如果我想去移动或者复制就需要使用参数来代替了。 xargs -i 参数或者-I参…...
焦作交友网站开发公司/知名网页设计公司
本文转自:https://blog.csdn.net/whm18322394724/article/details/80177950 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/whm18322394724/article/details/80177950正文小菜继续学习积累中,今天做…...