Ansible自动化运维(四)jinja2 模板、Roles角色详解

👨‍🎓博主简介

  🏅云计算领域优质创作者
  🏅华为云开发者社区专家博主
  🏅阿里云开发者社区专家博主
💊交流社区:运维交流社区 欢迎大家的加入!
🐋 希望大家多多支持,我们一起进步!😄
🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗


文章目录

  • 一、jinjia2 模板
    • 1.1 在 Ansible 中的使用
    • 1.2 jinjia2 模板语法
      • 1.2.1 基础语法
      • 1.2.2 流程控制
      • 1.2.3 过滤器
      • 1.2.4 其他控制结构
    • 1.3 templates 模块
    • 1.4 jinja2 使用案例
  • 二、Roles 角色
    • 2.1 Roles介绍与优势
    • 2.2 Roles 的目录结构
    • 2.3 ansible-galaxy 命令
    • 2.4 使用Roles(部署nginx)
    • 2.5 查看 nginx 树形目录结构
  • 三、相关文章

一、jinjia2 模板

jinja2是Python的全功能模板引擎。在python的WEB开发中被广泛应用。

Ansible通常会使用jinja2模板来修改被管理主机的配置文件等。

1.1 在 Ansible 中的使用

  使用Ansible的jinja2模板也就是使用template 模块,该模块和copy 模块一样,都是将文件复制到远端主机上去,但是区别在于,template 模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。比如想把脚本中的变量名改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名。

Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。通常jinja2模板文件的后缀为.j2

1.2 jinjia2 模板语法

1.2.1 基础语法

  • 基础语法

1)playbook文件使用template模块

2)模板文件里面变量使用{{名称}},比如{{PORT}}或使用facts

3){{}}也可以使用表达式,比如{{ 3+5 }} {{3 in [1,2,3,4,5] -}}

说明:{{}}中的表达式其实就是python中的表达式,可以包括比较运算,算数运算,逻辑运算,成员运行。

该模板支持:

字符串:使用单引号或双引号;
  数字:整数,浮点数;
  列表:[item1, item2, ...]
  元组:(item1, item2, ...)
  字典:{key1:value1, key2:value2, ...}
  布尔型:true/false
  算术运算:
    +, -, *, /, //, %, **
  比较操作:
    ==, !=, >, >=, <, <=
  逻辑运算:
    and, or, not
  • 模板通常都是通过引用变量来运用的
  • 【实例】
  1. 创建模板文件:
    首先,需要创建一个包含Jinja2模板的文件。这个文件通常包含要插入变量或表达式的位置。可以在文件中使用{{ }}来包裹变量或表达式。

    例如,创建一个名为 my_template.j2 的模板文件:

    [root@localhost jinja2]# vim my_template.j2 
    ServerName {{ hostname }}
    Listen {{ port }}
    Debug {{ debug_mode }}
    
  2. 在Playbook中使用模板:
    在 Ansible Playbook中,可以使用template模块来加载模板文件并将变量传递给它。以下是一个示例Playbook:

    [root@localhost jinja2]# vim jinja.yml
    ---
    - name: 使用Jinja2模板
      hosts: your_target_hosts
      vars:
        hostname: example.com
        port: 8080
        debug_mode: True
      tasks:
        - name: 生成配置文件
          template:
            src: my_template.j2
            dest: /etc/ansible/yml/jinja2/myapp.conf
    

    在这个示例中,我们使用了template模块,指定了模板文件的源 (src) 和目标 (dest)。我们还传递了变量 hostnameportdebug_mode,这些变量会在模板中替换{{ }}中的相应位置。

  3. 运行Playbook:
    运行上述Playbook,Ansible将使用模板文件生成 /etc/ansible/yml/jinja2/myapp.conf 配置文件,并将模板中的{{ }}替换为变量的值。

# 结果值为:
ServerName example.com
Listen 8080
Debug True

模板文件中的{{ }}不仅可以包含变量,还可以包含表达式,如您所述的比较运算、算术运算、逻辑运算等。这使得您可以在模板中执行各种操作以生成需要的配置或文本。

Jinja2模板的强大之处在于它允许创建灵活和动态的配置文件,以适应不同的场景和变量值。

1.2.2 流程控制

  • 流程控制

  • 条件判断

使用{% if %}{% endif %}块来实现条件语句。以下是一个示例:

