一、Ansible 概述

1.1 核心特性

Ansible 是一款开源的自动化运维工具,采用无代理(Agentless)架构,通过 SSH 协议实现对远程节点的管理。其核心特性包括:

  • 无代理架构:被管理节点无需安装代理软件,降低部署复杂度
  • 声明式语法:通过 YAML 格式的 Playbook 定义目标状态
  • 模块化设计:丰富的内置模块覆盖各类运维场景,支持自定义模块
  • 幂等性操作:确保多次执行相同任务结果一致,避免重复操作风险
  • 简单易用:学习曲线平缓,配置文件可读性强
  • 强大的编排能力:支持复杂任务流程和依赖关系定义

1.2 应用场景

Ansible 适用于多种运维自动化场景:

  • 服务器初始化配置(操作系统优化、安全加固)
  • 应用程序部署与升级
  • 配置文件统一管理与分发
  • 批量命令执行与任务调度
  • 云资源管理(AWS、Azure、GCP 等)
  • 容器编排(Docker、Kubernetes)
  • 基础设施即代码(IaC)实践

二、Ansible 安装与环境准备

2.1 控制节点安装

2.1.1 基于包管理器安装(CentOS 7)
# 安装 EPEL 源
yum install -y epel-release# 安装 Ansible
yum install -y ansible# 验证安装
ansible --version
2.1.2 基于包管理器安装(Ubuntu 20.04)
# 更新软件包列表
apt update# 安装 Ansible
apt install -y ansible# 验证安装
ansible --version
2.1.3 基于 Python Pip 安装
# 安装 Python 和 pip
yum install -y python3 python3-pip  # CentOS
# 或
apt install -y python3 python3-pip   # Ubuntu# 安装 Ansible
pip3 install ansible# 验证安装
ansible --version

2.2 被管理节点准备

Ansible 对被管理节点的要求极低,只需满足:

  • 开通 SSH 服务(默认端口 22)
  • 安装 Python 2.7 或 Python 3.5+
  • 控制节点能通过 SSH 访问被管理节点

对于未安装 Python 的节点,可通过以下方式快速安装:

# 在被管理节点手动安装(CentOS)
yum install -y python3# 在被管理节点手动安装(Ubuntu)
apt install -y python3

2.3 SSH 免密配置

为提高安全性和操作便捷性,建议配置控制节点到被管理节点的 SSH 免密登录:

# 在控制节点生成 SSH 密钥对
ssh-keygen -t ed25519 -N "" -f ~/.ssh/ansible_id_ed25519# 手动分发公钥到被管理节点
ssh-copy-id -i ~/.ssh/ansible_id_ed25519.pub admin@192.168.1.101# 批量分发公钥(使用密码)
ansible all -i inventory.ini -m authorized_key -a "user=admin key='{{ lookup('file', '~/.ssh/ansible_id_ed25519.pub') }}'" --user=admin --ask-pass

三、Ansible 核心配置

3.1 主配置文件

Ansible 主配置文件默认路径为 /etc/ansible/ansible.cfg,常用配置项:

[defaults]
# 默认 Inventory 文件路径
inventory = /etc/ansible/hosts# 默认远程用户
remote_user = admin# 是否自动提权
become = yes
become_method = sudo
become_user = root
become_ask_pass = no# 并行执行数量
forks = 5# SSH 连接超时时间(秒)
timeout = 10# 模块查找路径
module_paths = /usr/share/ansible/plugins/modules# 角色查找路径
roles_path = /etc/ansible/roles:/usr/share/ansible/roles# 日志配置
log_path = /var/log/ansible.log[ssh_connection]
# SSH 连接池设置
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
control_path_dir = ~/.ansible/cp

3.2 Inventory 配置

Inventory 用于定义被管理节点的清单,支持多种格式和分组方式。

