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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值