性能测试平台建设(三)
性能测试工程师使用性能测试平台一般流程为承接分配给自己的性能任务后,上传性能测试方案、脚本、参数化文件,在压力执行环节使用PTA压测控制台进行压力机器申请、延期、释放,压力发起、停止。其中压力机延期和释放本文不涉及细节,压力发起和暂停在PTA操作后具体由Ansible剧本实现。
本文主要讲述PTA通过Ansible playbook调用PTE实现压力发起和暂停。
PTA调用PTE图
PTA原型
脚本和参数化上传:
压力机申请--单机负载or联机负载:
压力机释放:
压力机延期:
Ansible playbook--create.yml
在PTA上承接任务后,Ansible playbook执行的内容:
创建项目目录,projectID表示一个性能测试项目,目录为csv、script目录,用来存储用户上传的脚本和参数化文件。
# 代码调用剧本命令为:
ansible-playbook -e "projectID=1" create.yml
# playbook内容
# create.yml
---
hosts: me
remote_user: root
vars:
dir_var:
"/csv/{{ projectID }}"
- "/script/{{ projectID }}"
tasks:
name: create project dirs
file:
path: "{{ item }}"
state: directory
"{{ dir_var }}" :
Ansible playbook--setup.yml
1.在PTA上申请controller机器,Ansible playbook执行下述tags为controller的剧本:
基于代码传入项目IDprojectID、controller机器IPcontroller_ip,在被选择的controller上创建脚本目录、参数化文件目录
从PTA主机中的对应的工程目录复制脚本文件和参数化文件到controller创建的对应目录中
如果是联机负载情况下的controller,除了以上步骤外还需要进行node ip配置到jmeter.properties文件中,见下文
# 代码调用剧本命令为:
ansible-playbook -e "projectID=1 controller_ip=127.0.0.1" setup.yml --tags=controller
# playbook内容
# setup.yml
---
- hosts: me
remote_user: root
vars:
dir_var:
- "/csv/{{ projectID }}"
- "/script/{{ projectID }}"
file_var:
- "/csv/{{ projectID }}/csv.txt"
- "/script/{{ projectID }}/script.jmx"
jmeter_path: /root/software/apache-jmeter-5.0/
# ====================================================================
tasks:
- name: create controller project script&csv dir.
file:
path: "{{ item }}"
state: directory
delegate_to: "{{ controller_ip }}"
with_items:
- "{{ dir_var }}"
tags: controller
- name: create node project dirs.
file:
path: "{{ item[0] }}"
state: directory
delegate_to: "{{ item[1] }}"
with_nested:
- "{{ dir_var }}"
- "{{ node_ip.split(',') }}"
tags: nodes
# ===================================================================
- name: copy jmx script & csv to controller host
copy:
src: "{{ item }}"
dest: "{{ item }}"
with_items: "{{ file_var }}"
delegate_to: "{{ controller_ip }}"
tags: controller
- name: copy jmx script to node host
copy:
src: "{{ file_var[1] }}"
dest: "{{ file_var[1] }}"
delegate_to: "{{ item }}"
with_items: "{{ node_ip.split(',') }}"
tags: nodes
- name: csv slicing
command: "sh ~/roll.sh {{ file_var[0] }} {{ node_ip_count }} {{ file_var[0] }}"
tags: nodes
- name: distribute csv to all node hosts
copy:
src: "{{ file_var[0] }}0{{ ansible_loop.index0 }}"
dest: "{{ file_var[0] }}"
loop_control:
extended: yes
delegate_to: "{{ item }}"
with_items: "{{ node_ip.split(',') }}"
tags: nodes
# ===================================================================
# distributed perfomance testing
- name: configurate controller jmeter properties
blockinfile:
path: "{{ jmeter_path }}/bin/jmeter.properties"
block: "remote_hosts={{ node_ip }}"
marker: "#{mark} CONF remote jmeter-server ip:{{ node_ip }}"
insertafter: "^# Remote Hosts - comma delimited"
delegate_to: "{{ controller_ip }}"
tags: nodes
- name: start all nodes jmeter-server process
shell: "{{ jmeter_path }}/bin/jmeter-server >>/dev/null &"
delegate_to: "{{ item }}"
with_items: "{{ node_ip.split(',') }}"
tags: nodes
2.在PTA上申请node机器,Ansible playbook执行下述tags为nodes的剧本,剧本内容见上述setup.yml:
# 代码调用剧本命令为:
ansible-playbook -e "projectID=1 controller_ip=127.0.0.1 node_ip=127.0.0.1 node_ip_count=1" setup.yml --tags=nodes
-
为各个node机器创建工程目录,包括脚本、csv目录
-
从PTA主机中的对应的工程目录复制脚本文件到node创建的对应目录中
-
基于node机器数量node_ip_count进行csv文件切分,该切分过程在PTA主机上完成
-
-
-
开启所有node的jmeter-server进程
可参考剧本执行后的TASK内容描述,一一对应了剧本应该完成的内容。
Ansible playbook--run.yml
上述准备工作就绪后,进行性能测试压力发起,分为单机负载和联机负载。
# 单机负载:flag=single
ansible-playbook -e "projectID=1 controller_ip=127.0.0.1 flag=single" run.yml
# 联机负载:flag=multi
ansible-playbook -e "projectID=1 controller_ip=127.0.0.1 flag=multi" run.yml
# run.yml
---
- hosts: me
remote_user: root
vars:
jmeter_path: /root/software/apache-jmeter-5.0/
script_path: "/script/{{ projectID }}"
tasks:
- name: start single pt testing
shell: "{{ jmeter_path }}/bin/jmeter -n -t {{ script_path }}/script.jmx >> /dev/null &"
when: '"{{ flag }}" == "single"'
delegate_to: "{{ controller_ip }}"
- name: start multi pt testing
shell: "{{ jmeter_path }}/bin/jmeter -n -t {{ script_path }}/script.jmx -r >> /dev/null &"
when: '"{{ flag }}" == "multi"'
delegate_to: "{{ controller_ip }}"
Ansible playbook--teardown.yml
压力发起后,主动进行性能测试暂停。
# 单机负载暂停和联机负载暂停都用该剧本命令
ansible-playbook -e "controller_ip=127.0.0.1" teardown.yml --tags=stop-test
# 联机负载机器释放时做一个环境清理:关闭jmeter-server进程
ansible-playbook -e "controller_ip=127.0.0.1 node_ip=127.0.0.1" teardown.yml --tags=kill-jmeter-server
# teardown.yml
---
- hosts: me
remote_user: root
vars:
jmeter_path: /root/software/apache-jmeter-5.0/
tasks:
- name: stop perfomance testing
shell: "java -cp {{ jmeter_path }}/bin/ApacheJMeter.jar org.apache.jmeter.util.ShutdownClient StopTestNow 4445"
delegate_to: "{{ controller_ip }}"
tags: stop-test
- name: stop jmeter-server process
shell: "ps -ef |grep 'ApacheJMeter.jar'|grep -v grep|awk '{print $2}'|xargs kill -9"
delegate_to: "{{ item }}"
with_items: "{{ node_ip.split(',') }}"
tags: kill-jmeter-server
执行结果:
总结
本文通过基本PTA原型图与调用图示,结合具体Ansible剧本演示了一个性能项目被性能测试工程师承接后,调用压力引擎进行性能测试的主流程。剧本文件命名遵循了实际项目和工具操作的顺序,如
-
项目被承接时--create.yml
-
测试环境设置时--setup.yml
-
测试执行时--run.yml,
-
测试结束时--teardown.yml
全篇也只是实现了主场景运行起来,并没有考虑一些分支逻辑流程,比如压测场景自动结束后,PTA界面上的按钮状态如何获取以及转换;脚本更改,参数化文件更改,压力机增减、延期如何触发Ansible剧本进行合理演示等。后续文章也会做一些分支逻辑的设计以及对当前的Ansible剧本进行基于roles的实现改造。