3.2.1 INI 格式 Inventory
# /etc/ansible/hosts
# 基础主机定义
web1.example.com
web2.example.com:2222  # 非默认 SSH 端口
192.168.1.103# 分组定义
[webservers]
web1.example.com
web2.example.com
192.168.1.103[dbservers]
db1.example.com
db2.example.com
192.168.1.201:2222# 组变量
[webservers:vars]
http_port=80
max_clients=200[dbservers:vars]
db_port=3306
db_name=appdb# 嵌套组
[allservers:children]
webservers
dbservers# 环境分组
[production:children]
webservers
dbservers[staging:children]
webservers_staging
dbservers_staging
3.2.2 YAML 格式 Inventory
# inventory.yaml
all:vars:ansible_user: adminansible_port: 22children:webservers:hosts:web1.example.com:http_port: 80web2.example.com:http_port: 8080192.168.1.103:http_port: 80vars:server_type: webmax_connections: 1000dbservers:hosts:db1.example.com:db_type: mysqldb2.example.com:db_type: postgresql192.168.1.201:ansible_port: 2222db_type: mysqlvars:server_type: databaseproduction:children:webservers:dbservers:

3.3 验证节点连通性

# 测试所有节点连通性
ansible all -m ping# 测试特定组节点连通性
ansible webservers -m ping# 测试单个节点连通性
ansible web1.example.com -m ping# 使用指定 Inventory 文件
ansible all -i inventory.yaml -m ping# 查看节点信息
ansible all -m setup

四、Ansible 命令行工具使用

4.1 常用 ansible 命令

# 执行临时命令(查看磁盘使用情况)
ansible webservers -a "df -h"# 指定用户执行命令
ansible dbservers -a "free -m" -u admin# 提权执行命令(需要 sudo 权限)
ansible all -a "systemctl status nginx" --become# 使用指定模块执行操作
ansible webservers -m yum -a "name=nginx state=present" --become
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become# 复制文件到远程节点
ansible webservers -m copy -a "src=/local/path/file dest=/remote/path/file mode=0644"# 创建目录
ansible all -m file -a "path=/data/logs state=directory mode=0755 owner=root group=root" --become# 查看模块帮助
ansible-doc yum
ansible-doc -s copy  # 查看模块示例

4.2 ansible-playbook 命令

# 执行 Playbook
ansible-playbook playbook.yml# 执行指定 Inventory 的 Playbook
ansible-playbook -i inventory.yaml playbook.yml# 执行指定标签的任务
ansible-playbook playbook.yml --tags "install,config"# 跳过指定标签的任务
ansible-playbook playbook.yml --skip-tags "restart"# 列出 Playbook 中的任务
ansible-playbook playbook.yml --list-tasks# 检查 Playbook 语法
ansible-playbook playbook.yml --syntax-check# 执行 dry-run(模拟执行)
ansible-playbook playbook.yml --check# 详细输出执行过程
ansible-playbook playbook.yml -v
ansible-playbook playbook.yml -vvv  # 更详细输出

五、Playbook 编写与应用

5.1 Playbook 基本结构

Playbook 是 Ansible 自动化任务的核心,采用 YAML 格式编写,基本结构:

- name: 第一个 Playbook 示例hosts: webserversvars:http_port: 80max_clients: 200remote_user: adminbecome: yesbecome_method: sudotasks:- name: 任务 1 描述module_name:parameter1: value1parameter2: value2tags:- tag1- tag2- name: 任务 2 描述module_name:parameter1: value1when: ansible_os_family == "RedHat"notify:- 处理程序名称handlers:- name: 处理程序名称module_name:parameter1: value1

5.2 常用模块示例

