Ansible自动化工具模块调用与playbook编写

news2024/11/28 0:50:23

目录

一、Ansible工作机制与特点

(一)Ansible工作机制

1. 初始化与配置

2. 编写Playbook

3. 调用模块

4. 加密敏感数据

5. 执行Playbook

6. 收集执行结果

7. 错误处理与回滚

8. 反馈与报告

(二)Ansible 的主要特点包括

(三)安装ansible

二、主机组

(一)定义主机组

(二)组嵌套

(三)组变量

三、Ansiible模块使用

(一)Command 模块

(二)shell模块

(三)Yum模块

(四)Service模块

四、Playbook

(一)Playbook基础

(二)Playbook结构

(三)Playbook示例

(四)定义、引用变量

(五)when条件判断

(六)迭代

五、实战---使用Playbook编译安装nginx


Ansible,作为一款强大的自动化运维工具,以其简洁的语法、零代理架构以及广泛的支持度,在DevOps领域占据了一席之地。它允许系统管理员和开发人员以声明式的方式描述基础设施的配置状态,从而实现跨平台的配置管理、应用部署、任务自动化等

一、Ansible工作机制与特点

(一)Ansible工作机制

1. 初始化与配置

  • 安装Ansible:首先确保Ansible已在控制节点(通常是运维人员的电脑或服务器)上安装并配置好。
  • 准备Inventory:创建或编辑/etc/ansible/hosts文件,定义要管理的目标主机或主机组,包括IP地址、主机名等。

2. 编写Playbook

  • Playbook编写:使用YAML格式编写Playbook,这是Ansible的核心配置文件,描述了需要在目标主机上执行的任务序列、角色分配、变量、条件判断等。

3. 调用模块

  • 模块选择与定义:在Playbook中,每个任务都会调用一个或多个Ansible模块。Ansible拥有大量内置模块,覆盖了系统管理、网络配置、云服务管理等多个方面。
  • 模块参数:为每个模块指定参数,以定制任务的具体行为。

4. 加密敏感数据

  • 使用Ansible Vault:对于Playbook中的敏感信息(如密码、密钥),可以使用Ansible Vault进行加密保护。

5. 执行Playbook

  • 执行模式选择:可以直接在命令行执行Ansible命令,或通过Ansible Tower等UI界面进行。
  • 提供认证信息:如果Playbook中使用到了加密数据,需要提供Ansible Vault的密码。
  • 解析Inventory:Ansible根据Inventory文件确定目标主机。
  • 连接目标主机:Ansible通过SSH(默认)或其他连接插件与目标主机建立连接。
  • 模块执行:Ansible在每个目标主机上顺序执行Playbook中定义的任务,调用相应的模块。
  • 幂等性执行:Ansible确保模块操作是幂等的,即重复执行相同任务,系统状态保持不变。

6. 收集执行结果

  • 输出与日志:Ansible收集每个任务的执行结果,输出到控制台或日志文件中。如果任务失败,会提供详细的错误信息。

7. 错误处理与回滚

  • 错误处理:通过Playbook中的错误处理机制(如rescuealways块)来捕获异常并执行相应的恢复操作。
  • 状态跟踪:Ansible可以追踪任务的执行状态,便于后续的审计和故障排查。

8. 反馈与报告

  • 生成报告:Ansible执行完成后,可以生成执行报告,便于分析任务的成功率、耗时等指标。

(二)Ansible 的主要特点包括

简单易用:基于 YAML 格式的 playbook 定义任务,直观且易于理解。

无代理架构:通过 SSH 连接直接在远程主机上执行任务,无需在目标机器上安装任何代理软件或守护进程。

模块化设计:提供了大量的内置模块,覆盖了操作系统配置、网络设备管理、云计算服务操作等众多领域。用户也可以自定义模块来满足特定需求。

幂等性:许多 Ansible 模块都具有幂等性,即无论执行多少次,只要系统状态达到预期,都不会再做更改,确保了系统的稳定性。

库存管理(Inventory):Ansible 使用 inventory 文件管理要操作的目标主机列表,可以灵活地根据组(groups)和主机变量进行运维操作。

角色(Roles):为了代码复用和组织结构清晰,Ansible 提供了角色的概念,用于将一组相关的任务、文件和模板打包在一起。

动态_inventory:支持从各种源获取动态主机信息,如 EC2 API、OpenStack 或者 CMDB 系统。

安全传输:通过使用 SSH 密钥对等方式保证数据的安全传输。

