趁热记录下,给未来的自己
0. 前言
最近做的项目,进入了压力测试阶段,偶尔会被测试的同学que到:你这个接口压测指标过不了,帮忙看看呗?于是,要放下手上的工作,来分析原因,分析来分析去,一天过去了,下班时间到了,主线任务还没做完,得了,开始加班吧。。。
虽然说,压力测试是测试工程师的工作范畴,但是,对于后端开发同学来说,提前对自己的接口性能有一个大概的摸底掌握,然后根据压测结果,针对性在代码、逻辑、设计等等层面进行优化,不仅可以保证压测的顺利通过,更能变被动为主动,保证项目更加高效地交付。毕竟,一个不重视接口性能的开发是不会成长为一个好架构师的嘛。
工于利其事,必先善其器。一个好的压测工具,会让我们的工作事半功倍。
其实说到压测工具,很多人第一时间想到的可能是Jmeter吧。Jmeter作为一款基于java的桌面级压测工具,功能是非常强大的。但是,正因为其是桌面级工具,所以,多人协作时会遇到一些问题,如环境安装、配置文件同步、本地机器性能差异,基于线程所以无法真正模拟多用户高并发等等。
所以,需要一款能解决以上痛点的工具,而nGrinder正是这样一款工具。
1. 什么是nGrinder
nGrinder是基于Grinder的开源的web性能测试平台,由韩国最大互联网公司NHN公司的开发团队进行了重新设计和完善。特性:开源、易用、高可用、可扩展 (来源)
nGrinder,是由一个controller和连接它的多个agent组成,用户可以通过web界面管理和控制测试,以及查看测试报告,controller会把测试分发到一个或多个agent去执行。用户可以设置使用多个进程和线程来并发的执行该脚本,而且在同一线程中,来重复不断的执行测试脚本,来模拟很多并发用户。
agent可以在一台机器上部署多个,也可以在多台机器上分别部署一个。所有的agent均连接到单个controller上。可以把agent类比成Kubernetes里的node节点,把controller类比成master节点
nGrinder的测试是基于一个python或者groovy的测试脚本,用户按照一定规则编写测试脚本以后,controller会将脚本以及需要的其他文件分发到agent去执行。并在执行过程中收集运行情况、响应时间、测试目标服务器的运行情况等。并保存这些数据生成运行报告,以供以后查看。
2. 安装
概览:本次安装基于ubuntu系统, 一共有两台虚机,在其中一台上安装controller,在两台上各安装一个agent
2.1 环境准备
- 两台虚机,IP为:
192.168.0.1和192.168.0.2 192.168.0.1可以通过ssh key实现无密码登录到192.168.0.2上。- 安装好
docker和docker-compose - 安装好
ansible
2.2 必要文件
2.2.1 docker-compose-controller.yml
ngrinder-controller:
image: ngrinder/controller
container_name: ngrinder-controller
hostname: ngrinder-controller
ports:
- 40080:80
- 16001:16001
- 12000-12009:12000-12009
volumes:
- /data/workspace/docker-install/ngrinder/controller:/opt/ngrinder-controller
2.2.2 docker-compose-agent.yml
ngrinder-agent-1:
image: ngrinder/agent
container_name: ngrinder-agent-1
hostname: ngrinder-agent-1
volumes:
- /data/workspace/docker-install/ngrinder/agent-1:/opt/ngrinder-agent
command:
- 192.168.0.1:40080 # 通过40080端口访问nGrinder的controller
2.2.3 ngrinder-install-playbook.yml
- hosts: all
remote_user: root
tasks:
- name: create ngrinder path
shell: mkdir -p /data/workspace/docker-install/ngrinder/docker-compose
- hosts: ngrinder-master
remote_user: root
tasks:
- name: copy docker-compose controller yaml file
copy: src=./docker-compose-controller.yml dest=/data/workspace/docker-install/ngrinder/ owner=root group=root
- name: run ngrinder controller
shell: docker-compose -f /data/workspace/docker-install/ngrinder/docker-compose-controller.yml up -d
- hosts: ngrinder-nodes
remote_user: root
tasks:
- name: copy docker-compose agent yaml file
copy: src=./docker-compose-agent.yml dest=/data/workspace/docker-install/ngrinder/ owner=root group=root
- name: modify agent yml file # 这里主要是替换每个agent的hostname为各自虚机的hostname,因为如果每个agent的hostname一致,会导致在WEB页面上只能看到其中一个agent在压测时占用的CPU,内存等资源的情况
shell: 'sed -i "s/hostname: ngrinder-agent-1/hostname: $(hostname)-1-ngrinder-agent/g" /data/workspace/docker-install/ngrinder/docker-compose-agent.yml'
- name: run ngringer agent
shell: docker-compose -f /data/workspace/docker-install/ngrinder/docker-compose-agent.yml up -d
2.2.4 /etc/ansible/hosts
编辑/etc/ansible/hosts,添加以下代码:
[ngrinder-master]
192.168.0.1
[ngrinder-nodes]
192.168.0.1
192.168.0.2
2.3 一句话安装
将docker-compose-controller.yml, ngrinder-install-playbook.yml, ngrinder-install-playbook.yml 放到同一个文件夹下,进入该文件夹,运行:
$ ansible-playbook ngrinder-install-playbook.yml
返回:
PLAY [all] ***********************************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************
ok: [192.168.0.1]
ok: [192.168.0.2]
TASK [create ngrinder path] ******************************************************************************************************************************************************
[WARNING]: Consider using the file module with state=directory rather than running mkdir. If you need to use command because file is insufficient you can add warn=False to
this command task or set command_warnings=False in ansible.cfg to get rid of this message.
changed: [192.168.0.1]
changed: [192.168.0.2]
PLAY [ngrinder-master] ***********************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************
ok: [192.168.0.1]
TASK [copy docker-compose controller yaml file] **********************************************************************************************************************************
ok: [192.168.0.1]
TASK [run ngrinder controller] ***************************************************************************************************************************************************
changed: [192.168.0.1]
PLAY [ngrinder-nodes] ************************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************
ok: [192.168.0.2]
ok: [192.168.0.1]
TASK [copy docker-compose agent yaml file] ***************************************************************************************************************************************
changed: [192.168.0.1]
changed: [192.168.0.2]
TASK [modify agent yml file] *****************************************************************************************************************************************************
[WARNING]: Consider using the replace, lineinfile or template module rather than running sed. If you need to use command because replace, lineinfile or template is
insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.
changed: [192.168.0.1]
changed: [192.168.0.2]
TASK [run ngringer agent] ********************************************************************************************************************************************************
changed: [192.168.0.1]
changed: [192.168.0.2]
PLAY RECAP ***********************************************************************************************************************************************************************
192.168.0.1 : ok=9 changed=5 unreachable=0 failed=0
192.168.0.2 : ok=6 changed=4 unreachable=0 failed=0
至此,安装成功。