5.2.1 包管理模块
# 安装软件包(yum)
- name: 安装 Nginxyum:name: nginxstate: present  # 确保安装update_cache: yes  # 等同于 yum clean all# 安装特定版本
- name: 安装特定版本的 Dockeryum:name: docker-19.03.15state: present# 卸载软件包
- name: 卸载 Apacheyum:name: httpdstate: absent  # 确保卸载# Ubuntu/Debian 系统使用 apt 模块
- name: 安装 Nginxapt:name: nginxstate: presentupdate_cache: yes
5.2.2 服务管理模块
# 启动服务并设置开机自启
- name: 启动 Nginx 服务service:name: nginxstate: startedenabled: yes  # 开机自启# 重启服务
- name: 重启 MySQL 服务service:name: mysqldstate: restarted# 停止服务
- name: 停止防火墙服务service:name: firewalldstate: stoppedenabled: no  # 禁止开机自启# 重载服务配置
- name: 重载 Nginx 配置service:name: nginxstate: reloaded
5.2.3 文件操作模块
# 复制文件
- name: 复制 Nginx 配置文件copy:src: ./files/nginx.confdest: /etc/nginx/nginx.confmode: '0644'  # 文件权限owner: root   # 所有者group: root   # 所属组backup: yes   # 覆盖前备份原文件# 模板文件(使用 Jinja2 模板)
- name: 生成虚拟主机配置template:src: ./templates/vhost.conf.j2dest: /etc/nginx/conf.d/{{ server_name }}.confmode: '0644'validate: 'nginx -t -c %s'  # 配置验证# 创建目录
- name: 创建应用日志目录file:path: /var/log/myappstate: directorymode: '0755'owner: appusergroup: appgrouprecurse: yes  # 递归创建父目录# 删除文件/目录
- name: 删除临时文件file:path: /tmp/tempfilesstate: absent
5.2.4 命令执行模块
# 执行命令(无环境变量)
- name: 查看系统版本command: cat /etc/redhat-releaseregister: os_version  # 保存输出结果- name: 显示系统版本debug:var: os_version.stdout# 执行 Shell 命令(带环境变量)
- name: 统计 Nginx 进程数shell: ps -ef | grep nginx | grep -v grep | wc -lregister: nginx_process_count# 执行脚本
- name: 执行初始化脚本script: ./scripts/init.shargs:creates: /var/log/init_done  # 如果文件存在则不执行

5.3 条件判断与循环

5.3.1 条件判断
# 根据操作系统类型安装不同软件
- name: 安装 Web 服务器(RedHat)yum:name: httpdstate: presentwhen: ansible_os_family == "RedHat"- name: 安装 Web 服务器(Debian)apt:name: apache2state: presentwhen: ansible_os_family == "Debian"# 多条件判断
- name: 仅在生产环境且内存大于 4GB 时执行command: /opt/app/heavy_task.shwhen:- environment == "production"- ansible_memtotal_mb > 4096# 基于前序任务结果判断
- name: 检查文件是否存在stat:path: /etc/important.confregister: important_file- name: 如果文件不存在则创建file:path: /etc/important.confstate: touchwhen: not important_file.stat.exists
5.3.2 循环
# 简单列表循环
- name: 创建多个目录file:path: "{{ item }}"state: directorymode: '0755'loop:- /var/log/app/debug- /var/log/app/error- /var/log/app/access# 字典列表循环
- name: 创建多个用户user:name: "{{ item.name }}"uid: "{{ item.uid }}"group: "{{ item.group }}"state: presentloop:- { name: 'appuser', uid: 1001, group: 'appgroup' }- { name: 'webuser', uid: 1002, group: 'webgroup' }- { name: 'dbuser', uid: 1003, group: 'dbgroup' }# 循环带标签
- name: 安装多个软件包yum:name: "{{ item }}"state: presentloop:- nginx- php- mysqlloop_control:label: "Installing {{ item }}"  # 简化输出

5.4 处理程序(Handlers)

Handlers 用于响应任务通知,通常用于重启服务、重新加载配置等操作:

- name: 配置 Nginxhosts: webserversbecome: yestasks:- name: 安装 Nginxyum:name: nginxstate: present- name: 复制 Nginx 主配置copy:src: ./files/nginx.confdest: /etc/nginx/nginx.confmode: '0644'notify:  # 配置变化时通知- 重启 Nginx- name: 复制虚拟主机配置template:src: ./templates/vhost.conf.j2dest: /etc/nginx/conf.d/example.com.confmode: '0644'notify:- 重载 Nginx 配置  # 配置变化时通知- name: 确保 Nginx 服务启动service:name: nginxstate: startedenabled: yeshandlers:  # 定义处理程序- name: 重启 Nginxservice:name: nginxstate: restarted- name: 重载 Nginx 配置service:name: nginxstate: reloaded