扩展性强:除了丰富的官方模块库,Ansible 还有一个活跃的社区,不断开发新的模块和插件以支持更多的功能。

一键回滚:部分高级特性如 ansible-bender 支持容器镜像构建时的一键回滚。

(三)安装ansible

[root@test opt]#yum  install epel-release.noarch -y
#安装epel源
[root@test opt]#yum install ansible  -y
#安装ansible

二、主机组

Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内

(一)定义主机组

[root@test opt]#vim /etc/ansible/hosts 
......
[web]            
192.168.83.60
192.168.83.100
#定义一个主机组,组名为web,改组包含的IP地址有192.168.83.60与192.168.83.100
......

使用ssh-keygen对指定主机进行免密登录

[root@test opt]#ssh-keygen -t rsa           #生成密钥文件
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:zMgIug5GNxry7YClXFETG+Lqh14BAkZEQCAhNkOE3HY root@docker
The key's randomart image is:
+---[RSA 2048]----+
|^&.. =.          |
|B.+ooE+          |
|..oo..           |
|..o..o +         |
|o+.=. o S        |
|=**.o            |
|=*oo.            |
|= oo             |
| o  .            |
+----[SHA256]-----+

[root@test opt]#sshpass -p '123' ssh-copy-id root@192.168.83.60
-p '123':指定远程主机,root用户的登录密码
[root@test opt]#sshpass -p '123' ssh-copy-id root@192.168.83.100

测试联通性

[root@test opt]#ansible web -m ping
192.168.83.60 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.83.100 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

(二)组嵌套

可以将多个组合并在同一个组内

在/etc/ansible/hosts文件中添加多个主机清单

[root@test opt]#vim  /etc/ansible/hosts
......
[web]
192.168.83.60
192.168.83.100

[web1]
192.168.83.[10:15]   #表示IP地址为192.168.83.10~192.168.83.15之间的所有主机

[webs:children]
web
web1
#将组名为web与web1中的所有主机,嵌套在同一个组下,取名为webs,childern为固定格式
#webs: 是一个父组,通过:children后缀表明它用来汇总或包含其他组作为其“子组”(children)
......

使用 ansible [组名] --list 列出指定组名包含的所有IP地址

(三)组变量

Inventory变量名作用
ansible_hostansible连接节点时的IP地址
ansible_port连接对方的端口号,ssh连接时默认为22
ansible_user

连接对方主机时使用的主机名。不指定时,将使用执行ansible或

ansible-playbook命令的用户

ansible_password连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
ansible_ssh_private_key_file指定密钥认证ssh连接时的私钥文件
ansible_ssh_common_args提供给ssh、sftp、scp命令的额外参数
ansible_become允许进行权限提升
ansible_become_method指定提升权限的方式,例如可使用sudo/su/runas等方式
ansible_become_user提升为哪个用户的权限,默认提升为root
ansible_become_password提升为指定用户权限时的密码
[root@test opt]#vim  /etc/ansible/hosts
......
[web]
192.168.83.60
192.168.83.100
192.168.83.30 ansible_password=123 ansible_port=22 ansible_user=root
#指定链接主机IP地址为192.168.83.30
#ansible_password=123:表示使用ssh协议访问该主机的密码为123
#ansible_port=22:指定访问端口为22。默认端口为22
#ansible_user=root:指定访问用户为root用户,可以指定其它普通用户,但是在操作命令时,需要一定权限
......

添加完变量后,就可以不是用ssh-keygen进行免密登录,但是一般不推荐这种方法,因为是明文密码,可能会造成外泄

三、Ansiible模块使用

[root@test opt]#ansible-doc -l |wc -l   #统计ansible一共有多少个模块
3387

下面就列举几个常用的模块

(一)Command 模块

功能:在远程主机执行命令,此为默认模块,可忽略 -m 选项

注意:此命令不支持 $VARNAME < > | ; & 等,可以用shell模块实现

注意:此模块不具有幂等性

比如查看定义的host组中的主机/opt目录下的文件

(二)shell模块

功能:和command相似,用shell执行命令,支持各种符号,比如:*,$, >

注意:此模块不具有幂等性

(三)Yum模块

yum和apt模块分别用于管理基于RHEL/CentOS系列(使用Yum或DNF包管理器)以及基于Debian/Ubuntu系列(使用Apt包管理器)的Linux系统的软件包。

常用参数

name                       所安装的包的名称
state                         present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache          强制更新yum的缓存
conf_file                   指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check  是否禁止GPG checking,只用于presentor latest。
disablerepo              临时禁止使用yum库。 只用于安装或更新时。
enablerepo               临时使用的yum库。只用于安装或更新时

