Ansible系列命令

Ansible系列命令有如下:

  • ansible:这个命令是日常工作中使用率非常高的命令之一,主要用于临时一次性操作;
  • ansible-doc:是Ansible模块文档说明,针对每个模块都有详细的用法说明和应用案例介绍;
  • ansible-galaxy:可以简单的理解为Github或PIP的功能,通过ansible-galaxy,我们可以下载安装优秀个Roles;
  • ansible-playbook:是日常应用中使用频率最高的命令,其工作机制是,通过读取预先编写好的playbook文件实现批量管理;
  • ansible-pull:Ansible的另一种工作模式,pull模式,ansible默认使用push模式;
  • ansible-vault:主要用于配置文件加密;
  • ansible-console:让用户可以在ansible-console虚拟出来的终端上像Shell一样使用Ansible内置的各种命令;

上一篇已经介绍过ansibleansible-doc的基本用法,下面再来介绍一下其他系列命令的用法。

ansible-galaxy

用法:ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...

https://galaxy.ansible.com/ 上传或下载优秀的Playbook(roles)

#列出所有已安装的galaxy
ansible-galaxy list #安装galaxy
ansible-galaxy install geerlingguy.redis #删除galaxy
ansible-galaxy remove geerlingguy.redis

ansible-valut

用法:ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] vaultfile.yml

ansible-vault encrypt hello.yml  # 加密
ansible-vault decrypt hello.yml # 解密
ansible-vault view hello.yml # 查看

ansible-console

root@mageduweb (2)[f:10] $ service name=httpd state=stopped

root@mageduweb (2)[f:10] $
执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$ 设置并发数: forks n 例如: forks 10
切换组: cd groupname 例如: cd mageduweb
列出当前组主机列表: list
列出所有的内置模块: ?

ansible-playbook

Usage: ansible-playbook playbook.yml

playbook就是一个用yaml语法把多个模块堆起来的一个文件而已。

1.简介

yaml是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。

2.特点

  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YAML使用实现语言的数据类型
  • YAML有一个一致的信息模型
  • YAML易于实现
  • YAML可以基于流来处理
  • YAML表达能力强,扩展性好

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。下面是一个示例。

- hosts: 10.1.0.1        #定义主机
vars: #定义变量
var1: value
var2: value
tasks: #定义任务
- name: #任务名称。
#这里就可以开始用模块来执行具体的任务了。 handlers: #定义触发通知所作的操作。里面也是跟tasks一样,用模块定义任务。
- name: remote_user: #远程主机执行任务时的用户。一般都是root,一般也不用指定。 - hosts: web
vars:
tasks:
handlers:
remote_user:

YAML文件扩展名通常为.yaml,如example.yaml

Playbooks:

核心组件:

  • Hosts:执行的远程主机列表
  • Tasks:任务,由模块定义的操作的列表;
  • Varniables:内置变量或自定义变量在playbook中调用
  • Templates:模板,即使用了模板语法的文本文件;
  • Handlers:和nogity结合使用,为条件触发操作,满足条件方才执行,否则不执行;
  • Roles:角色;
* 安装http脚本实现:

#!/bin/bash
# 安装Apache
yum install --quiet -y httpd httpd-devel # command: yum install --quiet -y httpd httpd-devel
# 复制配置文件
cp /path/to/config/httpd.conf /etc/httpd/conf/httpd.conf -f
cp/path/to/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf -f
# 启动Apache,并设置开机启动
service httpd start
chkconfig httpd on * 安装httpd ansible-playbook实现 ---
- hosts: all
tasks:
- name: "安装Apache"
command: yum install --quiet -y httpd httpd-devel
- name: "复制配置文件"
command: cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
command: cp /tmp/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf
- name: "启动Apache,并设置开机启动"
command: service httpd start
command: chkconfig httpd on

playbook的基础组件:

Hosts:运行指定任务的目标主机;
remote_user:在远程主机以哪个用户身份执行;
sudo_user:非管理员需要拥有sudo权限;
tasks:任务列表
模块,模块参数:
格式:
(1) action: module arguments
(2) module: arguments