六、Ansible 角色(Roles)

6.1 角色目录结构

Roles 是 Ansible 用于组织 Playbook 的标准化目录结构,便于代码复用和共享。标准的角色目录结构如下:

roles/
├── role_name/               # 角色名称
│   ├── defaults/            # 默认变量(优先级最低)
│   │   └── main.yml
│   ├── files/               # 静态文件(copy模块使用)
│   ├── handlers/            # 处理程序
│   │   └── main.yml
│   ├── meta/                # 角色元数据(依赖关系等)
│   │   └── main.yml
│   ├── tasks/               # 任务列表
│   │   └── main.yml
│   ├── templates/           # 模板文件(template模块使用)
│   ├── vars/                # 角色变量(优先级较高)
│   │   └── main.yml
│   └── README.md            # 角色说明文档

各目录功能说明:

  • defaults/main.yml:定义角色的默认变量,可被外部变量覆盖
  • files/:存放需要复制到目标主机的静态文件
  • handlers/main.yml:角色相关的处理程序
  • meta/main.yml:定义角色依赖、作者、许可证等元数据
  • tasks/main.yml:角色的主要任务列表
  • templates/:存放 Jinja2 模板文件
  • vars/main.yml:角色的私有变量,优先级高于 defaults

6.2 创建和使用角色

6.2.1 初始化角色
# 使用ansible-galaxy命令创建角色骨架
ansible-galaxy init roles/nginx
ansible-galaxy init roles/mysql
ansible-galaxy init roles/php
6.2.2 编写角色内容

以nginx角色为例:

  1. 定义任务(tasks/main.yml)
- name: 安装Nginxyum:name: nginxstate: presentwhen: ansible_os_family == "RedHat"- name: 安装Nginx(Debian)apt:name: nginxstate: presentwhen: ansible_os_family == "Debian"- name: 复制Nginx主配置文件template:src: nginx.conf.j2dest: /etc/nginx/nginx.confmode: '0644'notify: 重启Nginx- name: 创建虚拟主机配置目录file:path: /etc/nginx/conf.dstate: directorymode: '0755'- name: 部署默认虚拟主机配置template:src: default.conf.j2dest: /etc/nginx/conf.d/default.confmode: '0644'notify: 重载Nginx配置- name: 确保Nginx服务启动并开机自启service:name: nginxstate: startedenabled: yes

    2. 定义处理程序(handlers/main.yml)

- name: 重启Nginxservice:name: nginxstate: restarted- name: 重载Nginx配置service:name: nginxstate: reloaded

    3. 定义变量(defaults/main.yml)

# 默认端口
nginx_listen_port: 80# 服务器名称
nginx_server_name: localhost# 文档根目录
nginx_root: /var/www/html

    4. 创建模板文件(templates/nginx.conf.j2)