使用yum模块,可以在远程主机上同时安装软件

使用shell模块查看安装版本

(四)Service模块

service模块的作用是管理远程主机上的服务

常用参数

name参数           #指定需要操作的服务名称,比如httpd
state参数            #指定服务的状态,可用值有 started(开启)、stopped(关闭)、restarted(重启)、reloaded(重新加载配置文件)。
enabled参数       #指定是否将服务设置为开机启动项, yes表示设置为开机启动,no不设置

ansible的核心模块较多,更多的模块操作,可以访问下列的链接,去查看更多的模块使用

链接地址:Ansible基本介绍与模块使用_ansible script模块-CSDN博客

四、Playbook

(一)Playbook基础

Playbook是Ansible的配置、部署和编排语言。它以YAML格式编写,用来描述一组任务序列,以及这些任务如何在不同主机上执行。Playbook使得复杂的多步骤部署变得简单易管理。

(二)Playbook结构

一个基本的Playbook由以下部分构成:

Hosts指定:定义了执行任务的目标主机或主机组。

Tasks:一系列要执行的任务列表,每个任务调用一个特定的模块。

Handlers:特殊任务,仅在被其它任务通知时执行,常用于服务重启等。

Variables:用于存储配置信息,可以在Playbook中或外部文件定义。

Roles:组织相关任务、文件、变量的集合,促进代码复用和模块化。

(三)Playbook示例

[root@test opt]#cat  tree.yaml
---    
#这是YAML文档的开始声明,表明一个新的文档或“playbook”即将开始
- name: tree     
#Playbook的描述性名称,本例中为"tree",用于说明此Playbook的功能或目的
  hosts: host    
#指定此Playbook将要执行于host组的所有主机上
  gather_facts: false 
#设置是否收集目标主机的系统信息,默认为True。设为false可以加快执行速度
  remote_user: root
#指定连接目标主机时使用的用户名
  tasks:
#Playbook的核心部分,包含了一系列任务(tasks),这些任务将会在上面定义的主机上顺序执行
    - name: install tree
#任务的描述性名称,这里是"install tree",说明任务是为了安装tree软件包
      yum: name=tree state=latest
#使用Ansible的yum模块来管理软件包,state=latest表示安装最新版本
      ignore_errors: True
#该任务的配置选项,当设为True时,即使该任务执行出错,Ansible也会继续执行后续任务,而不是立即停止

[root@test opt]#ansible-playbook tree.yaml  #加载执行指定的yaml文件

PLAY [tree] ***************************************************************************************************

TASK [install tree] *******************************************************************************************
changed: [192.168.83.60]

PLAY RECAP ****************************************************************************************************
192.168.83.60              : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

yaml文件注意格式,以空格缩进区分层级

验证命令是否安装

(四)定义、引用变量

[root@test opt]#vim  vars.yaml 
[root@test opt]#cat  vars.yaml 
---
- name: vars
#Playbook的描述性名称
  hosts: host
#指定此Playbook将要执行于host组的所有主机上
  gather_facts: false
  remote_user: root
  vars:
    - username: lisi
#在vars下定义了一个变量 username,其值为 "lisi"。这个变量在playbook的后续任务中引用
  tasks:
    - name: create user
#描述为 "create user",意在创建一个新的系统用户
      user: name={{username}} uid=1200
#使用user模块
#name={{username}}:设置用户名称,使用刚才定义的变量 {{username}},创建用户名为lisi的用户
#uid=1200:设置uid为1200
    - name: copy file
#描述为 "copy file",目的是将一段内容复制到远程主机上的一个文件中
      copy: content="{{ansible_version}}" dest=/opt/kernel.txt
#使用coyp模块
#content: 指定了要写入文件的内容,这里使用了内置的 Ansible 变量 {{ansible_version}},
#即 Ansible 的当前运行版本号,作为文件内容
#dest: 指定目标文件的路径,即/opt/kernel.txt

常用的Ansible内置变量

ansible_version 表示 Ansible 的版本信息。
inventory_hostname 返回当前正在处理的主机名,即清单文件中定义的主机名。
inventory_hostname_short 返回清单文件中主机名的第一部分,通常是去掉域名后的主机名。
hostvars

 一个字典,包含了在同一 playbook 运行中所有主机的变量。

可以通过 hostvars['hostname'] 访问其他主机的变量。

