在多用户执行中分配类似于唯一ID的东西,可以使用locust

如果要在Locust中为每个用户分配唯一的用户ID并重新执行,却陷入了重复使用同一用户的困境,这里介绍三种方法。

请参阅

Locust公式的GitHub
Locust的文档(分布式负载生成)

使用数组进行模式匹配

如果要使用多个工作进程,则需要考虑到没有在工作进程之间共享数组,但是可以简单且轻松地实现。

from locust import HttpUser, task, between

USERNAMES = [
    "user1",
    "user2",
    "user3",
]

class WebsiteUser(HttpUser):
    wait_time = between(5, 60)

    def __init__(self, parent):
        self.username = ""
        if len(USERNAMES) > 0
            self.username = USERNAMES.pop()

        super().__init__(parent)

    @task
    def task(self):
        print(self.username)

使用了节点间通信的模式。

在测试启动时,从测试用户数中创建唯一用户并平均分配给每个工作器。请注意,虽然仅需要使用Python,但不能应对通过WebUI增加的用户。

from locust import HttpUser, task, events, between
from locust.runners import MasterRunner, WorkerRunner

usernames = []

def setup_test_users(environment, msg, **kwargs):
    # 受信したデータをworkerの変数にセット
    usernames.extend(msg.data)


@events.init.add_listener
def on_locust_init(environment, **_kwargs):
    # node間通信の設定
    if not isinstance(environment.runner, MasterRunner):
        environment.runner.register_message("test_users", setup_test_users)


@events.test_start.add_listener
def on_test_start(environment, **_kwargs):
    # テストユーザーの作成と各workerへ送信
    if not isinstance(environment.runner, WorkerRunner):
        users = []
        for i in range(environment.runner.target_user_count):
            users.append(f"User{i}")

        worker_count = environment.runner.worker_count
        chunk_size = int(len(users) / worker_count)

        for i, worker in enumerate(environment.runner.clients):
            start_index = i * chunk_size

            if i + 1 < worker_count:
                end_index = start_index + chunk_size
            else:
                end_index = len(users)

            data = users[start_index:end_index]

            # workerへデータ送信
            environment.runner.send_message("test_users", data, worker)


class WebsiteUser(HttpUser):
    wait_time = between(2, 5)

    def __init__(self, parent):
        self.username = usernames.pop()
        super().__init__(parent)

    @task
    def task(self):
        print(self.username)

使用Redis的模式

虽然相对于节点间通信,我们可以更简洁地实现对WebUI中用户增加的支持,但是我们仍需要准备Redis。

import redis
from locust import HttpUser, task, between, events
from locust.runners import WorkerRunner

USER_COUNTER_KEY = "user_counter"

# Redisクライアントの取得
redis_client = redis.Redis(host = "[REDIS_HOST]", port = [REDIS_PORT], db = 0)

@events.test_start.add_listener
def on_test_start(environment, **_kwargs):
    # masterでkeyを削除してcounterをリセット
    if not isinstance(environment.runner, WorkerRunner):
        redis_client.delete(USER_COUNTER_KEY)


class WebsiteUser(HttpUser):

    wait_time = between(1, 5)

    def on_start(self):
        # インクリメントでカウントアップして値を取得
        user_count = redis_client.incr(USER_COUNTER_KEY)
        self.username = f"user{user_count}"

    @task
    def task(self):
        print(self.username)

赠品

我在GitHub上上传了使用Redis进行模式重写的GitHub,该模式是对负载测试的执行和本地执行环境进行修正的locust和GKE。

GitHub: GitHub是一个代码托管平台。

 

使用方法

请确认原文因为在本地执行是与原文相同的。
在GKE中执行的方法只是在“使用Google Kubernetes Engine进行负载均衡测试”的步骤上添加了git仓库和redis配置文件的加载,所以只记录差异部分。

设置环境

1. 从 GitHub 上克隆示例存储库。

git clone https://github.com/marv-kashiwabarak/locust_redis_user_counter

2. 切换到克隆的存储库作为工作目录。

cd locust_redis_user_counter
Locust 主节点和工作节点的部署

请将locust-master-controller.yaml文件和locust-worker-controller.yaml文件中的目标主机和项目ID替换为部署的端点和项目ID。还需要替换locust-redis-controller.yaml文件。

sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-master-controller.yaml
sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-worker-controller.yaml
sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-master-controller.yaml
sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-worker-controller.yaml
sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-redis-controller.yaml

2. 部署 Locust 的主节点和工作节点。
还要添加部署 redis 节点。

kubectl apply -f kubernetes-config/locust-master-controller.yaml
kubectl apply -f kubernetes-config/locust-master-service.yaml
kubectl apply -f kubernetes-config/locust-worker-controller.yaml
kubectl apply -f kubernetes-config/locust-redis-controller.yaml
kubectl apply -f kubernetes-config/locust-redis-service.yaml

以上就是流程的更改。
这样就可以在GKE上使用了。

如果有什么错误或更好的方法,请在评论中指出。

bannerAds