user nginx;
worker_processes {{ ansible_processor_vcpus }};  # 使用facts获取CPU核心数error_log /var/log/nginx/error.log;
pid /run/nginx.pid;events {worker_connections 1024;
}http {log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile            on;tcp_nopush          on;tcp_nodelay         on;keepalive_timeout   65;types_hash_max_size 2048;include             /etc/nginx/mime.types;default_type        application/octet-stream;include /etc/nginx/conf.d/*.conf;
}
6.2.3 在 Playbook 中使用角色
# site.yml
- name: 部署Web服务器hosts: webserversbecome: yesroles:- role: nginxvars:nginx_listen_port: 8080nginx_server_name: web.example.com- role: php- role: mysqlvars:mysql_root_password: secure_passwordmysql_databases:- name: webappmysql_users:- name: webuserpassword: user_passwordpriv: 'webapp.*:ALL'

也可以使用import_role或include_role动态导入角色:

- name: 部署应用服务器hosts: appserversbecome: yestasks:- name: 安装基础组件import_role:name: base- name: 根据环境部署Web服务include_role:name: "{{ web_server_role }}"vars:web_server_role: nginx

6.3 角色依赖管理

在meta/main.yml中定义角色依赖:

galaxy_info:author: Your Namedescription: Nginx web server rolelicense: MITmin_ansible_version: 2.9platforms:- name: ELversions:- 7- 8- name: Ubuntuversions:- focal- bionicgalaxy_tags:- web- nginx- serverdependencies:- role: firewalldvars:firewall_ports:- 80/tcp- 443/tcp- role: ssl_certvars:cert_domain: "{{ nginx_server_name }}"

七、Ansible 实战案例

7.1 服务器初始化配置

# init_server.yml
- name: 服务器初始化配置hosts: allbecome: yesvars:timezone: Asia/Shanghaissh_port: 22allowed_ssh_users:- admin# 禁用密码登录,只允许SSH密钥ssh_password_auth: notasks:- name: 设置时区timezone:name: "{{ timezone }}"- name: 安装基础工具包yum:name:- vim- wget- curl- net-tools- lsof- tcpdump- chronystate: presentwhen: ansible_os_family == "RedHat"- name: 安装基础工具包(Debian)apt:name:- vim- wget- curl- net-tools- lsof- tcpdump- chronystate: presentwhen: ansible_os_family == "Debian"- name: 启动时间同步服务service:name: chronydstate: startedenabled: yes- name: 配置SSH服务lineinfile:path: /etc/ssh/sshd_configregexp: "{{ item.regexp }}"line: "{{ item.line }}"state: presentloop:- { regexp: '^Port', line: 'Port {{ ssh_port }}' }- { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication {{ ssh_password_auth | lower }}' }- { regexp: '^PermitRootLogin', line: 'PermitRootLogin no' }notify: 重启SSH服务- name: 配置sudo权限lineinfile:path: /etc/sudoers.d/allowed_usersline: '{{ item }} ALL=(ALL) NOPASSWD: ALL'state: presentmode: '0440'validate: 'visudo -cf %s'loop: "{{ allowed_ssh_users }}"handlers:- name: 重启SSH服务service:name: sshdstate: restarted

7.2 部署 Docker 和容器化应用

# deploy_docker_app.yml
- name: 部署Docker和应用容器hosts: appserversbecome: yesvars:docker_packages:- docker-ce- docker-ce-cli- containerd.io- docker-compose-pluginapp_name: myappapp_port: 8080app_image: myapp:latesttasks:- name: 添加Docker YUM源yum_repository:name: docker-ce-stabledescription: Docker CE Stable - $basearchbaseurl: https://download.docker.com/linux/centos/$releasever/$basearch/stablegpgcheck: yesgpgkey: https://download.docker.com/linux/centos/gpgwhen: ansible_os_family == "RedHat"- name: 安装Dockeryum:name: "{{ docker_packages }}"state: presentwhen: ansible_os_family == "RedHat"- name: 启动Docker服务service:name: dockerstate: startedenabled: yes- name: 将用户添加到docker组user:name: "{{ ansible_user }}"groups: dockerappend: yes- name: 创建应用目录file:path: /opt/{{ app_name }}state: directorymode: '0755'- name: 复制docker-compose配置template:src: docker-compose.yml.j2dest: /opt/{{ app_name }}/docker-compose.ymlmode: '0644'- name: 启动应用容器community.docker.docker_compose:project_src: /opt/{{ app_name }}state: present

对应的docker-compose.yml.j2模板:

version: '3'
services:app:image: {{ app_image }}ports:- "{{ app_port }}:8080"environment:- DB_HOST={{ db_host }}- DB_NAME={{ db_name }}- DB_USER={{ db_user }}- DB_PASS={{ db_pass }}restart: alwaysvolumes:- app_data:/var/lib/{{ app_name }}depends_on:- dbdb:image: mysql:8.0environment:- MYSQL_ROOT_PASSWORD={{ db_root_pass }}- MYSQL_DATABASE={{ db_name }}- MYSQL_USER={{ db_user }}- MYSQL_PASSWORD={{ db_pass }}restart: alwaysvolumes:- db_data:/var/lib/mysqlvolumes:app_data:db_data:

八、Ansible 高级特性

8.1 变量与事实(Facts)

8.1.1 变量优先级

Ansible 变量按以下优先级从高到低排序:

  1. 命令行变量(-e 或 --extra-vars)
  2. 角色内 vars 目录定义的变量
  3. Playbook 中 vars 部分定义的变量
  4. 主机变量(Inventory 中定义)
  5. 组变量(Inventory 中定义)
  6. 角色内 defaults 目录定义的变量
8.1.2 事实缓存

Facts 是 Ansible 收集的被管理节点信息,可缓存以提高性能:

# ansible.cfg
[defaults]
gathering = smart  # 只在需要时收集
fact_caching = jsonfile
fact_caching_connection = /var/cache/ansible/facts
fact_caching_timeout = 86400  # 缓存24小时

8.2 加密敏感数据

使用ansible-vault加密敏感信息:

# 创建加密文件
ansible-vault create secrets.yml# 编辑加密文件
ansible-vault edit secrets.yml# 查看加密文件
ansible-vault view secrets.yml# 加密现有文件
ansible-vault encrypt existing_file.yml# 解密文件
ansible-vault decrypt encrypted_file.yml# 更改密码
ansible-vault rekey secrets.yml

运行 Playbook 时需要提供密码:

ansible-playbook --ask-vault-pass playbook.yml
# 或使用密码文件
ansible-playbook --vault-password-file vault_pass.txt playbook.yml

8.3 动态 Inventory

动态 Inventory 用于从外部源(如云服务、CMDB)获取主机列表:

# 使用AWS动态Inventory
pip3 install boto3
wget https://raw.githubusercontent.com/ansible/ansible/stable-2.14/contrib/inventory/ec2.py
wget https://raw.githubusercontent.com/ansible/ansible/stable-2.14/contrib/inventory/ec2.ini
chmod +x ec2.py# 测试动态Inventory
./ec2.py --list# 使用动态Inventory运行Playbook
ansible-playbook -i ec2.py playbook.yml

8.4 回调插件

回调插件用于自定义 Ansible 的输出格式:

# ansible.cfg
[defaults]
stdout_callback = yaml  # 更易读的YAML格式输出
# 或使用社区插件
# stdout_callback = community.general.yaml

常用回调插件:

  • yaml:YAML 格式输出
  • json:JSON 格式输出
  • debug:详细调试输出
  • profile_tasks:任务执行时间统计

九、Ansible 最佳实践

9.1 项目结构组织

推荐的 Ansible 项目结构:

project/
├── ansible.cfg           # 项目级配置
├── inventory/            #  inventory文件
│   ├── production/
│   │   ├── hosts
│   │   ├── group_vars/
│   │   └── host_vars/
│   └── staging/
│       ├── hosts
│       ├── group_vars/
│       └── host_vars/
├── playbooks/            # Playbook文件
│   ├── webserver.yml
│   ├── dbserver.yml
│   └── site.yml          # 主Playbook
├── roles/                # 自定义角色
│   ├── nginx/
│   ├── mysql/
│   └── common/
├── roles/                # 第三方角色(通过ansible-galaxy安装)
├── files/                # 通用文件
├── templates/            # 通用模板
├── vars/                 # 变量文件
│   ├── main.yml
│   └── secrets.yml       # 加密的敏感变量
└── docs/                 # 文档

9.2 安全性最佳实践

  1. 敏感数据管理
    • 使用 ansible-vault 加密密码、密钥等敏感信息
    • 避免在 Playbook 中硬编码敏感数据
    • 限制加密文件的访问权限

     2. 权限控制

    • 最小权限原则:远程用户只授予必要权限
    • 避免使用 root 用户直接操作
    • 使用 sudo 提权而非直接登录 root

     3. SSH 安全

    • 禁用 SSH 密码认证,只使用密钥
    • 更改默认 SSH 端口
    • 限制允许登录的用户和 IP

9.3 性能优化

  1. 减少事实收集开销
# 完全禁用事实收集
- hosts: allgather_facts: no

     2. 增加并行处理数量

# ansible.cfg
[defaults]
forks = 20  # 根据控制节点性能调整

    3. 使用连接池

# ansible.cfg
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=300s

    4. 任务优化

    • 合理使用when条件减少不必要的任务
    • 使用tags只执行必要任务
    • 避免在循环中使用with_items处理大量数据

十、总结与展望

Ansible 凭借其无代理架构、简单易用的特点,成为自动化运维领域的佼佼者。它不仅能简化日常运维工作,还能通过基础设施即代码(IaC)的方式提高系统的可重复性和可维护性。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Effective C++ 条款18:让接口容易被正确使用,不易被误用

Effective C 条款18:让接口容易被正确使用,不易被误用核心思想:设计接口时,应使正确使用方式直观自然,同时通过类型系统、行为约束等手段主动预防常见错误,减少用户犯错的可能性。 ⚠️ 1. 接口误用的常见陷…

nodejs读写文件

1.读文件 node有很多模块,可在node模块查看相应模块; var fsrequire(fs)fs.readFile(./src/a.doc,utf8,function(err,data){// 如果发生错误,data是undefined 如果成功 err为null console.log(err); console.log(data); }) 2.写文件 var…

ConcurrentHashMapRedis实现二级缓存

1. 为什么使用ConcurrentHashMap?在Java中,ConcurrentHashMap 是一个线程安全且高效的哈希表实现,广泛用于高并发场景。将其用作一级缓存的原因主要包括以下几点:1.1. 线程安全性ConcurrentHashMap 是线程安全的,支持多…

Mysql集群技术

实验在RHEL7中做,因为9中缺少了一个关键的高可用组件环境:两台数据库,内存和CPU要多一点主流是MYSQL(开源),Oracle收费较贵RHEL7中直接用make编译是有问题的,所以需要要gcc工具做好前置准备&…

自动驾驶嵌入式软件工程师面试题【持续更新】

文章目录前言请描述 CAN 帧的基本结构(包括标识符、数据字段、CRC 等)描述 WebSocket 协议的基本工作流程(包括握手、数据帧结构)请说明如何实现 WebSocket 连接的心跳机制以检测连接状态,并描述在断开后如何通过重连策…

vue(5)-组件

一.组件三大组成部分(结构/样式/逻辑)(1)组件样式冲突用scoped全局样式在组件中起全局作用,局部样式可以加scoped属性来只作用于当前组件图中只给baseone加这个样式,就在baseone中style加scoped&#xff08…

【机器学习】两大线性分类算法:逻辑回归与线性判别分析:找到分界线的艺术

文章目录一、核心概念:数据分类的"切分线"二、工作原理:从"找分界线"理解二、常见算法1、逻辑回归:二分类2、线性判别分析(LDA):分类与降维3、两种算法对比分析三、实际应用&#xff1…

静态分析c/cpp源码函数调用关系图生成

calltree calltree 不好使用 Dpxygen https://www.doxygen.nl/download.html Graphviz https://graphviz.org/download/ 静态代码调用结构图分析、构建、生成 doxygen doxygen在win和linux上均可运行,可以自动分析源码,对c语言项目友好,预处…

使用 MySQL Shell 进行 MySQL 单机到 InnoDB Cluster 的数据迁移实践

迁移背景与环境原来都是用mysqldump,DTS或者cdc迁移,这次8.0用了下新工具感觉挺好用的,简单快捷,30G数据不到源环境:单机 MySQL 8.0,地址为 172.23.3.28目标环境:InnoDB Cluster 集群&#xff0…

淘宝商品API可以获取哪些商品详情数据?

商品详情页商品全部sku信息"skus": {"sku": [{"price": 45.6,"total_price": 0,"orginal_price": 45.6,"properties": "1627207:39617249736","properties_name": "1627207:39617249736…

新一代PLC控制软件平台EsDA-AWStudio

在工业自动化和智能制造领域,高效的软件平台是提升开发效率和系统性能的关键。ZLG致远电子推出的EsDA-AWStudio平台,凭借其强大的功能和灵活的设计,为工业控制和物联网应用提供了全新的解决方案。一站式PLC工业控制软件平台EsDA-AWStudioZLG致…

基于深度学习的医学图像分析:使用MobileNet实现医学图像分类

前言 医学图像分析是计算机视觉领域中的一个重要应用,特别是在医学图像分类任务中,深度学习技术已经取得了显著的进展。医学图像分类是指将医学图像分配到预定义的类别中,这对于疾病的早期诊断和治疗具有重要意义。近年来,MobileN…

docker 容器常用命令

在平常的开发工作中,我们经常需要使用 docker 容器,那么常用的 docker 容器命令有哪些呢?今天简单总结下。 一:查看容器查看运行的容器:docker ps查看所有的容器:docker ps a查看容器详细信息&#…

重型机械作业误伤预警响应时间缩短80%!陌讯多模态识别算法在工程现场的应用优化

一、行业痛点:机械作业场景的识别困境据《工程机械安全白皮书(2025)》统计,施工现场因机械盲区导致的工伤事故中​​78.3%由识别延迟引发​​。核心难点包括:​​动态遮挡问题​​:吊臂摆动导致目标部件部分…

2025年ESWA SCI1区TOP,强化学习多目标灰狼算法MOGWO-RL+分布式混合流水车间调度,深度解析+性能实测

目录1.摘要2.问题描述和数学建模3.强化学习多目标灰狼算法MOGWO-RL4.结果展示5.参考文献6.算法辅导应用定制读者交流1.摘要 本文针对大规模个性化制造(MPM)中的调度问题,提出了一种新的解决方案。MPM能够在确保大规模生产的前提下&#xff0…

Mac 系统下安装 nvm

Mac 系统下安装 nvm nvm 全称为 node version manger,顾名思义就是管理 node 版本的一个工具,通过这个工具,我们可以在一台计算机上安装多个版本的 node,并且随时进行无缝的切换。 1. 卸载原本的 node.js(重要&#xf…

变量筛选—随机森林特征重要性

对于接触算法模型不久的小伙伴来说,建模中海量变量筛选总是让人头疼,不知道如何把握。之前已经介绍了一些变量筛选的方法:变量筛选一张图、【变量筛选】计算类别型变量IV值、KS值、一文囊括风控建模中的变量筛选方法、变量筛选—特征包含信息量。本文详细介绍通过随机森林算…

【设计模式】 3.设计模式基本原则

单一职责原则 对于一个类而言,有且仅有一个引起他变化的原因或者说,一个类只负责一个职责 如果一个类承担的职责过多,那么这些职责放在一起耦合度太高了,一个职责的变化可能会影响这个类其他职责的能力。 所以我们在做软件设计的时…

ABP VNext + Redis Bloom Filter:大规模缓存穿透防护与请求去重

ABP VNext Redis Bloom Filter:大规模缓存穿透防护与请求去重 🚀 📚 目录ABP VNext Redis Bloom Filter:大规模缓存穿透防护与请求去重 🚀TL;DR ✨1. 引言 🎉2. 环境与依赖 🛠️3. Bloom Filt…

构建工具和脚手架:从源码到dist

构建工具和脚手架:从源码到dist**1. 为什么需要工程转换?****2. 构建工具的核心职责**为什么要求转换**1)明确三种关键问题****(2)Webpack 的打包机制****3. 开发服务器(Webpack Dev Server)***…