Locust源码分析之runners.py模块(6)

runners.py模块是控制locust运行的核心功能,控制着性能测试的运行机制。包含了本地运行,分布式运行等。

主要由LocustRunner,LocalLocustRunner,DistributedLocustRunner,MasterLocustRunner以及SlaveLocustRunner三个类组成。其中LocustRunner类是其他类的基类,MasterLocustRunner和SlaveLocustRunner是DistributedLocustRunner的拓展类。

LocustRunner

LocustRunner是其余所有runner类的基类,也是整个locust中运行的核心代码

class LocustRunner(object):
    # 实例化LocustRunner时,需要传入两个参数:locust_classes和options
    def __init__(self, locust_classes, options):
        self.options = options # 命令行中传入的参数
        self.locust_classes = locust_classes # locust类,task任务列表
        self.hatch_rate = options.hatch_rate  # 命令行参数:每秒启动数
        self.num_clients = options.num_clients # 命令行参数:并发数
        self.host = options.host # 命令行参数:被压服务器地址
        self.locusts = Group() #协程组:gevent.pool.Group()
        self.greenlet = self.locusts 
        self.state = STATE_INIT # 压测状态,初始状态为“READY”
        self.hatching_greenlet = None 
        self.exceptions = {}
        self.stats = global_stats # 在stats模块中,有一个全局变量global_stats用于存储当前状态
        
        # 注册监听器,当收到reset_stats指令时重置当前性能数据stats状态
        def on_hatch_complete(user_count):
            self.state = STATE_RUNNING
            if self.options.reset_stats:
                logger.info("Resetting stats\n")
                self.stats.reset_all()
        events.hatch_complete += on_hatch_complete

    # 属性request_stats:返回当前性能指标状态
    @property 
    def request_stats(self):
        return self.stats.entries

    # 属性errors:返回当前错误信息
    @property
    def errors(self):
        return self.stats.errors
    
    # 属性user_count,返回用户并发数
    @property
    def user_count(self):
        return len(self.locusts)

    def weight_locusts(self, amount, stop_timeout = None):
        """
        根据权重分发各个Locust类占有的并发数量bucket,amount为总并发数
        """
        bucket = []
        # 计算权重之和
        weight_sum = sum((locust.weight for locust in self.locust_classes if locust.task_set)) 
        for locust in self.locust_classes:
            if not locust.task_set:
                warnings.warn("Notice: Found Locust class (%s) got no task_set. Skipping..." % locust.__name__)
                continue

            if self.host is not None:
                locust.host = self.host
            if stop_timeout is not None:
                locust.stop_timeout = stop_timeout

            # 根据每个locust请求的权重计算所占的比例
            percent = locust.weight / float(weight_sum)
            # 计算出每个locust请求需要多少个并发数
            num_locusts = int(round(amount * percent))
            bucket.extend([locust for x in xrange(0, num_locusts)])
        return bucket

    def spawn_locusts(self, spawn_count=None, stop_timeout=None, wait=False):
        """
        执行压力测试并发任务
        spawn_count: 并发数
        stop_timeout:超时时间
        wait: task任务执行间隔
        """
        # 如果没有传入spawn_count参数则使用命令行传入的并发数
        if spawn_count is None:
            spawn_count = self.num_clients

        #获取任务并发数
        bucket = self.weight_locusts(spawn_count, stop_timeout) 
        spawn_count = len(bucket)

        #如果是首次启动/重启性能测试,并发数等于传入的spawn_count
        if self.state == STATE_INIT or self.state == STATE_STOPPED:
            self.state = STATE_HATCHING
            self.num_clients = spawn_count
        else: #如果当前性能测试已经启动,则叠加spawn_count并发数
            self.num_clients += spawn_count

        logger.info("Hatching and swarming %i clients at the rate %g clients/s..." % (spawn_count, self.hatch_rate))
        #获取每一个task任务
        occurence_count = dict([(l.__name__, 0) for l in self.locust_classes])
        
        def hatch():
            sleep_time = 1.0 / self.hatch_rate #用户并发间隔,为每秒新增请求数的倒数
            while True:
                if not bucket:
                    # 当bucket为空时,表示增压已经完成
               
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Locust是一个基于Python的开源负载测试工具,它可以模拟大量的用户并发访问应用程序,从而测试应用程序的性能和稳定性。下面是Locust源码分析。 ## 1. 项目结构 Locust的代码结构如下: ``` locust/ ├── core/ │ ├── events.py │ ├── exception.py │ ├── runners.py │ ├── stats.py │ └── taskset.py ├── runners/ │ ├── __init__.py │ ├── base.py │ ├── master.py │ ├── worker.py │ └── web.py ├── stats/ │ ├── __init__.py │ ├── distributions.py │ ├── history.py │ ├── percentile.py │ └── stats.py ├── test/ │ └── __init__.py ├── ui/ │ ├── __init__.py │ ├── static/ │ ├── templates/ │ └── web.py ├── util/ │ ├── __init__.py │ ├── exceptions.py │ ├── roundrobin.py │ ├── runners.py │ └── web.py ├── __init__.py ├── contrib/ ├── runners.py └── web.py ``` 其中,`core`目录下是Locust的核心代码,`runners`目录下是Locust的运行器,`stats`目录下是Locust的统计代码,`ui`目录下是Locust的Web界面代码,`util`目录下是Locust的工具代码。 ## 2. 核心代码 Locust的核心代码位于`core`目录下,其中比较重要的文件包括: - `events.py`:定义了Locust的事件管理器,用于管理不同事件的触发和处理。 - `exception.py`:定义了Locust的自定义异常。 - `runners.py`:定义了Locust的运行器,包括单机运行器和分布式运行器。 - `stats.py`:定义了Locust的统计数据模块,包括整个测试的统计数据和单个任务的统计数据。 - `taskset.py`:定义了Locust的任务集合,即一组任务的集合。 ## 3. 运行器 Locust的运行器位于`runners`目录下,其中包括如下文件: - `base.py`:定义了运行器的基类。 - `master.py`:定义了主节点运行器,用于控制整个测试的运行。 - `worker.py`:定义了工作节点运行器,用于执行任务并向主节点报告测试结果。 - `web.py`:定义了Web界面运行器,用于提供Web界面。 从上面的文件可以看出,Locust支持分布式测试,其中主节点负责控制整个测试的运行,而工作节点负责执行任务和向主节点报告测试结果。 ## 4. 统计数据 Locust的统计数据位于`stats`目录下,其中包括如下文件: - `distributions.py`:定义了一些分布函数,用于统计数据分析。 - `history.py`:定义了历史统计数据,用于保存历史统计数据并进行比较。 - `percentile.py`:定义了百分位数,用于统计数据分析。 - `stats.py`:定义了一些统计数据的类,包括请求数、错误数、响应时间等。 可以看出,Locust的统计数据比较丰富,可以帮助我们更好地分析测试结果。 ## 5. Web界面 Locust的Web界面位于`ui`目录下,其中包括如下文件: - `web.py`:定义了Web界面运行器,用于提供Web界面。 - `templates`:定义了Web界面的HTML模板。 - `static`:定义了Web界面的静态资源文件,包括CSS、JavaScript等。 通过Web界面,我们可以方便地启动测试、查看测试结果以及实时监控测试进度和统计数据。 ## 6. 工具代码 Locust的工具代码位于`util`目录下,其中包括如下文件: - `exceptions.py`:定义了一些自定义异常。 - `roundrobin.py`:定义了一个循环列表,用于轮询任务执行。 - `runners.py`:定义了运行器相关的工具函数。 - `web.py`:定义了一些Web相关的工具函数。 这些工具代码为Locust的实现提供了一些辅助函数和数据结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值