본문 바로가기

잡부생활

Python locust load test tool

보통 벤치마크는 간단히 ApacheBenchmark를 통해 Req 임계치, Latency 정도를 확인하거나,
(ab -n 100 -c 5 -C "somecookie=rawr" http://google.com/)

Jmeter, nGrinder(Java)와 같은 프로그램을 통해 더 많은 정보를 확인하거나(nGrinder는 안 써봄)
장점
1. GUI 환경
2. 필요 시 플러그인 사용

단점
1. GUI 환경
2. 필요 시 플러그인 사용
3. 환경 구성이 짜증남
4. 메모리 소모가 매우 큼

구성해놓은 Jmeter 클러스터 VM들은 다시 start 하기도 싫음... 뭔가 버벅이는 느낌..

그러던 중 Python locust를 발견

 

Installation — Locust 0.12.2 documentation

On Windows, running pip install locustio should work. However, if it doesn’t, chances are that it can be fixed by first installing the pre built binary packages for pyzmq, gevent and greenlet. Once you’ve done that you should be able to just pip install lo

docs.locust.io

장점
1. GUI 환경이 아님
2. Python locust는 python만 설치되어 있으면 됨
3. python 테스트 시나리오를 작성하고, Run 하면 끝
4. 메모리도 Jmeter에 비해 훨씬 덜 소모함

단점
1. GUI 환경이 아님
2. python 테스트 시나리오를 작성하고 수행하면 끝
3. Request 주기 설정이 유연하지 못함(가능한가? 확인해봐야됨)


[사용 방법]
python 설치... pip 패키저로 locust 설치..

locust 이벤트 순서
1. Locust setup
2. TaskSet setup
3. TaskSet on_start
4. TaskSet tasks…
5. TaskSet on_stop
6. TaskSet teardown
7. Locust teardown

Document Sample

from locust import HttpLocust, TaskSet, task

class UserBehavior(TaskSet): 
	def on_start(self): 
    """ on_start is called when a Locust start before any task is scheduled """
		self.login() 
    
	def on_stop(self):
    """ on_stop is called when the TaskSet is stopping """ 
		self.logout() 
        
	def login(self): 
		self.client.post("/login.php", {"user_id":"admin", "user_pw":"1324"}) 
        
	def logout(self): 
		self.client.post("/logout.php", {"user_id":"admin", "user_pw":"1324"}) 
     
     
	@task(2)
	def index(self): 
		self.client.get("/main.php") 
        
	@task(1) 
	def profile(self): 
		self.client.get("/") 
        
        
class WebsiteUser(HttpLocust): 
	task_set = UserBehavior
	min_wait = 1000
	max_wait = 5000

 

 

HttpsLocust, TaskSet의 클래스명 변경
Locust -> User
HttpsLocust -> HttpUser
https://docs.locust.io/en/latest/changelog.html#changelog-1-0

 

Changelog Highlights — Locust 2.4.1.dev2 documentation

SubLocust replaced by TaskSet and Locust class behaviour changed Locust classes does no longer control task scheduling and execution. Therefore, you no longer define tasks within Locust classes, instead the Locust class has a task_set attribute which shoul

docs.locust.io


on_start -> login // Task 수행 // on_stop -> logout
task 데코레이션의 경우 task fucntion의 weigth 수치(index 2 : 1 profile)
min_wait, max_wait: task function 호출 간격(1~5초 사이로 task 수행)

실행 명령어: locust -f my_locust_file.py --host=타겟주소
(slave 실행: locust -f my_locustfile.py --slave --master-host=192.168.0.14) 

slave... out -> work

locust -f my_locust_file.py
(master 실행: locust -f my_locust_fily.py --master)
(work 실행: locust -f my_locust_fily.py --worker --master-host=127.0.0.1)
https://docs.locust.io/en/stable/running-locust-distributed.html

 

Distributed load generation — Locust 2.4.0 documentation

A single process running Locust can simulate a reasonably high throughput. For a simple test plan it should be able to make many hundreds of requests per second, thousands if you use FastHttpUser. But if your test plan is complex or you want to run even mo

docs.locust.io


브라우저: http://localhost:8089 접속(vhost와 초당 vhost 증가율)
기본적으로 locust는 로컬 주소만 접속 가능
따라서 로컬이 아닌 곳에서 사용할 경우에는 터널링 필요

putty

Web에서 호스트까지 지정하도록 변경
RPS의 경우 locust는 싱글코어로 동작하기 때문에 기본적으로는 500~700 정도 내의 한계가 있다.
따라서 RPS를 늘리기 위해서는 워커 노드를 추가로 사용

c5.4xlarge(vCPU 16 / Mem 32GiB)의 경우
master + 10개 worker 기준 CPU 60% 사용, RPS는 5500 수준 (단순한 Req)

변경 후
변경 전


결과

 

 



locust 테스트 후 느낀 점
주요 기능은 Document를 통해 짧은 시간내 학습이 가능함
프로그램이 가벼움, 대부분 필요한 결과 데이터 확인 가능
앞으로 locust 애용 애정

세련된 스크립팅은 아래 ktanakaj상?을 참고해서 공부해야 할 듯

 

ktanakaj/locust-example

Example scripts for Locust. Contribute to ktanakaj/locust-example development by creating an account on GitHub.

github.com


python version 2에서 too many error 발생 시 참고

 

Error: Too many files open · Issue #92 · locustio/locust

Hello, When using locust with 1 master and 4 slaves, running a 50,000 users at 200 hatched per second I'm receiving the following error: 'ConnectionError(MaxRetryError("HTTPConnectionP...

github.com