group_names 当前主机所属的所有组名列表。
play_hosts 当前 play 中所有目标主机的列表。
ansible_facts

 一个包含收集到的目标系统事实信息的字典,

例如网络接口信息 (ansible_default_ipv4, ansible_all_ipv4_addresses)、

操作系统类型 (ansible_system)、主机架构 (ansible_architecture) 等。

ansible_os_family 表示操作系统家族,如 'RedHat', 'Debian' 等。
ansible_distribution 操作系统的具体发行版名称,如 'Ubuntu', 'CentOS' 等。
ansible_hostname 目标主机的 hostname。
ansible_env 包含目标主机环境变量的字典。
ansible_connection 当前连接到主机所使用的连接插件类型。
ansible_python_interpreter 当前用于执行Python脚本的Python解释器路径。

(五)when条件判断

在Ansible中,when条件判断是一种强大的控制结构,允许你根据特定条件来决定是否执行某个任务。这对于实现任务执行的灵活性和针对性非常有用,特别是在管理具有不同配置或需求的多主机环境时

基本语法
when条件可以放在任务定义之下,使用YAML语法编写。其基本形式如下:

- name: 任务描述
  action: 任务模块及参数
  when: 条件表达式

条件表达式

条件表达式可以是简单的布尔表达式、比较运算符、变量检查、逻辑运算符组合等。一些常见的用法包括:

  • 简单条件:直接比较或检查变量,如 when: ansible_os_family == RedHat'',这会检查目标主机的操作系统家族是否为RedHat
  • 逻辑运算:支持and、or、not等逻辑运算符,例如 when: ansible_distribution == 'Ubuntu' or ansible_distribution == 'CentOS'。
  • 存在性检查:使用when: variable is defined或when: variable | default('') != ''来检查变量是否已定义或非空。
  • 数值和字符串比较:比如 when: ansible_memory_mb.real.total > 2048,比较内存大小

首先定义多个主机

在主机名为hy的主机上安装 httpd服务

---
- name: httpd
  hosts: web
  remote_user: root
  tasks:
    - name: firewalld
      service: name=firewalld state=stopped
#使用service模块,关闭防火墙,也可以使用shell或command模块关闭selinux
    - name: install httpd
      yum: name=httpd 
#使用yum模块安装httpd软件包
      when: ansible_hostname == 'hy'
#进行条件判断,仅当主机名为'hy'时执行此任务
#ansible_hostname为内置变量,反回组内的所有主机名
    - name: start httpd
      service: name=httpd state=started
      when: ansible_hostname == 'hy'

注意:

gather_facts 参数的值需要设置为ture(默认),可以不添加参数,因为关闭此参数,ansible获取不到主机信息,后面的内置变量,如ansible_hostname无法识别

[root@test opt]#vim  httpd.yaml
[root@test opt]#ansible-playbook httpd.yaml 

PLAY [httpd] **************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [192.168.83.60]
ok: [192.168.83.100]
ok: [192.168.83.30]
......

[root@test opt]#ansible web -a 'rpm -q httpd'
192.168.83.30 | FAILED | rc=1 >>
未安装软件包 httpd non-zero return code
192.168.83.60 | FAILED | rc=1 >>
未安装软件包 httpd non-zero return code
192.168.83.100 | CHANGED | rc=0 >>
httpd-2.4.6-99.el7.centos.1.x86_64   #主机名为hy

(六)迭代

Ansible中的迭代允许你对列表或其他可迭代对象中的每一项执行一个任务或一组任务,这是处理重复性工作时非常有用的特性。迭代可以通过几种方式实现,最常用的是使用loop或历史上的with_items

---
- name: Create Directories on Hosts
  hosts: host
  tasks: 
    - name: Create Specified Directories
      file:                   #使用file模块
        path: "{{item}}"      
#指定要操作的文件或目录路径。
#使用{{ item }}表示循环中的当前项目,每次迭代时item的值会依次替换为列表中的每个路径
        state: directory 
#设定资源的状态,这里是directory,意味着如果指定的路径不存在,则创建目录
      with_items:             
#Ansible中用来迭代列表的关键词。指定接下来的任务需要对提供的列表中的每一个元素执行一次。
        - /data
        - /data/test01
        - /data/test02
#定义了要创建的目录路径

#整个playbook定义了一个操作,即在名为host的组内所有主机上创建with_items定义的一系列目录

五、实战---使用Playbook编译安装nginx

[root@test opt]#vim /etc/ansible/hosts 
......
[nginx]            
192.168.83.30

准备nginx安装包与安装脚本文件