示例:

vim test.yaml,后缀也可以是.yml

- hosts: all
remote_user: root
tasks:
- name: install a group
group: name=mygrp system=true
- name: install a user
user: name=user1 group=mygrp system=true - hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: start httpd service
service: name=httpd state=started

运行playbook,使用ansible-playbook命令:

检测语法:

  • ansible-playbook –syntax-check /path/to/playbook.yaml

测试运行,即不真正执行:

  • ansible-playbook -C /path/to/playbook.yaml
  • ansible-playbook –check /path/to/playbook.yaml
    --list-hosts
--list-tasks
--list-tags

运行:

  • ansible-playbook /path/to/playbook.yaml
    -t TAGS, --tags=TAGS
--skip-tags=SKIP_TAGS 跳过指定的标签
--start-at-task=START_AT 从哪个任务后执行

tags: 标签,给指定的任务定义一个调用标识;

- name: NAME
module: arguments
tags: TAG_ID

指定某条任务执行: ansible-playbook --tags=user useradd.yml

- hosts: mageduweb
remote_user: root tasks:
- name: add group nginx
tags: user
user: name=nginx state=present - name: add user nginx
user: name=nginx state=present group=nginx - name: Install Nginx
yum: name=nginx state=present - name: Start Nginx
service: name=nginx state=started enabled=yes

可以一次调用多个名称相同的标签。也可以调用不同的标签用 “,” 分割。

示例:

我们把httpd的监听端口改为8080

用playbook把这个文件传到node3,4上

指明标签的检查

从标签位置开始执行

跳过标签

handlers 和 notify 结合使用触发条件,让playbook在满足一定触发条件时才去执行某条task

- name: TASK_NAME
module: arguments
notify: HANDLER_NAME
handlers:
- name: HANDLER_NAME
module: arguments

第一次的话都会运行,后边如果文件内容发生改变就会触发notify,然后会直接执行handlers的内容(这里notify后边的事件就都不会执行了)。估计是md5那种的校验。删了个#号竟然也会通知。

---

- hosts: mageduweb
remote_user: root tasks:
- name: add group nginx
tags: user
user: name=nginx state=present - name: add user nginx
user: name=nginx state=present group=nginx - name: Install Nginx
yum: name=nginx state=present - name: config
copy: src=/root/config.txt dest=/etc/nginx/config.txt
notify:
- Restart Nginx
- Check Nginx Process handlers:
- name: Restart Nginx
service: name=nginx state=restarted enabled=yes
- name: Check Nginx Process
shell: ss -tnl | grep 80

playbook 变量使用

变量来源:

(1)ansible setup facts远程主机的所有变量都可以用

(2)自定义变量

a. 在/etc/ansible/hosts 定义变量,在主机组中的主机单独定义,优先级高于组中公共变量

b. 在/etc/ansible/hosts 定义变量,针对主机组中的所有主机集中定义变量

c. 通过命令行指定变量,优先级最高

在hosts Inventory(/etc/ansible/hosts)中为每个主机定义专用变量值;
[all]
172.16.47.103 aaa=nginx
172.16.47.104 aaa=httpd ###############################
- hosts: all
remote_user: root
tasks:
- name: install web package
yum: name={{ aaa }} state=latest
(a) 向不同的主机传递不同的变量;

        IP/HOSTNAME variable_name=value
[web]
10.1.6.72 qzx=httpd
10.1.6.73 qzx=nginx (b) 向组内的所有主机传递相同的变量 ; [groupname:vars]
variable_name=value [web:qzx]
qzx=httpd [web]
10.1.6.72
10.1.6.73

变量调用方式:

{{ variable_name }} 通过{{ }} 调用变量,且变量和{}两头之间必须有空格

额外介绍的是:

在playbook中调用变量时,有时"{{ variable_name }}"需要要双引号引起来方可生效,有时候必须不能用""引起来

d.在playbook中定义,建议使用这个!

vars:
- var_name: value
- var_name: value

e.Inventory还可以使用参数

用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
...

