Operations-ansible-01

ansible

features

模块化,调用特定的模块来完成特定任务
基于python语言实现,由paramiko、pyYAML和jinja2三个关键模块实现
部署简单,agentless
主从模式
支持自定义模块
支持playbook
幂等性:运行多次,结果相同

组成部分

ansible core
host inventory:主机库,定义了ansible能够管控的主机列表
connection plugins:用于管理主机的插件,一般是SSH的API向主机建立会话并发送指令
modules:各种core modulescustom modules
playbooks:定制好的模块和命令

配置文件

主配置文件

/etc/ansible/ansible.cfg

Host Inventory

/etc/ansible/hosts

ansible命令

ansible <host-pattern> [-f forks] [-m module_name] [-a args]host-patternA name of a group in the inventory file, a shell-like glob selecting hosts in inventory file, or any combination of the two separated by semicolons./etc/ansible/hostsINI风格,中括号中的字符是组名;一个主机可同时属于多个组-i PATH, --inventory=PATHThe PATH to the inventory hosts file, which defaults to /etc/ansible/hosts.-a 'ARGUMENTS', --args='ARGUMENTS'The ARGUMENTS to pass to the module.

[root@husa ansible]# ansible-doc --help
Usage: ansible-doc [options] [module...]Show Ansible module documentationOptions:--version             show program's version number and exit-h, --help            show this help message and exit-M MODULE_PATH, --module-path=MODULE_PATHAnsible modules/ directory-l, --list            List available modules-s, --snippet         Show playbook snippet for specified module(s)   #查看模块的使用参数-v                    Show version number and exit

常用模块

ansible-doc -l查看支持的模块

[root@localhost .ssh]# ansible-doc -l
...
apt                           Manages apt-packages
apt_key                       Add or remove an apt key
apt_repository                Add and remove APT repositories
apt_rpm                       apt_rpm package manager
assemble                      Assembles a configuration file from frag...
assert                        Fail with custom message
at                            Schedule the execution of a command or s...
authorized_key                Adds or removes an SSH authorized key
azure                         create or terminate a virtual machine in...
bigip_facts                   Collect facts from F5 BIG-IP devices
bigip_monitor_http            Manages F5 BIG-IP LTM http monitors
bigip_monitor_tcp             Manages F5 BIG-IP LTM tcp monitors
...

模块的参数是KV数据
-a key=value

command

-a  'COMMAND'
[root@localhost .ssh]# ansible all -m command -a 'ls'
172.16.11.101 | success | rc=0 >>
anaconda-ks.cfg
httpd.csr172.16.11.102 | success | rc=0 >>
anaconda-ks.cfg

command是默认模块,可以省略不写即ansible all -a ‘ls’
默认模块,这个模块的参数不是KV格式而是直接给出命令;这个模块不能使用 管道

ping

A trivial test module, this module always returns pong on successful contact. It does not make sense in playbooks, but it is useful from /usr/bin/ansible to verify the ability to login and that a usable python is configured. This is NOT ICMP ping, this is just a trivial test module.
[root@localhost .ssh]# ansible 172.16.11.101 -m ping
172.16.11.101 | success >> {"changed": false, "ping": "pong"
}

user

name yes Name of the user to create, remove or modify.
state no [present|absent] Whether the account should exist or not, taking action if the state is different from what is stated.
system no [yes|no] When creating an account, setting this to yes makes the user a system account. This setting cannot be changed on existing users.

-a  'name=  state={present|absent}  force=   system=  uid=  shell=  home='
# 在两个主机上创建了centos用户
[root@localhost ~]# ansible all -m user -a 'name=centos system=yes state=present'
172.16.11.101 | success >> {"changed": true, "comment": "", "createhome": true, "group": 992, "home": "/home/centos", "name": "centos", "shell": "/bin/bash", "state": "present", "system": true, "uid": 995
}172.16.11.102 | success >> {"changed": true, "comment": "", "createhome": true, "group": 992, "home": "/home/centos", "name": "centos", "shell": "/bin/bash", "state": "present", "system": true, "uid": 995
}[root@husa ~]# id centos
uid=995(centos) gid=992(centos) 组=992(centos)

