locust+geventhttpclient 性能优化

  上一篇讲述了 Locust 的单进程,多进程,分布式的使用,在压测的时候发现客户机 cpu 基本接近100%,当服务器资源还很空闲,客户机已先达到瓶颈了。下文使用同一台客户机(8核8g)压测网关,对比优化前和优化后的效果。git

 

1、locust 自带 httpclient 

locust 自带 client 是 requests 库的,这个库功能很强大,也是最经常使用的,但性能很通常。github

测试脚本:json

from locust import HttpLocust, TaskSet, task, between # 任务
class UserTsak(TaskSet): def on_start(self): '''初始化数据'''
        pass @task def test(self): self.client.get("/sz/api2/test") def on_stop(self): '''销毁数据'''
        pass

class WebsiteUser(HttpLocust): host = 'https://10.1.62.133' task_set = UserTsak wait_time = between(0, 0)

压测场景一:

1个进程,100 个 user。平均 qps:625api

 CPU 单核占用 100%服务器

 

压测场景二:

 8个进程,100 个 user。平均 qps:4847并发

 CPU 8核 平均使用率 100%分布式

 

2、locust + geventhttpclient

    geventhttpclient  GitHub 地址:https://github.com/locustio/geventhttpclient 高并发

1)geventhttpclient 中的 httpclient 使用协程实现,性能相对 requests 库提高5~6倍。而后使用 events(事件)从新定义客户端,events(事件)最终会把压测中产生的数据输出到 UI 界面。做为压测脚本,咱们要尽量减小没必要要的逻辑。工具

from locust import HttpLocust, TaskSet, task, between, events import time from locust.exception import LocustError from geventhttpclient import HTTPClient from geventhttpclient.url import URL # 任务
class UserTsak(TaskSet): def on_start(self): '''初始化数据''' url = URL('http://10.1.62.133') self.http = HTTPClient(url.host) @task def test(self): try: start_time = time.time() res = self.http.get("/sz/api2/test") data = res.read() end_time = time.time() response_time =int((end_time - start_time)*1000) response_length = len(data) assert json.loads(data)['Error'] == 0 if res.status_code == 200: events.request_success.fire(request_type="GET", name="test_success", response_time = response_time, response_length=response_length)

        except AssertionError: end_time = time.time() response_time =int((end_time - start_time)*1000) events.request_failure.fire(request_type="GET", name="test_failure", response_time=response_time,response_length=0, exception="断言错误。status_code:{}。接口返回:{}。".format(res.status_code,json.loads(data))) except Exception as e: events.locust_error.fire(locust_instance=UserTsak, exception=e, tb =sys.exc_info()[2]) def on_stop(self): '''运行结束,关闭http/https链接''' self.http.close() class WebsiteUser(HttpLocust): host = 'http://10.1.62.133' task_set = UserTsak wait_time = between(0, 0)

 

2)其实还有一种简单的实现方式,官网上有案例,代码和 locust+requests 同样。须要安装geventhttpclient,而后将 WebsiteUser 继承的超类换成 FastHttpLocust类 便可。但实际测试下来不如 案例1 来的高效(差异还蛮大的),缘由多是 events(事件)处理不如自定义效率高。性能

from locust import TaskSet, task, between from locust.contrib.fasthttp import FastHttpLocust # 任务
class UserTsak(TaskSet): def on_start(self): '''初始化数据'''
        pass @task def test(self): self.client.get("/sz/api2/test") def on_stop(self): '''销毁数据'''
        pass

class WebsiteUser(FastHttpLocust): host = 'https://10.1.62.133' task_set = UserTsak wait_time = between(0, 0)

 

 压测场景一:

 1个进程,100 个 user。平均 qps:3948

  CPU 单核占用也接近 100%,看起来是单进程客户端瓶颈了

 

压测场景二:

8个进程,100 个 user。平均 qps:9424

 CPU 8核平均使用率 60% 左右

 

总结一下:

        经过下面表格能够看出,locust + geventhttpclient 性能提高幅度仍是挺大的,单进程提高5倍多,开8个slave后 CPU占用在60%。

 httpclient方式 单进程qps CPU使用率(单进程模式) 多进程qps(8个进程) CPU使用率 (多进程模式)
locust + requests  625 100%(单核)  4847  100%(平均)
locust + geventhttpclient  3948 100%(单核)  9424  60%(平均)

 

 

 

 

       

  如下是用 jmeter 在同一台客户机100线程压测结果,平均qps在9000左右,比 locust 稍低。并且 locust 在高并发能力方面比 jmeter 强多了,因此推荐使用 locust 做为压测工具。固然 jmeter 的优点也不少,好比:使用 GUI 建立脚本很方便,各类统计、图形报告很丰富,众多插件支持,这个仁者见仁,智者见智哈。 

 

相关文章
相关标签/搜索