f.在角色调用时传递

roles:
- { role: ROLE_NAME, var: value, ...}

templates模版

文本文件,内部嵌套有模板语言脚本(使用模板语言编写)

Jinja2 是由python编写的。 在我们打算使用基于文本的模板语言时,jinja2是很好的解决方案。yeml是写playbookjinja2是写配置文件模板的。

功能:

将模板的文件的变量值转换成对应的本地主机的确定值。例如:ansible端写一个内建变量{{ ansible_processor_vcpus }},当这个文件被复制到对应主机时会自动生成对应主机 cpu的颗数的结果替换之。

Jinja2语法:

字面量:
字符串:使用单引号或双引号;
数字:整数、浮点数;
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false 算术运算:
+, -, *, /, //, %, ** 比较操作:
==, !=, >, <, >=, <= 逻辑运算:and, or, not

执行模板文件中的脚本,并生成结果数据流,需要使用template模块

template:使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。相当于copy。

将jinja2的文件模板理解并执行,转化为各个主机间的对应值

backup       建立个包括timestamp在内的文件备份,以备不时之需.
dest 远程节点上的绝对路径,用于放置template文件。
group 设置远程节点上的的template文件的所属用户组
mode 设置远程节点上的template文件权限。类似Linux中chmod的用法
owner 设置远程节点上的template文件所属用户
src 本地Jinjia2模版的template文件位置。

注意:此模板不能在命令行使用,而只能用于playbook;用法同copy

(1) templates文件必须存放于目录名为templates下,且命名为 .j2 结尾
(2)yaml/yml playbook文件需和templates目录平级,目录结构如下:
./
├── temnginx.yml
└── templates
└── nginx.conf.j2

案例1:

// templates/nginx.conf.j2

{% for vhost in  nginx_vhosts %}
server {
listen {{ vhost }} } {% endfor %} // temnginx.yml
--- - hosts: mageduweb
remote_user: root
vars:
nginx_vhosts:
- web1
- web2
- web3
# nginx_vhosts:
# - listen: 8080 tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

生成的结果:

server {
listen web1 } server {
listen web2 } server {
listen web3 }
案例2:

shell脚本与Jinja语法对比:
-- shell脚本中写法
for i in {1..10}
do
con
done if [ xx ];then
con
elif
con
else
con
fi -- Jinja写法: // templates/nginx.conf.j2 {% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }} } {% endfor %} * 生成的结果 server {
listen 8080 } * playbook调用文件
// temnginx.yml --- - hosts: mageduweb
remote_user: root
vars:
nginx_vhosts:
- listen: 8080 tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf * 案例3 // temnginx.yml --- - hosts: mageduweb
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
server_name: "web1.magedu.com"
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web3.magedu.com"
root: "/var/www/nginx/web3/" ## 案例1
# nginx_vhosts:
# - web1
# - web2
# - web3
## 案例2 tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf // templates/nginx.conf.j2 {% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
server_name {{ vhost.server_name }}
root {{ vhost.root }} } {% endfor %} * 生成结果: server {
listen 8080
server_name web1.magedu.com
root /var/www/nginx/web1/ } server {
listen 8080
server_name web2.magedu.com
root /var/www/nginx/web2/ } server {
listen 8080
server_name web3.magedu.com
root /var/www/nginx/web3/ } * 案例4
// templates/nginx.conf.j2 {% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }} {% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %} root {{ vhost.root }} } {% endfor %} // temnginx.yml --- - hosts: mageduweb
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
#server_name: "web1.magedu.com"
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web3.magedu.com"
root: "/var/www/nginx/web3/" ## 案例1
# nginx_vhosts:
# - web1
# - web2
# - web3
## 案例2 tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf * 执行命令 ansible-playbook temnginx.yml * 生成的结果 server {
listen 8080 root /var/www/nginx/web1/ } server {
listen 8080 server_name web2.magedu.com root /var/www/nginx/web2/ } server {
listen 8080 server_name web3.magedu.com root /var/www/nginx/web3/ } ### ansible-playbook when条件判断 --- - hosts: mageduweb
remote_user: root tasks:
- name: add group nginx
tags: user
user: name=nginx state=present - name: add user nginx
user: name=nginx state=present group=nginx - name: Install Nginx
yum: name=nginx state=present - name: restart Nginx
service: name=nginx state=restarted
when: ansible_distribution_major_version == "6" ### ansible-playbook with_items 列表 --- - hosts: mageduweb
remote_user: root tasks:
- name: create rsyncd file
copy: src={{ item }} dest=/tmp/{{ item }}
with_items:
- a
- b
- c
- d - name: yum install httpd
yum: name={{ item }} state=present
with_items:
- apr
- apr-util
- httpd * with_itmes 嵌套子变量 --- - hosts: mageduweb
remote_user: root tasks:
- name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1' , groups: 'wheel'}
- { name: 'testuser2' , groups: 'root'}