group

-a  'name=  state={present|absent}  gid=  system='[root@localhost ~]# ansible-doc -s group- name: A d d   o r   r e m o v e   g r o u p saction: groupgid                    # Optional `GID' to set for the group.name=                  # Name of the group to manage.state                  # Whether the group should be present or not on the remote host.system                 # If `yes', indicates that the group created is a system group.

file

Sets attributes of files, symlinks, and directories, or removes files/symlinks/directories. Many other modules support the same options as the file module - including copy, template, and assemble.

-a  'path=  mode=  owner=  group=  state={file|directory|link|hard|touch|absent}  src='
[root@localhost ~]# ansible all -m file -a 'path=/root/ansi state=directory mode=755 owner=root group=root'
172.16.11.102 | success >> {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/root/ansi", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 6, "state": "directory", "uid": 0
}172.16.11.101 | success >> {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/root/ansi", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 6, "state": "directory", "uid": 0
}# 172.16.11.101[root@husa ~]# ll
总用量 8
-rw-------. 1 root root 1998 1月  30 02:49 anaconda-ks.cfg
drwxr-xr-x. 2 root root    6 1月  31 08:11 ansi
-rw-r--r--. 1 root root  708 1月  31 03:39 httpd.csr

yum

Installs, upgrade, removes, and lists packages and groups with the yum package manager.

-a  'name=  conf_file=  state={present|latest|absent}  enablerepo=  disablerepo='
[root@localhost ~]# ansible all -m yum -a 'name=httpd state=present'
172.16.11.101 | success >> {"changed": false, "msg": "", "rc": 0, "results": ["httpd-2.4.6-31.el7.centos.x86_64 providing httpd is already installed"]
}172.16.11.102 | success >> {"changed": false, "msg": "", "rc": 0, "results": ["httpd-2.4.6-31.el7.centos.x86_64 providing httpd is already installed"]
}
# 安装httpd,但是提示已经早已安装过了

copy

The copy module copies a file on the local box to remote locations. Use the fetch module to copy files from remote locations to the local box. If you need variable interpolation in copied files, use the template module.把本地主机的文件复制到远程主机

-a  'dest=  src=  content=  owner=  group=  mode='
[root@localhost ~]# ansible all -m copy -a 'src=/etc/httpd/conf/httpd.conf dest=/tmp mode=744 owner=root group=root'
172.16.11.101 | success >> {"changed": true, "checksum": "fa2850bb3dae846b727917ae0777bc85109cf4e0", "dest": "/tmp/httpd.conf", "gid": 0, "group": "root", "md5sum": "f6351c6d8c8dfc5899820d8c46d74651", "mode": "0744", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 34419, "src": "/root/.ansible/tmp/ansible-tmp-1451141734.1-70247620035515/source", "state": "file", "uid": 0
}172.16.11.102 | success >> {"changed": true, "checksum": "fa2850bb3dae846b727917ae0777bc85109cf4e0", "dest": "/tmp/httpd.conf", "gid": 0, "group": "root", "md5sum": "f6351c6d8c8dfc5899820d8c46d74651", "mode": "0744", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 34419, "src": "/root/.ansible/tmp/ansible-tmp-1451141734.12-232176586930023/source", "state": "file", "uid": 0
}# remote location[root@husa ~]# ll /tmp
总用量 60
drwxr-xr-x. 2 root root    17 1月  30 02:40 hsperfdata_root
-rwxr--r--. 1 root root 34419 1月  31 08:29 httpd.conf

service

Controls services on remote hosts. Supported init systems include BSD init, OpenRC, SysV, Solaris SMF, systemd, upstart.

-a  'name=  state={started|stopped|restarted}  enabled=  runlevel='
enabled表示开机自启
# 启动httpd服务并设置开机启动[root@localhost ~]# ansible all -m service -a 'name=httpd state=started enabled=true'
172.16.11.102 | success >> {"changed": true, "enabled": true, "name": "httpd", "state": "started"
}172.16.11.101 | success >> {"changed": true, "enabled": true, "name": "httpd", "state": "started"
}