[root@test data]#ls
nginx-1.18.0.tar.gz  nginx.sh
[root@test data]#chmod +x nginx.sh
#给脚本文件添加执行权限

查看脚本文件

[root@test data]#cat nginx.sh 
#/bin/bash
systemctl  start  nginx  >>/dev/null
if [ $? -eq 0 ];then 
echo  "nginx服务已安装"
else
useradd -M -s /sbin/nologin nginx
cd  /opt
wget http://nginx.org/download/nginx-1.18.0.tar.gz >>/dev/null
echo "正在安装,请耐心等待"
tar xf   nginx-1.18.0.tar.gz
cd  /opt/nginx-1.18.0
yum -y install gcc pcre-devel openssl-devel zlib-devel openssl  openssl-devel  &>>/dev/null
./configure --prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
make -j `lscpu|sed -n '4p'|awk '{print $2}'`&>>/dev/null
make  install  &>>/dev/null
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
cat >  /usr/lib/systemd/system/nginx.service  <<EOF
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -1 $MAINPID
ExecStop=/bin/kill -3 $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
chown -R nginx.nginx  /usr/local/nginx
systemctl  daemon-reload  &>>/dev/null
systemctl  enable --now nginx
echo  "nginx服务已开启"
fi

编写playbook副本

[root@test opt]#vim  nginx.yaml
[root@test opt]#cat  nginx.yaml 
---
- name: install nginx   #Playbook的描述性名称,这里是安装Nginx
  hosts: nginx          #定义执行此Playbook的目标主机组,这里指的是名为nginx的主机组
  remote_user: root     #指定远程执行任务时使用的用户名,这里是root用户
  tasks:                #开始定义具体任务列表
    - name: firewalld stop   #任务一:停止firewalld服务
      service: name=firewalld state=stopped
    - name: package          #任务二:复制Nginx安装包到目标主机
      copy: src=/data/nginx-1.18.0.tar.gz dest=/opt/ owner=root group=root
    - name: Execute script   #任务三:执行编译安装nginx脚本文件
      script: /data/nginx.sh  #使用script模块

执行playbook脚本并进行测试

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

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

相关文章

BUUCTF [极客大挑战 2019]EasySQL 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; [极客大挑战 2019]EasySQL 1 密文&#xff1a; 解题思路&#xff1a; 1、根据题目提示&#xff0c;并且网站也存在输入框&#xff0c;尝试进行SQL注入。 首先&#xff0c;判断提交方式&#xff0c;随机输入数据…

力扣刷题--数组--第二天

今天仍然做二分查找相关的题目。先来回顾一下二分查找的方法和使用的条件。二分查找是在数组中查找目标值的一种方法&#xff0c;通过边界索引确定中间索引&#xff0c;判断中间索引处的元素值和目标值的大小&#xff0c;来不断缩小查找区间。使用二分查找有如下一些限制&#…

PXE批量安装

系统装机的三种引导方式 u盘光盘网络装机 光盘&#xff1a; 1.类似于usb模式 2.刻录模式 系统安装过程 加载boot loader Boot Loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序&#xff0c;我们可以初始化硬件设备、建立内存空间的映射图&#xff0c;从…

使用开放式用户通信连接两台西门子S71200plc

步骤1.在项目中创建两台PLC。 步骤2.分别设置两个PLC的参数。 plc1 plc2 步骤3.对两个plc进行组态 步骤4.在plc1和plc2中各自创建DB块&#xff0c;用于通信。 须在块的属性中取消优化块的访问选项。 plc1 plc2 步骤5.往plc1的main块中编写代码。 步骤6.往plc2的main块中编写…

AndroidStudio的Iguana版的使用

1.AndroidStudio介绍 Android Studio 是用于开发 Android 应用的官方集成开发环境 (IDE)。Android Studio 基于 IntelliJ IDEA 强大的代码编辑器和开发者工具&#xff0c;还提供更多可提高 Android 应用构建效率的功能&#xff0c;例如&#xff1a; 基于 Gradle 的灵活构建系统…

XORM 框架的使用

1、xorm 1.1、xorm 简介 xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。 特性 支持 struct 和数据库表之间的灵活映射&#xff0c;并支持自动同步事务支持同时支持原始SQL语句和ORM操作的混合执行使用连写来简化调用支持使用ID, In, Where, Limit,…

nginx模型设计和进程讲解

一. Nginx进程模型解析 1. master主进程 和 worker工作进程 [rootlocalhost sbin]# ps -ef|grep nginx root 15411 1 0 21:08 ? 00:00:00 nginx: master process ./nginx nobody 15412 15411 0 21:08 ? 00:00:00 nginx: worker process root…