1、普通示例:

这里/root/nginx.conf内容发生了改变。

  - hosts: ngxsrvs
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=latest
- name: install conf file
template: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: ngxconf
notify: reload nginx service
- name: start nginx service
service: name=nginx state=started enabled=true
handlers:
- name: reload nginx service
shell: /usr/sbin/nginx -s reload

2、条件测试:

when语句:在tasks中使用,Jinja2的语法格式;

-     hosts: all
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=latest
- name: start nginx service on CentOS6
shell: service nginx start
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
- name: start nginx service
shell: systemctl start nginx.service
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"

3、循环:迭代,需要重复执行的任务;

对迭代项的引用,固定变量名为"item”,使用with_item属性给定要迭代的元素; 这个是以任务为中心,围绕每个任务来跑主机,如果中间某个任务中断,那么所有主机以后的任务就无法安装。

元素:

  • 列表
  • 字符串
  • 字典

基于字符串列表给出元素示例:

-   hosts: websrvs
remote_user: root
tasks:
- name: install packages
yum: name={{ item }} state=latest
with_items:
- httpd
- php
- php-mysql
- php-mbstring
- php-gd

基于字典列表给元素示例:item.name .后边的表示键

- hosts: all
remote_user: root
tasks:
- name: create groups
group: name={{ item }} state=present
with_items:
- groupx1
- groupx2
- groupx3
- name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- {name: 'userx1', group: 'groupx1'}
- {name: 'userx2', group: 'groupx2'}
- {name: 'userx3', group: 'groupx3'}

角色:roles

以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;相当于函数的调用把各个事件切割成片段来执行。

mkdir ./{nginx,memcached,httpd,mysql}/{file,templates,vars,handlers,meta,default,tasks} -pv

role_name/

    files/:存储由copy或script等模块调用的文件; 

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

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

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

    templates/:存储由template模块调用的模板文本;

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

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

在playbook中调用角色的方法:

- hosts: HOSTS
remote_user: USERNAME
roles:
- ROLE1
- ROLE2
- { role: ROLE3, VARIABLE: VALUE, ...}
- { role: ROLE4, when: CONDITION }

事例: 基于角色的方式安装 nginx

1.创建需要的文件

mkdir ./{nginx,memcached,httpd,mysql}/{files,templates,vars,handlers,meta,default,tasks} -pv

2.复制相应的安装包和模板到对应目录下

3.写tasks/下的主main.yml

- name: copy nginx package
copy: src=nginx-1.10.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.10.0-1.el7.ngx.x86_64.rpm - name: install nginx package
yum: name=/tmp/nginx-1.10.0-1.el7.ngx.x86_64.rpm state=present - name: install nginx.conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: ngxconf
notify: reload nginx service - name: install default.conf file
template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf
tags: ngxconf
notify: reload nginx service - name: start nginx service
service: name=nginx enabled=true state=started

4.根据需要修改nginx的配置文件模板。(这里改的是work进程生成数和监听的端口)

5.写handlers目录和vars/下的main.yml 文件

6.写需要运行的主yml文件

7.测试

8.运行

安装成功

9.改端口测试,通过传递参数方式

修改成功!!!

推荐资料

http://galaxy.ansible.com