格式:

{% if EXPR %}
	执行内容
{% else %}
	执行内容
{% endif %}

实例:

{% if is_production %}
    # 生产环境配置
    DebugLevel: 0
{% else %}
    # 开发/测试环境配置
    DebugLevel: 2
{% endif %}
  • 多条件判断

格式:

{% if EXPR %}
	执行内容
{% elif EXPR %}
	执行内容
{% else %}
	执行内容
{% endif %}

实例:

{% if is_production %}
	DebugLevel: 0
{% elif is_production %}
	DebugLevel: 1
{% else %}
	DebugLevel: 2
{% endif %}

在这个示例中,根据is_production变量的值,将生成不同的配置。

  • 循环表达式

可以使用{% for %}{% endfor %}块来实现循环。以下是一个示例:

格式:

{% for i in EXPR %}
	执行内容
{% endfor %}

实例:

{% for item in list_items %}
    - {{ item }}
{% endfor %}

在这个示例中,list_items 是一个包含多个元素的列表,模板将循环遍历列表中的每个元素并生成相应的输出。

说明:默认不支持breakcontinue的,但是可以使用ansible的扩展选项,在配置/etc/ansible/ansible.cfg中的132行中:

jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n,jinja2.ext.loopcontrols

1.2.3 过滤器

  • 过滤器

Jinja2还支持过滤器,可以使用过滤器来对变量进行操作。例如,可以使用default过滤器来设置默认值:

{{ variable | default("default_value") }}

或者,您可以使用length过滤器来获取列表的长度:

The list has {{ list_items | length }} items.

1.2.4 其他控制结构

  • 其他控制结构

Jinja2还支持其他控制结构,如{% include %}用于包含其他模板文件,以及{% macro %}{% call %}用于定义和调用宏。

请注意,Jinja2语法和功能非常强大,支持许多高级用例,例如宏、继承、自定义过滤器等。要更深入地了解Jinja2模板的流程控制和功能,请查看Jinja2的官方文档。在Ansible中,可以将这些模板用于生成配置文件、编排任务等,以满足不同的需求和环境。

1.3 templates 模块

  template模块与copy模块的用法十分类似,只是更多用于jinja2模板的渲染,也就是模板文件中可以引用变量,实现对不同主机有定制化的配置。

copy与template的区别

  • copy模块不替代参数,template模块替代参数
  • template的参数几乎与copy的参数完全相同
  • 常用参数:
参数解析
src指定本地jinja2模板文件的位置
dest指定目标远程主机路径
backup指定是否备份,默认值no
mode设置权限
user设置用户
group设置用户组

templates 模块的使用: jinja2模板的基础用法

1.4 jinja2 使用案例

比如需要实现对被控端主机安装redis服务,默认的redis服务只监听本地的127.0.0.1端口,换句话说,其他主机是不可以访问该redis服务器的,如何来解决这个问题呢?此时就可以使用jinja2的模板,在其中引用变量,使用template模块进行渲染。

本案例使用了:jinja2模板、templates模块、copy模块、yum模块、shell模块、service模块、vars定义变量、register变量注册、ignore_errors忽略错误、tags标签、when判断、notifyhandlers通知与触发(处理程序)

  • 1、创建一个自定义的Redis配置模板文件,如 redis_conf.j2,并在其中修改Redis绑定地址以侦听所有IP地址:
[root@localhost redis]# vim redis_conf.j2
bind {{ ansible_host }} 127.0.0.1
port {{ redis_port }}
protected-mode no
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice

在此示例中,我们使用了 bind {{ ansible_host }} 127.0.0.1 来告诉Redis服务只接受本地IP连接,并使用变量 redis_port 来指定Redis端口。

  • 2、在Ansible Playbook中,使用template模块加载该模板并渲染它,然后将渲染后的配置文件复制到Redis配置文件目录。以下是一个示例Playbook:
[root@localhost redis]# vim redis.yml
---
- name: 部署Redis服务
  hosts: web
  remote_user: root
  gather_facts: no
  vars:
    redis_port: 6379  # 指定Redis端口

  tasks:
    - name: Upload yum repo
      copy: 
        src: /etc/yum.repos.d/CentOS-Base.repo
        dest: /etc/yum.repos.d
        backup: no
      tags: 
       - upload_yum
       - upload_repo
       - redis_server

    - name: Upload epel repo
      copy:
        src: /etc/yum.repos.d/epel.repo
        dest: /etc/yum.repos.d/
        backup: no
      tags: 
       - upload_epel
       - upload_repo
       - redis_server

    - name: Check redis install
      shell: /usr/bin/rpm -q redis
      register: redis_msg
      ignore_errors: yes
      tags: 
       - check_redis
       - redis_server

    - name: Install redis server
      yum: 
        name: redis
        state: present
      when: redis_msg.failed == true
      tags: 
       - install_redis
       - redis_server

    - name: Upload redis.conf
      template:
        src: redis_conf.j2
        dest: /etc/redis.conf
      notify: Restart Redis
      tags: 
       - upload_redis.conf
       - redis_server

    - name: Start Redis server
      service:
        name: redis
        state: started
        enabled: yes
      tags: 
       - start_redis
       - redis_server

    - name: Restart Redis server
      service:
        name: redis
        state: restarted
      tags:
       - restart_redis
        
    - name: Stop Redis Server
      service: 
        name: redis
        state: stopped
      tags: 
        - stop_redis
        - uninstall_redis

    - name: uninstall Redis Server
      yum: 
        name: redis
        state: absent
      tags: 
        - uninstall_redis

  handlers:
    - name: Restart Redis
      service:
        name: redis
        state: restarted
  • 3、执行检查:
# 检查语法
[root@localhost redis]# ansible-playbook --syntax-check redis.yml 

# 列出任务列表
[root@localhost redis]# ansible-playbook --list-tasks redis.yml 

# 列出所有tags标签
[root@localhost redis]# ansible-playbook --list-tags redis.yml 

在这里插入图片描述

tasks 解析:(列出tasks任务的时候后面也会包含tags标签,每个任务用的标签都有哪些)

tasks:
  Upload yum repo		 # 更新yum源
  Upload epel repo		 # 更新yum扩展源
  Check redis install	 # 检查是否安装过 redis
  Install redis server	 # 安装 redis
  Upload redis.conf		 # 更新 redis 配置文件
  Start Redis server	 # 启动 redis
  Restart Redis server	 # 重启 redis
  Stop Redis Server		 # 停止 redis
  uninstall Redis Server # 卸载 redis

tags 解析:(列出tasks任务的时候后面也会包含tags标签,每个任务用的标签都有哪些)

TASK TAGS: 
  upload_repo		# 更新yum源,包含:Upload yum repo,Upload epel repo
  upload_yum		# 更新yum源
  upload_epel		# 更新yum扩展源
  redis_server		# 一键安装redis,包含:Upload yum repo、Upload epel repo、Check redis install、Install redis server、Upload redis.conf、Start Redis server
  check_redis		# 检查是否安装 redis
  upload_redis.conf	# 更新 redis 配置文件
  install_redis		# 安装 redis
  restart_redis		# 重启 redis
  start_redis		# 启动 redis
  stop_redis		# 停止 redis
  uninstall_redis	# 卸载 redis
  • 4、执行yml脚本
# 执行更新yum源
[root@localhost redis]# ansible-playbook redis.yml -t upload_repo

# 检查是否安装过 redis,会有报错说找不到,不会影响,里面有 ignore_errors 忽略错误;
[root@localhost redis]# ansible-playbook redis.yml -t check_redis

# 执行安装 redis(不能单独执行redis,会报错,因为有一个when判断需要调用上面的查询是否有redis服务)
[root@localhost redis]# ansible-playbook redis.yml -t check_redis,install_redis

# 执行更新 redis 配置文件
[root@localhost redis]# ansible-playbook redis.yml -t upload_redis.conf
# 执行完毕可以查看redis状态及redis端口是否启动,正常是都启动的;

# 执行停止 redis
[root@localhost redis]# ansible-playbook redis.yml -t stop_redis
# 执行完毕可以查看redis状态及redis端口是否启动,如果没有那就是没问题,因为这是停止;

# 执行卸载 redis
[root@localhost redis]# ansible-playbook redis.yml -t uninstall_redis
# 执行完可以使用: rpm -q redis 查看或使用 check_redis标签检查

# 执行一键安装redis
[root@localhost redis]# ansible-playbook redis.yml -t redis_server
# 执行完毕可以查看redis状态及redis端口是否启动,正常是都启动的;