pytest教程-39-钩子函数-pytest_runtest_setup

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_runtest_protocol钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_runtest_setup钩子函数的使用方法。 pytest_runtest_setup 钩子函数在每个测试用例的 setup 阶段被调用。这…

学习软考----数据库系统工程师22

关系运算 基本的关系代数运算 拓展的关系运算 除&#xff1a;需要S连接中属性为C和D的两个元组都与R连接一样&#xff0c;且在R连接中对应的另外的元素完全一致 总结

聊聊 ASP.NET Core 中间件(三):如何创建自己的中间件?

前言 本质上&#xff0c;中间件类也是一个普通的 .NET 类&#xff0c;它不需要继承任何父类或者实现任何接口。 但是有几个约定&#xff1a; 需要有一个构造方法构造方法至少要有一个 RequestDelegate 类型的参数&#xff0c;用来指向下一个中间件。需要定义一个名字为 Invo…

交易复盘-20240507

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 蔚蓝生物 (5)|[9:25]|[36187万]|4.86 百合花…

STM32F10x移植FreeRTOS

一、获取FreeRTOS源码 &#xff08;1&#xff09;登录FreeRTOS官网&#xff1a;www.freertos.org&#xff0c;下载第一个压缩包 &#xff08;2&#xff09;通过GitHub网站&#xff1a;github.com/FreeRTOS/FreeRTOS下载&#xff0c;由于该网站服务器在国外&#xff0c;所以访问…

28.leetcode---前K个高频单词(Java版)

题目链接: https://leetcode.cn/problems/top-k-frequent-words/description/ 题解: 代码: 测试:

巨控GRM561/562/563/564Q杀菌信息远程监控

摘要 通过程序编写、手机APP画面制作等运行系统&#xff0c;实现电脑及手机APP显示的历史曲线画面和数据图形化的实时性。 不仅流程效率提升90%以上&#xff0c;同时为杀菌生产提供有利的质量保障&#xff0c;还有效规避因触屏及内存卡的突发异常导致历史数据的丢失&#xff0…

强大的禄得可转债自定义因子轮动系统完成,可转债三低为例子

经过几天的测试终于完成了可转债自定义因子轮动&#xff0c;超过1000行的源代码 我提供了服务器的数据支持自动api下载&#xff0c;我给大家维护数据 网页 http://120.78.132.143:8023/ 录得数据支持http://120.78.132.143:8023/lude_data_app api数据支持&#xff0c;我提供…

杭州恒生面试,社招,3年经验

你好&#xff0c;我是田哥 一位朋友节前去恒生面试&#xff0c;其实面试问题大部分都是八股文&#xff0c;但由于自己平时工作比较忙&#xff0c;完全没有时间没有精力去看八股文&#xff0c;导致面试结果不太理想&#xff0c;HR说节后通知面试结果&#xff08;估计是凉了&…

传统汽车空调系统工作原理

1.首先讲一个概念 液体变成气体&#xff1a;吸热 气体变成液体&#xff1a;放热 2.在汽车空调系统中热量的传递的介质不是水&#xff0c;而是氟利昂&#xff0c;简称&#xff1a;“氟”。 3.传统式汽车空调结构如下 该三个部件位于车头进气口位置 该部位位于汽车驾驶车厢前方…

常见的容器技术有哪些

容器技术是一种轻量级的软件封装方式&#xff0c;它将软件代码及其依赖项打包在一起&#xff0c;这样应用可以在任何支持容器的系统上无缝运行。它允许应用程序及其依赖项在一个隔离的环境中运行&#xff0c;这个环境被称为容器。容器技术有助于提高应用程序的可移植性、一致性…

Vue3专栏项目 -- 一、第一个页面(上)

一、ColumnList 组件&#xff08;专栏列表组件&#xff09;编码&#xff1a; 该组件要接收一个数组&#xff0c;数组中是一个个专栏数据&#xff0c;数据中包括id、title、avator、description。所以我们定义一个泛型&#xff0c;泛型为id为number类型title为string类型如下这…

初识C++ · 类和对象(下)

目录 1 再谈构造函数 2 类中的隐式类型转换 3 Static成员 4 友元和内部类 5 匿名对象 6 编译器的一些优化 1 再谈构造函数 先看一段代码&#xff1a; class Date { public :Date(int year, int month, int day){_year year;_month month;_day day;} private:int _ye…