https://galaxy.ansible.com/explore#/

http://github.com/

http://ansible.com.cn/

https://github.com/ansible/ansible

https://github.com/ansible/ansible-examples

最后打个广告,Stanley老师的Ansible权威指南,你,值得拥有

Ansible详解(二)的更多相关文章

  1. .NET DLL 保护措施详解(二)关于性能的测试

    先说结果: 加了缓存的结果与C#原生代码差异不大了 我对三种方式进行了测试: 第一种,每次调用均动态编译 第二种,缓存编译好的对象 第三种,直接调用原生C#代码 .net dll保护系列 ------ ...

  2. PopUpWindow使用详解(二)——进阶及答疑

      相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...

  3. Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

    [Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.And ...

  4. logback -- 配置详解 -- 二 -- <appender>

    附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...

  5. 爬虫入门之urllib库详解(二)

    爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...

  6. [转]文件IO详解(二)---文件描述符(fd)和inode号的关系

    原文:https://www.cnblogs.com/frank-yxs/p/5925563.html 文件IO详解(二)---文件描述符(fd)和inode号的关系 ---------------- ...

  7. Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)

    View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇  ...

  8. HTTPS详解二:SSL / TLS 工作原理和详细握手过程

    HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流 ...

  9. Linux dts 设备树详解(二) 动手编写设备树dts

    Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 前言 硬件结构 设备树dts文件 前言 在简单了解概念之后,我们可以开始尝试写一个 ...

  10. pika详解(二) BlockingConnection

    pika详解(二) BlockingConnection   本文链接:https://blog.csdn.net/comprel/article/details/94592348 版权 Blocki ...

随机推荐

  1. 刷新UITableView

    [from]http://www.superqq.com/blog/2015/08/18/ios-development-refresh-uitableview/ UITableView对于iOS开发 ...

  2. Java解析JSON文件的方法(一)

    一.首先需要在Eclipse工程中导入相关的jar包,jar包参见链接:http://yunpan.alibaba-inc.com/share/link/NdA5b6IFK 二.提供一份待解析的jso ...

  3. App外包开发周期一般多长?

    很多人问我,开发一个app要用多长时间.事实上开发一款app没有固定周期的,得因产品而论,你软件的功能需求决定了app外包开发的周期.但是除了app本身以外,人为因素往往对开发周期也有一定的影响.例如 ...

  4. 属性(Attribute)资源

    前面已经介绍过自定义View组件的开发,自定义View组件与Android系统提供的View组件一样,即可在Java代码中使用,也可在XML界面布局代码中使用. 当在XML布局文件中使用Android ...

  5. layer弹窗插件实战用法小结1—— layer.alert()

    http://layer.layui.com 第一节:layer.alert()弹窗的用法 1.解压layer-v2.2.zip压缩包 2.拷贝layer文件夹到实战项目目录 3.注意:layer.j ...

  6. 2.10. 代码片段:demo方法(Core Data 应用程序实践指南)

    该代码段我觉得没有太多东西 - (void)applicationDidBecomeActive:(UIApplication *)application { [self cdh]; [self de ...

  7. Mac 电脑系统的重装

    首先来说一下我为什么会想到重装Mac的系统呢??? 其实呢  很简单的一个理由,在我写上一个项目的时候,在功能code编写完成后,在模拟器上运行是完全没有问题的,但是在真机上就不行,大家也都知道,在X ...

  8. MyBatis 延迟加载

    在sqlMapConfig中进行设置 <configuration> <settings> <!--延迟加载的总开关--> <setting name=&qu ...

  9. .Net多线程编程—使用Visual Studio 2012进行调试

    1 相关概念 1)栈帧 C语言中,每个栈帧对应着一个未运行完的函数.栈帧中保存了该函数的返回地址和局部变量. 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构. 2)单步执行与单步函 ...

  10. Postman编程

    Postman常用Api Postman像jmeter一样提供前置处理脚本和后置处理脚本.脚本主要使用JavaScript语法,并内置提供了一些js代码库,提供了一些内置对象和方法. 参考:https ...