我使用 AWS 上提供的 terraform 进行分布式 Locust。在加载期间,我更新目标的 Route53 加权记录以指向另一个版本。 我看到 Locust 不会更新初始 DNS 解析,并继续针对我的第一个版本。
如何让 Locust 在加载过程中重新计算 dns 解析?
您可以使用
dnspython
自行解析地址 (
https://blog.devgenius.io/pyops-dnspython-toolkit-590a368b5c2)
A = dns.resolver.resolve(domain, 'A')
for answer in A.response.answer:
for item in answer.items:
ip = item.address
然后针对该 ip 执行请求,手动添加适当的
Host
标头。
self.client.get(f"http://{ip}", headers={"Host": domain})
编辑:如果使用操作系统 DNS 解析是可以的或者甚至是可取的,那么也许只需创建一个新的
Session
就足够了。这会创建一个新的 tcp 连接,并且一旦任何操作系统级别缓存超时,就会触发新的 DNS 查询:
from locust.clients import HttpSession
...
@task
def t(self):
self.client.close()
self.client = HttpSession(
base_url=self.host,
request_event=self.environment.events.request,
user=self
)
# your actual requests
当每个 HttpUser 创建新的 HttpSession 时,每个用户实例都有自己的连接池。
https://docs.locust.io/en/stable/writing-a-locustfile.html#connection-pooling从用户池中删除连接并建立新连接之前,对 DNS 记录的任何更新都不会反映出来。
有多种方法可以禁用连接池:
覆盖
pool_manager
num_pools=0
pool
覆盖 User 类(在同一类中共享)的 pool_manager
from locust import HttpUser, task
from urllib3 import PoolManager
class SampleUser(HttpUser):
# add this
pool_manager = PoolManager(num_pools=0)
@task
def hello_world(self):
self.client.get("/")
将 Connection: close
Connection: close
HTTP 标头时,一旦处理请求,连接就会断开,这会有效地禁用连接池。
from locust import HttpUser, task
class SampleUser(HttpUser):
@task
def hello_world(self):
self.client.get("/", headers={"Connection": "close"})
使用 FastHttpUser
FastHttpUser
公开 API 来显式禁用连接池。
默认情况下,如果可能,用户将重用相同的 TCP/HTTP 连接。为了更真实地模拟连接到您的应用程序的新用户,可以手动关闭此连接。https://docs.locust.io/en/stable/increase-performance.html#connection-handlingfrom locust import FastHttpUser, task
class SampleUser(FastHttpUser):
@task
def hello_world(self):
self.client.client.clientpool.close()
self.client.get("/")
请注意,禁用连接池可能会降低负载测试性能。