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

news2024/11/20 8:41:06

👨‍🎓博主简介

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


文章目录

  • 一、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

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

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

相关文章

【Pytorch】Transfer Learning 迁移学习

文章目录 1. 获取数据2. 创建Dataset和DataLoader3. 获取预训练模型4. 训练模型5. 通过绘制损失曲线来评估模型6. 对测试集中的图像进行预测补充 迁移学习允许我们采用另一个模型从另一个问题中学到的模式&#xff08;也称为权重&#xff09;并将它们用于我们自己的问题。 例如…

51单片机 wifi连接

一、基本概念 ESP8266是一款集成了WiFi功能的高性能芯片&#xff0c;广泛应用于物联网设备、智能家居、传感器网络等领域。以下是ESP8266的详细讲解&#xff1a; 1. 功能特点&#xff1a;ESP8266集成了TCP/IP协议栈&#xff0c;支持STA&#xff08;Station&#xff09;和AP&am…

Kamacoder第八题摆平积木的C语言解法

8. 摆平积木 时间限制&#xff1a;1.000S 空间限制&#xff1a;32MB 题目描述 小明很喜欢玩积木。一天&#xff0c;他把许多积木块组成了好多高度不同的堆&#xff0c;每一堆都是一个摞一个的形式。然而此时&#xff0c;他又想把这些积木堆变成高度相同的。但是他很懒&…

[足式机器人]Part2 Dr. CAN学习笔记-Ch00-2 - 数学知识基础

本文仅供学习使用 本文参考: B站:DR_CAN 《控制之美(卷1)》 王天威 《控制之美(卷2)》 王天威 Dr. CAN学习笔记-Ch00 - 数学知识基础 Part2 4. Ch0-4 线性时不变系统中的冲激响应与卷积4.1 LIT System:Linear Time Invariant4.2 卷积 Convolution4.3 单位冲激 Unit Impulse—…

上传大文件报错No data found for resource with given identifier

预览中的数据No data found for resource with given identifier 首先以为是nginx问题查看nginx日志 39.89.216.201 - - [27/Feb/2024:10:14:53 0800] "POST /api/crm/clue/upload HTTP/1.1" 499 0 "https://op-dev.*.com/customer/clue-management" &qu…

163邮箱SMTP端口号及服务器地址详细设置?

163邮箱SMTP端口号是什么&#xff1f;163邮件SMTP设置教程&#xff1f; 除了基本的邮箱账号和密码外&#xff0c;还需要了解SMTP服务器地址和端口号&#xff0c;以及相应的设置。这些设置对于确保邮件能够顺利发送至关重要。下面&#xff0c;蜂邮EDM将详细介绍163邮箱SMTP端口…

idea生成WebServices接口

文章目录 idea生成WebServices接口1.创建接口2.生成wsdl文件3.在soapUI中&#xff0c;生成6个文件4.将生成的文件拷贝到工程中5.在service-config中注册服务 idea生成WebServices接口 1.创建接口 新建一个webServices工程&#xff0c;按照接口规范生成接口、请求类、响应类。…

phpldapadmin This base cannot be created with PLA

phpldapadmin This base cannot be created with PLA 1、问题描述2、问题分析3、解决方法&#xff1a;创建根节点 1、问题描述 安装phpldapadmin参考链接: https://blog.csdn.net/OceanWaves1993/article/details/136048686?spm1001.2014.3001.5501 刚安装完成phpldapadmin&…

2024全新版EasyRecovery14数据恢复软件功能详细分析

一、功能概述 EasyRecovery14是一款功能全面的数据恢复软件&#xff0c;它提供了从各种存储设备&#xff08;如硬盘、U盘、SD卡、数码相机等&#xff09;中恢复丢失或删除数据的能力。该软件支持多种恢复模式&#xff0c;包括快速恢复、深度扫描、格式化恢复等&#xff0c;以满…

C语言 int和unsigned int逻辑比较

文章目录 测试1、测试 CMP (int,int)2、测试 CMP (int ,unsigned int)3、测试 CMP (unsigned int ,unsigned int)4、测试 CMP(int ,常量&#xff09; 总结 测试 在IAR(8.40.2)平台下测试单片机为STM32F103ZET6 1、测试 CMP (int,int) //a -2,b 3 int test_fun(int a, int…

vue组件中data为什么必须是一个函数

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

R语言——条形图数据可视化的多种方式

本文章将会介绍如何使用R语言中的ggplot2包使用条形图进行数据可视化。将会使用一个“生产企业原材料的订购与运输”的订单数据&#xff0c;该数据来自2021数学建模国赛C题。 某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料总体可分为 A B C 三种类…

LeetCode 刷题 [C++] 第240题.搜索二维矩阵 II

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 题目分析 通过分析矩阵的特点发现&#xff0c;其左下角和右上角可以看作一个“二叉搜索树的根节…

ROS-Ubuntu 版本相关

ROS-Ubuntu 版本相关&#xff1a;安装指引 年代ROS1版本Ubuntu 版本2014Indigo14.042016Kinetic16.042018Melodic18.042020Noetic20.04 & 22.04 ROS2兼顾了工业使用上的问题。 年代ROS2版本Ubuntu 版本2022Humble20.04 & 22.042023Iron16.04 相关参考&#xff1a; […

MySQL进阶:大厂高频面试——各类SQL语句性能调优经验

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;MySQL进阶&#xff1a;强推&#xff0c;冲大厂必精通&#xff01;MySQL索引底层&#xff08;BTree&#xff09;、性能分析、使用…

【Java程序设计】【C00336】基于Springboot的防疫物资管理系统(有论文)

基于Springboot的防疫物资管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的防疫物资管理系统&#xff0c;本系统有管理员以及用户二种角色&#xff1b; 管理员&#xff1a;个人中心、管理员管理、用户管理…

AI领域的从业女性, 合成数据和减少AI的偏见等议题

关于企业AI领域创新举措的新闻层出不穷&#xff0c;澳鹏也不例外。AI领域的女性、数据管理和偏见减少的专家建议以及合成数据突破等内容成为今年第三季度各大媒体出版物的头版头条&#xff01;请继续阅读&#xff0c;了解新闻媒体对澳鹏上一季度表现的评价。 ‘虚假’数据如何对…

laravel8配合jwt

composer 安装包 composer require tymon/jwt-authconfig/app.php 注册服务提供者 providers > [Tymon\JWTAuth\Providers\LaravelServiceProvider::class, ]aliases > [JWTAuth > Tymon\JWTAuth\Facades\JWTAuth::class,JWTFactory > Tymon\JWTAuth\Facades\JWT…

Web服务器群集:OpenEuler 部署 LAMP(LNMP) 基础服务

目录 一、实验 1.环境 2. 网络配置 3. MobaXterm远程连接 4. apache 2.4.58 源码编译安装 5. php 8.3.1源码编译安装 6.配置httpd 连接 php-fpm 6. nginx 1.24.0源码编译安装 7. mysql 8.0.36安装 二、问题 1.MobaXterm设置右键复制粘贴 2.OpenEuler如何查看CPU的核…

String LCM

题目链接&#xff1a;Problem - 1473B - Codeforces 解题思路&#xff1a; 先算出两个字符串的最小公倍数&#xff0c;再分别除以字符串长度&#xff0c;构造出两个新的字符串&#xff0c;就是最小公倍数除以老字符串长度个老字符串相加&#xff0c;打个比方&#xff0c;a字符…