shell

The shell module takes the command name followed by a list of space-delimited arguments. It is almost exactly like the command module but runs the command through a shell (/bin/sh) on the remote node.可以使用管道重定向等

-a  'COMMAND'
# 向远程主机的centos用户设置密码为root[root@localhost ~]# ansible all -m shell -a 'echo "root" | passwd --stdin centos'
172.16.11.101 | success | rc=0 >>
Changing password for user centos.
passwd: all authentication tokens updated successfully.172.16.11.102 | success | rc=0 >>
Changing password for user centos.
passwd: all authentication tokens updated successfully.

script

The script module takes the script name followed by a list of space-delimited arguments. The local script at path will be transferred to the remote node and then executed. The given script will be processed through the shell environment on the remote node. This module does not require python on the remote system, much like the raw module.把本地的脚本文件传递到远程主机并执行,执行结果

-a  '/PATH/TO/SCRIPT'
# local host[root@localhost ~]# vim hello.sh#!/bin/bash
#echo "hello $HOSTNAME"[root@localhost ~]# ansible all -m script -a '/root/hello.sh'
172.16.11.101 | success >> {"changed": true, "rc": 0, "stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to 172.16.11.101 closed.\r\n", "stdout": "hello husa\r\n"
}172.16.11.102 | success >> {"changed": true, "rc": 0, "stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to 172.16.11.102 closed.\r\n", "stdout": "hello localhost.localdomain\r\n"
}

script上传到远程主机并在远程主机执行,结果在本地主机可以捕获

cron

Use this module to manage crontab entries. This module allows you to create named crontab entries, update, or delete them. The module includes one line with the description of the crontab entry “#Ansible: ” corresponding to the “name” passed to the module, which is used by future ansible/module calls to find/check the state. The “name” parameter should be unique, and changing the “name” value will result in a new cron task being created (or a different one being removed)

-a  'name=  state=  minute=  hour=  day=  month=  weekday=  job='

setup

This module is automatically called by playbooks to gather useful variables about remote hosts that can be used in playbooks. It can also be executed directly by /usr/bin/ansible to check what variables are available to a host. Ansible provides many facts about the system, automatically. 获取指定主机的facts