在这里插入图片描述

二、Roles 角色

  在Ansible中,有一个roles的概念。roles并不是指定具体的东西,而是一种规范,将复杂的Playbook分割为多个文件的机制,简化复杂的Playbook编写,并且使Playbook的复用变得简单。

建议:每个roles最好只使用一个tasks这样方便调用,能够很好的做到解耦;

2.1 Roles介绍与优势

一般情况下将roles写在 /etc/ansible/roles 中,也可以写在其他任意位置(写在其他位置要自己手动建立一个roles文件夹)

  • 对于以上所有方式有个缺点就是无法实现同时部署web、database、keepalived等不同服务或者不同服务器组合不同的应用就需要写多个yaml文件,很难实现灵活的调用
  • roles用于层次性,结构化地组织playbook。roles能够根据层次结果自动装载变量文件、tasks以及handlers等。
  • 要使用roles只需要在playbook中使用include指令即可。
  • 简单来讲,roles就是通过分别将变量(vars)、文件(files)、任务(tasks)、模块(modules)以及处理器(handlers)放置于单独的目录中,并且可以便捷的include它们地一种机制。
  • 角色一般用于基于主机构建服务的场景中,但是也可以用于构建守护进程等场景中。

2.2 Roles 的目录结构

  • 创建一个角色目录,用于演示:
mkdir -pv /etc/ansible/roles/{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
  • 查看Roles的目录结构:

在这里插入图片描述

  • 目录解析:
  • /etc/ansible/roles/:存放roles的文件路径

  • httpd:存放apached服务的yml文件

  • mysql:存放mysql服务的yml文件

  • nginx:存放nginx服务的yml文件

  • default:此目录至少应该有一个名为main.yml的文件,用于设定默认变量;

  • files:存储由copy或者script等模块调用的文件或者脚本;

  • handlers:此目录中至少应该有一个名为main.yml的文件,用于定义各个handler;其他文件需要由main.yml进行包含调用;

  • meta:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定以及依赖关系,其他文件需要由main.yml进行包含调用;

  • tasks:此目录中至少应该有一个名为main.yml的文件,用于定义各个task;其他文件需要由main.yml进行包含调用;

  • templates:存储由templates模块调用的模板文件;

  • vars:此目录至少应该有一个名为main,yml的文件,用于定义各个variable;其他的文件需要由main.yml进行包含调用;

2.3 ansible-galaxy 命令

ansible-galaxy命令用于管理roles,同时也可以在 galaxy.ansible.com 上下载别人写好的roles

  • 1、初始化roles的目录结构
[root@localhost roles]# ansible-galaxy init /etc/ansible/roles/webserver
- Role /etc/ansible/roles/webserver was created successfully
  • 2、安装别人写好的roles
[root@localhost roles]# ansible-galaxy role install -p /etc/ansible/roles tenequm.mysql
- downloading role 'mysql', owned by tenequm
- downloading role from https://github.com/tenequm/ansible-mysql/archive/1.0.1.tar.gz
     [ERROR]: failed to download the file: <urlopen error timed out>
    [WARNING]: - tenequm.mysql was NOT installed successfully.
    ERROR! - you can use --ignore-errors to skip failed roles and finish processing the list.


# 会遇到两个报错,暂时还没找到解决方法,我们可以先使用wget去拉取,第二行downloading已经给出了地址,拉取一下;
[root@localhost roles]# wget https://github.com/tenequm/ansible-mysql/archive/1.0.1.tar.gz

# 拉取完,解压即可,解压后的名字为:ansible-mysql-1.0.1
[root@localhost roles]# tar xf 1.0.1.tar.gz 

拉取、解压完就可以看到roles目录下多了一个新的目录ansible-mysql-1.0.1,里面存放的mysql。

在这里插入图片描述

  • 3、列出已安装的roles
[root@localhost roles]# ansible-galaxy list
# /usr/share/ansible/roles
# /etc/ansible/roles
- webserver, (unknown version)
- ansible-mysql-1.0.1, (unknown version)
[WARNING]: - the configured path /root/.ansible/roles does not exist.
  • 4、查看指定roles的信息
[root@localhost roles]# ansible-galaxy info tenequm.mysql

Role: tenequm.mysql
        description: Simply installs MySQL 5.7 on Xenial.
        commit: b3a7139ba44a91e9568345565e861e326e9d401e
        commit_message: Added priveleges configs for users.
        created: 2023-05-08T20:18:24.338543Z
        download_count: 179
        github_branch: master
        github_repo: ansible-mysql
        github_user: tenequm
        id: 103
        modified: 2023-10-10T00:48:33.420438Z
        path: (u'/root/.ansible/roles', u'/usr/share/ansible/roles', u'/etc/ansible/roles')
        upstream_id: 17029
        username: tenequm
  • 5、删除一个roles

如果是使用的wget拉取的,那么删除他的哪个roles目录就可以;

[root@localhost roles]# ansible-galaxy remove /etc/ansible/roles/tenequm.mysql
- successfully removed /etc/ansible/roles/bennojoy.mysql

2.4 使用Roles(部署nginx)

流程:

定义配置文件 --> 定义jinja2模板,生成配置文件用 --> 定义变量 --> 定义触发(通知已定义在配置文件中) --> 定义roles的yml文件

5步

检查yml语法 --> 执行roles.yml文件 --> 查看服务启动状态

  • 定义配置文件:/etc/ansible/roles/nginx/tasks/main.yml
- name: install wget
	yum: name=wget state=present
	
- name: wget nginx package
	command: " wget http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.18.0-1.el7.ngx.x86_64.rpm -O /etc/ansible/roles/nginx/files/nginx-1.18.0-1.el7.ngx.x86_64.rpm"
	
- name: cp nginx
  copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm
  
- name: install nginx
  yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest
  
- name: conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  tags: nginxconf
  notify: new conf to reload

- name: start service
  service: name=nginx state=started enabled=true
  • 定义templates生成配置文件:/etc/ansible/roles/nginx/templates/nginx.conf.j2
user  nginx; #设置nginx服务的系统使用用户
worker_processes  {{ ansible_processor_vcpus }}; #工作进程数

error_log  /var/log/nginx/error.log warn; #nginx的错误日志
pid        /var/run/nginx.pid; #nginx启动时候的pid

events {
    worker_connections  1024; #每个进程允许的最大连接数
}

http { #http请求配置,一个http可以包含多个server

    #定义 Content-Type
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    #日志格式 此处main与access_log中的main对应
    #$remote_addr:客户端地址
    #$remote_user:http客户端请求nginx认证的用户名,默认不开启认证模块,不会记录
    #$timelocal:nginx的时间
    #$request:请求method + 路由 + http协议版本
    #status:http reponse 状态码
    #body_bytes_sent:response body的大小
    #$http_referer:referer头信息参数,表示上级页面
    #$http_user_agent:user-agent头信息参数,客户端信息
    #$http_x_forwarded_for:x-forwarded-for头信息参数
    log_format  main  '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    #访问日志,后面的main表示使用log_format中的main格式记录到access.log中
    access_log  /var/log/nginx/access.log  main;

    #nginx的一大优势,高效率文件传输
    sendfile        on;
    #tcp_nopush     on;

    #客户端与服务端的超时时间,单位秒
    keepalive_timeout  65;

    #gzip  on;
    server { #http服务,一个server可以配置多个location
        listen       {{ nginxport }}; #服务监听端口
        server_name  localhost; #主机名、域名

        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;

        location / {
            root   /usr/share/nginx/html; #页面存放目录
            index  index.html index.htm; #默认页面
        }

        #error_page  404              /404.html;

        # 将500 502 503 504的错误页面重定向到 /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html { #匹配error_page指定的页面路径
            root   /usr/share/nginx/html; #页面存放的目录
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
    include /etc/nginx/conf.d/*.conf;
}
  • 定义变量: /etc/ansible/roles/nginx/vars/main.yml
nginxport: 9999
  • 定义触发:/etc/ansible/roles/nginx/handlers/main.yml

因为上面通知已经定义,所以,还需要定义一个触发;

- name: new conf to reload
  service: name=nginx state=restarted
  • 定义剧本文件:/etc/ansible/roles/nginx/roles.yml
- hosts: web
  remote_user: root
  roles:
    - nginx
  • 检查yml文件语法是否正确
[root@localhost nginx]# ansible-playbook --syntax-check roles.yml 

playbook: roles.yml

# 检查roles会自动去检查其他的yml文件的语法。
  • 执行roles.yml文件
[root@localhost nginx]# ansible-playbook roles.yml
  • 查看服务启动状态
[root@localhost nginx]# systemctl status nginx

在这里插入图片描述

2.5 查看 nginx 树形目录结构

tree /etc/ansible/roles/nginx

在这里插入图片描述

这里完整的一个使用Roles部署nginx服务就完成了;

三、相关文章

文章标题文章链接
Ansible自动化运维(一)简介及部署、清单https://liucy.blog.csdn.net/article/details/133769300
Ansible自动化运维(二)ad-hoc 模式详解https://liucy.blog.csdn.net/article/details/133772023
Ansible自动化运维(三)Playbook 模式详解https://liucy.blog.csdn.net/article/details/133899966
Ansible自动化运维(四)jinja2 模板、Roles角色详解https://liucy.blog.csdn.net/article/details/133994509

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VUE3搭载到服务器

1.搭建服务器 使用 Windows 自带的 IIS 作为服务器。 步骤如下&#xff1a;https://blog.csdn.net/qq_62464995/article/details/130140673 同时&#xff0c;上面的步骤中&#xff0c;还使用了 cpolar 将 IIS 本地网址映射到公共网址。 注&#xff1a; cpolar客户端&#xf…

【React源码 - 调度任务循环EventLoop】

我们知道在React中有4个核心包、2个关键循环。而React正是在这4个核心包中运行&#xff0c;从输入到输出渲染到web端&#xff0c;主要流程可简单分为一下4步&#xff1a;如下图&#xff0c;本文主要是介绍两大循环中的任务调度循环。 4个核心包&#xff1a; react&#xff1a;…

MySQL 篇-深入了解 DML、DQL 语言(二)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 DML、DQL 语言说明 2.0 使用 DML 实现对数据管理和操作 2.1 DML - 增添数据 insert 2.2 DML - 修改数据 update 2.3 DML - 删除数据 delete 3.0 使用 DQL 实现对…

使用.NET 升级助手工具将.net framework4.8 MVC项目升级到net6

1 新建.net framework4.8 MVC项目 随便添加一个可以访问的界面用于测试 2 对当前项目进行升级 注意&#xff1a;若要进行升级&#xff0c;首先确保本地已安装相应的sdk&#xff0c;例如&#xff1a;dotnet-sdk-6.0.402-win-x64.exe1.运行cmd命令窗口&#xff0c;进入项目所在…

【蓝桥杯】快读|min和max值的设置|小明和完美序列|​顺子日期​|星期计算|山

目录 一、输入的三种方式 1.最常见的Scanner的输入方法 2.数据多的时候常用BufferedReader快读 3.较麻烦的StreamTokenizer快读&#xff08;用的不多&#xff09; StreamTokenizer常见错误&#xff1a; 二、min和max值的设置 三、妮妮的翻转游戏 四、小明和完美序列 五…

Docker之数据卷自定义镜像

目录 一、数据卷 ​二、自定义镜像 2.1自定义centos 一、数据卷 在docker中&#xff0c;数据卷是宿主机的一个可以供一个或多个容器使用的特殊目录&#xff0c;它可以在容器之间共享和重用&#xff0c;本地与容器间传递数据更高效&#xff1b;对数据卷的修改会立马有效&#…

CSS——PostCSS简介

文章目录 PostCSS是什么postCSS的优点补充&#xff1a;polyfill补充&#xff1a;Stylelint PostCSS架构概述工作流程PostCSS解析方法PostCSS解析流程 PostCSS插件插件的使用控制类插件包类插件未来的CSS语法相关插件后备措施相关插件语言扩展相关插件颜色相关组件图片和字体相关…

代码库管理工具Git介绍

阅读本文同时请参阅-----免费的Git图形界面工具sourceTree介绍 Git是一个分布式版本控制系统&#xff0c;它可以帮助开发者跟踪和管理代码历史。Git的命令行工具是使用Git的核心方式&#xff0c;虽然它可能看起来有些复杂&#xff0c;但是一旦掌握了基本命令&#xff0c;你…

基于MQTT协议实现微服务架构事件总线

一、场景描述 昨天在博客《客户端订阅服务端事件的实现方法》中提出了利用websocket、服务端EventEmitter和客户端mitt实现客户端订阅服务端事件&#xff0c;大大简化了客户端对服务端数据实时响应的逻辑。上述方案适用于单服务节点的情形。 对于由服务集群支撑的微服务架构&…

招聘系统架构的设计与实现

在当今竞争激烈的人才市场中&#xff0c;有效的招聘系统对企业吸引、筛选和管理人才至关重要。本文将探讨招聘系统的架构设计与实现&#xff0c;帮助企业构建一个高效、可靠的人才招聘平台。 ## 1. 系统架构设计 ### 1.1 微服务架构 招聘系统通常采用微服务架构&#xff0c;将…

Java JVM虚拟机面试题

Java JVM虚拟机面试题 前言1、ThreadLocal的底层原理和应用&#xff1f;2、Java中的锁池和等待池&#xff1f;3、wait()&#xff0c;yield()&#xff0c;join()&#xff0c;sleep()的区别&#xff1f;4、你们项⽬如何排查JVM问题&#xff1f;5、YGC和FGC发生时间&#xff1f;6、…

11.vue学习笔记(组件生命周期+生命周期应用+动态组件+组件保持存活)

文章目录 1.组件生命周期2.生命周期应用2.1通过ref获取元素DOM结构2.2.模拟网络请求渲染数据 3.动态组件3.1.A&#xff0c;B两个组件 4.组件保持存活&#xff08;销毁期&#xff09; 1.组件生命周期 每个Vue组件实例在创建时都需要经历一系列的初始化步骤&#xff0c;比如设置…

探索AI视频模型的无限可能:OpenAI的Sora引领创新浪潮

文章目录 &#x1f4d1;前言一、技术解析二、应用场景三、未来展望四、伦理与创意五、用户体验与互动&#x1f324;️总结 &#x1f4d1;前言 随着人工智能技术的蓬勃发展&#xff0c;AI视频模型正逐渐成为科技领域的新宠。在这个变革的浪潮中&#xff0c;OpenAI推出的首个AI视…

Spring中 Unsupported class file major version 61 报错

初学Spring时遇到的一个错误&#xff1a;Unsupported class file major version 61 &#xff0c;如图所示&#xff1a; 网上查了一下大概是JDK的版本与Spring的版本不一致导致的错误&#xff1b;刚开始我用的Spring版本是&#xff1a; <dependencies><dependency>…

(全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF

研究生英语读写教程基础级教师用书PDF 研究生英语读写教程提高级教师用书PDF pdf下载&#xff08;完整版下载&#xff09; &#xff08;1&#xff09;研究生英语读写教程基础级教师用书PDF &#xff08;2&#xff09;研究生英语读写教程基提高级教师用书PDF

【Pytorch深度学习开发实践学习】Pytorch实现LeNet神经网络(1)

1.model.py import torch.nn as nn import torch.nn.functional as F引入pytorch的两个模块 关于这两个模块的作用&#xff0c;可以参考下面 Pytorch官方文档 torch.nn包含了构成计算图的基本模块 torch,nn.function包括了计算图中的各种主要函数&#xff0c;包括&#…

linux gdb 调试工具

1.写程序 首先&#xff0c;我们先写出一个 .c 或者.cpp程序 如 然后 gcc -g hello.c -o hello 或者 g -g hello.cpp -o hello &#xff08;-g&#xff09;要加 2. gdb调试 用 gdb &#xff08;可执行程序&#xff0c;如hello&#xff09; 进入之后&#xff0c;有…

Window系统安装USB Redirector结合cpolar实现远程访问本地USB设备

文章目录 前言1. 安装下载软件1.1 内网安装使用USB Redirector1.2 下载安装cpolar内网穿透 2. 完成USB Redirector服务端和客户端映射连接3. 设置固定的公网地址 前言 USB Redirector是一款方便易用的USB设备共享服务应用程序&#xff0c;它提供了共享和访问本地或互联网上的U…

物业智能水电抄表管理系统

物业智能水电抄表管理系统是物业管理行业的关键技术之一&#xff0c;其结合了智能化、远程监控和数据分析等功能&#xff0c;为物业管理公司和业主提供了高效、精准的水电抄表管理解决方案。该系统具有多项优势&#xff0c;能够提升物业管理效率&#xff0c;降低成本&#xff0…

[计算机网络]--MAC/ARP/DNS协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、认识以…