[root@localhost ~]# ansible 172.16.11.101 -m setup
172.16.11.101 | success >> {"ansible_facts": {"ansible_all_ipv4_addresses": ["192.168.200.101", "172.16.11.101"], "ansible_all_ipv6_addresses": ["fe80::20c:29ff:fecc:de26", "fe80::20c:29ff:fecc:de1c"], "ansible_architecture": "x86_64", "ansible_bios_date": "07/02/2015", "ansible_bios_version": "6.00", "ansible_cmdline": {"BOOT_IMAGE": "/vmlinuz-3.10.0-229.el7.x86_64", "LANG": "zh_CN.UTF-8", "crashkernel": "auto", "quiet": true, "rhgb": true, "ro": true, "root": "UUID=6db0652d-dad9-400a-bd91-0d6dfb59b2b4"}, "ansible_date_time": {"date": "2016-01-31", "day": "31", "epoch": "1454201429", "hour": "08", "iso8601": "2016-01-31T00:50:29Z", "iso8601_micro": "2016-01-31T00:50:29.107179Z", "minute": "50", "month": "01", "second": "29", "time": "08:50:29", "tz": "CST", "tz_offset": "+0800", "weekday": "Sunday", "year": "2016"}, "ansible_default_ipv4": {
......

templates

-a  'dest=  src=  content=  owner=  group=  mode='

playbooks

contain one or more plays
written in YAML
executed in the order it is written

ansible-playbook - run an ansible playbook

ansible-playbook

变量

变量命名:字母数字下划线,只能以字母开头变量种类:facts:由远程主机发回的主机属性信息,这些信息被保存在ansible变量中;无须定义,可直接调用自定义变量通过命令行传递:ansible-playbook xxx.yml --extra-vars "host=xxx user=xxx"通过roles传递:在roles的yml文件中使用 {{role:role_name,var_name:var_value}},传递模板变量的值给变量主机变量:定义在inventory中的主机之后的变量组变量:定义在inventory中的组上的变量

inventory参数

ansible基于ssh连接inventory中指定的远程主机时,以此处的参数指定的属性进行

ansible_ssh_host
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass

例子:

  oot@localhost ~]# vim /etc/ansible/hosts
[real server]
172.16.11.101   ansible_ssh_user='root' ansible_ssh_port=22     ansible_ssh_pass='root' ansible_sudo_pass='xxxx'
172.16.11.102

facts

使用setup模块可以查看远程主机的各种facts

主机变量

定义在inventory中的主机之后的变量

[root@localhost ~]# vim /etc/ansible/hosts
[real server:vars]
172.16.11.101   user=apace      group=apace
172.16.11.102

自定义变量之通过命令行传递

ansible-playbook  test.yml  --extra-vars "host=172.16.11.101"       #这里的host就是一个通过命令行传递的自定义变量

组变量

[root@localhost ~]# vim /etc/ansible/hosts
[real server:vars]
user=apache
group=apache
172.16.11.101
172.16.11.102

palybook结构

  • host {hostname|inventory_name|ip} #表示远程主机标识
    remote_user:remote_user_name #表示远程主机上执行任务的身份
    vars: #定义变量
    Key1:Value1 #这种变量的应用方法为 {{Keyx}}
    Key2:Value2
    Keyn:Valuen
    tasks: #表示一个任务组,用列表表示

    • name:task_name1 #具有标识性质的字符串比如:task useradd
      module_name:module_args #比如:user:name={{var_name}} state=present或者user:name=username state=present,args中的变量还可以是item中的
      when:condition #比如条件为facts即:ansible_os_family==”RedHat”
      notify:handlers_name #表示发生改变才触发的任务,handlers_name表示handlers条目中的名称
      with_items:
    • item_name1 #这种形式的item在args中使用 {{item}} 应用
    • item_name2
    • item_namen
    • {var_name:’content’,var_name2:’content’,var_namen:’content’} #这种形式的item在args中使用 {{item.var_name}} 应用
    • {var_name:’content’,var_name2:’content’,var_namen:’content’}
      template:template_args #这里显示使用template模块,其参数主要是 src 和 dest,一般用于配置文件的修改使用,src的配置文件应该使用jinja2模板的语法,使用{{tempalte_name}}定义,而其应用可以使用主机变量、自定义变量和vars变量
      tags:tags_name #定义tasks的TAGS,这个tags可用于ansible-playbook -t tags_name playname.yml来调用特定的tasks
    • name:task_namex… #表示可以定义多个tasks
      handlers:
    • name:handlers_name1
      module_name:module_args #表示handlers同样也使用模块来定义任务

    • name:handlers_name2… #表示可以定义多个handlers

roles

在roles目录中定义各种元素,然后再定义一个playbook,在playbook中定义好role的名称,执行这个yml文件,就能够按照目录结构寻找相应的配置

文件组织格式

一个目录表示一个roles,roles下的目录是各种配置
roles用于实现“代码复用”;
roles以特定的层次型格式组织起来的playbook元素(variables, tasks, templates, handlers);可被playbook以role的名字直接进行调用;

            roles/webserver/files/:此角色中用到的所有文件均放置于此目录中;templates/:Jinja2模板文件存放位置;tasks/:任务列表文件;可以有多个,但至少有一个叫做main.yml的文件;handlers/:处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件;vars/:变量字典文件;可以有多个,但至少有一个叫做main.yml的文件;meta/:此角色的特殊设定及依赖关系;
[root@localhost ~]# tree /etc/ansible/roles/
/etc/ansible/roles/
└── real server                 # 这个real server目录就表示一个roles├── files                   # 此角色中用到的所有文件均放置于此目录中├── handlers                # 处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件├── meta                    # 此角色的特殊设定及依赖关系├── tasks                   # 任务列表文件;可以有多个,但至少有一个叫做main.yml的文件├── templates               # Jinja2模板文件存放位置└── vars                    # 变量字典文件;可以有多个,但至少有一个叫做main.yml的文件

安装ansible

ansible在epel源,要先配置好epel源

[root@localhost ~]# yum install ansible
Installing:ansible         noarch         1.9.2-1.el6            epel         1.7 MTransaction Summary
Installed:ansible.noarch 0:1.9.2-1.el6                                            Complete!

配置host inventory文件

[root@localhost ~]# vim /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups
[real server]
172.16.11.101
172.16.11.102

上面就把172.16.11.101和172.16.11.102作为了ansible得被管理主机

另外可以使用ansible -i PATH,–inventory=PATH指明使用的host inventory文件路径

基于密钥认证

# ansible所在主机
[root@localhost .ssh]# ssh-keygen -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
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:
35:e3:89:d5:d8:94:99:96:c4:6b:a1:b7:e6:64:fa:9b root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|           oo=   |
|           =O    |
|          *ooo   |
|         =.++    |
|        S oo .   |
|            =    |
|           *     |
|          . ..   |
|           .E.   |
+-----------------+# 被管理主机[root@localhost .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.11.101
The authenticity of host '172.16.11.101 (172.16.11.101)' can't be established.
RSA key fingerprint is 7c:83:16:24:34:09:db:58:a5:31:32:1b:c9:25:07:a2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.11.101' (RSA) to the list of known hosts.
root@172.16.11.101's password:
Now try logging into the machine, with "ssh 'root@172.16.11.101'", and check in:.ssh/authorized_keysto make sure we haven't added extra keys that you weren't expecting.# 被管理主机的.ssh目录下生成了authorized_keys文件说明OK
[root@husa .ssh]# cd
[root@husa ~]# ls ~/.ssh/
authorized_keys# 同样的方法把ansible所在主机的公钥复制到RS2[root@localhost .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.11.102
The authenticity of host '172.16.11.102 (172.16.11.102)' can't be established.
RSA key fingerprint is fe:1e:4a:0d:c9:d1:67:91:57:1f:01:2c:ea:c1:b3:69.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.11.102' (RSA) to the list of known hosts.
root@172.16.11.102's password:
Now try logging into the machine, with "ssh 'root@172.16.11.102'", and check in:.ssh/authorized_keysto make sure we haven't added extra keys that you weren't expecting.

简单使用ansible

[root@localhost .ssh]# ansible-doc -s ping
less 436
Copyright (C) 1984-2009 Mark Nudelmanless comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
- name: T r y   t o   c o n n e c t   t o   h o s t   a n d   r e t u r n action: ping
(END) [root@localhost .ssh]# ansible all -m ping
172.16.11.101 | success >> {"changed": false, "ping": "pong"
}172.16.11.102 | success >> {"changed": false, "ping": "pong"
}# 下面使用的组名也可以
[root@localhost .ssh]# ansible real\ server -m ping
172.16.11.101 | success >> {"changed": false, "ping": "pong"
}172.16.11.102 | success >> {"changed": false, "ping": "pong"
}# 下面是在RS上的抓包信息
[root@husa ~]# tcpdump -i eno16777728 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno16777728, link-type EN10MB (Ethernet), capture size 65535 bytes
06:58:04.918637 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:05.941705 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:07.062513 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:09.036487 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 48

使用ansible-doc -s查看模块的用法,使用ansible hosts -m module -a发送命令

参考文献:http://chrisrc.me/2015-09-23/autoit-ansible/

http://afoo.me/posts/2014-06-12-understanding-ansible.html#fnref2

Operations-ansible-01相关推荐

  1. 自动化运维工具Ansible实战(一)简介和部署

    一.Ansible的介绍 Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点.实现了批量系统配置 ...

  2. 如何快速上手一款开源软件

    最近一篇比较火的文章中提到,techcrunch上有一篇文章,列举了当前最火的开源软件列表 https://techcrunch.com/2017/04/07/tracking-the-explosi ...

  3. 01 安装ansible

    #################103上安装ansible yum install -y ansible rpm -ql ansible | egrep -v "^/usr/(lib|sh ...

  4. Ansible纸上谈兵01:认识一下Ansible

    Why:为什么要使用Ansible 当给你6台云主机,你应该怎么去使用,或者计划如何进行统一管理,完成微服务的自动化部署? 作为一个未接触过服务集群部署的小白,第一次拿到鲲鹏的6台云主机(操作系统:O ...

  5. Ansible 剧本变量 -01

    Ansible 剧本变量 一.变量的介绍 1.概述 变量提供了便捷的方式来管理Ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其它地方或许会反复使 ...

  6. Ansible基础概述

    一.Ansible简介 Ansible基于Python语言实现,由paramiko和PyYAML两个关键模块构建.Ansible的编排引擎可以出色地完成配置管理,流程控制,资源部署等多方面工作.Ans ...

  7. Ansible基本命令

    Ansible安装完成之后就自带很多命令,其中较常用的有7个: ansible ansible-doc ansible-galaxy ansible-init ansible-playbook ans ...

  8. ansible自动化运维从入门到精通

    ansible自动化运维 Ansible介绍 Ansible是一个同时管理多个远程主机的软件(任何可以通过SSH协议登录的机器),因此Ansible可以管理远程虚拟机.物理机,也可以是本地主机. An ...

  9. 中key的用途_Micro Focus Operations Bridge Manager中的多个(RCE)漏洞

    从供应商的网站上. OBM作为操作桥为您的IT操作提供了一个单一的控制中心.所有来自服务器.网络.应用程序.存储和基础设施中其他IT孤岛的事件和性能管理数据都会被整合到一个先进的中央事件控制台的单一事 ...

  10. Ansible基础一Playbook(二)

    摘自:http://www.ansible.com.cn/docs/playbooks_intro.html Handlers: 在发生改变时执行的操作 (当发生改动时)'notify' action ...

最新文章

  1. 如何正确处理Android6.0+的运行时权限申请
  2. openlayers 可以实现3d地图效果吗_OpenLayers教程:地图标注
  3. XScroll.js更新:加入交错切换效果,附思路
  4. 项目调试之小工具---文件名替换
  5. Protocol基本概念
  6. python configparse_python中ConfigParse模块的用法
  7. 道客巴巴vip账号共享2020_腾讯视频VIP怎么两个手机通用?
  8. Creative media发表了Flash memory player「ZEN Mozaic」的存储增量模式
  9. MySQL笔记-简单配置主从库
  10. [转]你会做Web上的用户登录功能吗?
  11. RecyclerView.ItemDecoration 间隔线
  12. sql server的数据同步
  13. 吉林大学超星MOOC学习通高级语言程序设计 C++ 实验01 顺序程序设计(2021级)
  14. BP神经网络(BPNN)
  15. html视频文件哪种格式好,常见的视频格式有哪些?
  16. mysql中的eeplace,mysql必知必会笔记
  17. 5G牌照发放 ,手机产业将迎来第二春
  18. 计算机word表格基础,Word表格的作-计算机基础.doc
  19. hpp文件和h文件有什么区别
  20. 区块链,开启数字时代的金钥匙

热门文章

  1. C语言scanf为啥有时候要输入两次(解析)
  2. win10系统内置PDF虚拟打印机不能用了怎么办
  3. Java 百度ocr文字识别-发票识别,并在页面显示信息
  4. 【计算机组成原理】:计算机系统的组成和层次
  5. P1004 方格取数
  6. 至尊宝代表哪一种人?
  7. MQTT断线重连及订阅消息恢复
  8. PHP框架底层源码怎么看,php底层_php框架底层源码怎么看
  9. centos7文件同步服务器,教你在 Centos7 中使用 Unison 同步文件
  10. _validate_lengths‘ from ‘numpy.lib.arraypad