Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Hosts, Host Function #99

Closed
robottaway opened this issue Sep 30, 2013 · 12 comments
Closed

Multiple Hosts, Host Function #99

robottaway opened this issue Sep 30, 2013 · 12 comments

Comments

@robottaway
Copy link

Sorry if this is a bad venue for asking this. I could only find twitter as a possible forum for my question.

I have been using Locust for awhile now, and it's been very useful. Having come from using JMeter I would even say I love it. I use it for load testing of course, but I also have it running continuously as a "traffic generator". In this sense it adds a small amount of load across different clusters (our webapps, Elasticsearch).

I work mostly with Amazons AWS. Most of the time I target a cluster of like instances. Could locust be enhanced to load balance across hosts in a cluster? It seems I have to run a new command for each host. I can set host on the locust, but it is static. What if that could be a function that I could implement to talk to AWS and get the list of current cluster hosts and select one (likely randomly).

Having this function would allow locust to automatically detect changes in the clusters (add/remove instance). Since I run indefinitely it would save me a lot of time manually handling changes in cluster topology. If there is any interest in this enhancement I would love to help implement and test it.

@Jahaja
Copy link
Member

Jahaja commented Oct 1, 2013

Thanks, I'm glad it's useful for you.

I reckon you could do this in your own locust file. Basically by overriding the Locust constructor and choosing a random host. The list of hosts could be fetched from wherever just using python.

@robottaway
Copy link
Author

Would that pick a new host per task run though? I seems that would only pick a random host once, and then all future requests would be against that one host. I did something like this by having the host property on the Locust impl use random.choice on a set of hosts to verify and it only picks one and then sticks with it. Would this work any different than doing it in the constructor?

@robottaway
Copy link
Author

I was also thinking of simulating a property via a func but since the host only seems to be consulted once I didn't bother. Maybe it would work?

@property
def host(self):
    return choice(hosts)

@Jahaja
Copy link
Member

Jahaja commented Oct 1, 2013

Oh, I see. Yeah, the constructor is run once for each Locust/user so that would only solve the load balancing. You could solve this by overriding the execute_task in TaskSet like this:

def execute_task(self, task, *args, **kwargs):
    host = get_random_host_func()
    self.client = HttpSession(base_url=host)
    super(TaskSet, self).execute_task(task, *args, **kwargs)

Note that this means that a new http client is created before executing each task and as such no state (cookies etc) remains.

@robottaway
Copy link
Author

Awesome, I will try this. Can I cache the clients themselves? It'd be nice to make it work the way I think we both would like. Basically if I could create a client per simulated customer (locust?).

@Jahaja
Copy link
Member

Jahaja commented Oct 2, 2013

Do you mean that you would like every locust/user to have a http session (which keeps cookies etc) saved for each host that's been randomly assigned on each task?

@robottaway
Copy link
Author

Please excuse me, I wasn't very clear.

In this one particular case I do not need to worry about cookies or sessions. Each request is using basic/digest/oauth type of credentials. If I was testing the forward app servers then I would use an Elastic Load Balancer to solve this problem, and just configure the one host needed.

The thing is Locust is just too good to use for the case of normal front tier website traffic. I use it to test our Elasticsearch servers, our own mid-tier service infrastructure and other types of things available via HTTP(S). It's ability to hammer endpoints is unmatched 👍

I was looking at the code last night, particularly clients.py. It seems an approach we took at Netflix could work which is to allow configuring a "load balancer" implementation into the HttpSession. This class would know about the host(s), and could even maintain the hosts dynamically over time. In my case it can randomly select a host from the set of discovered instances. It looked like the random selection could happen in the "request" method.

I noticed looking at clients.py that I could probably just send the full URL each time I do a request. It's a bit wonkey but seems it's supported. In that case I can probably figure a way to graft the "load balancer" into it.

@Jahaja
Copy link
Member

Jahaja commented Oct 7, 2013

I like that Locust have been useful for hammering your http endpoints, it's fulfulling it's purpose :)

I'm not sure what end-result you are looking for.

So far, I think, you would like to be able to do one or more of the following:

  • Send requests to multiple hosts - basically load-balancing.
  • Add hosts to a running locust setup.
  • To keep the user's/locust's state for each hosts that the locust have requested.

@robottaway
Copy link
Author

Send requests to multiple hosts - basically load-balancing.

Yes, I would like to boot one instance and have it send requests to any number of hosts

Add hosts to a running locust setup.

Yes and also remove them in cases where they go away.

To keep the user's/locust's state for each hosts that the locust have requested.

No. I just want the basic timings and such, and I don't care if they are per host either. There is no cookies or anything else that I need to track.

@Jahaja
Copy link
Member

Jahaja commented Oct 20, 2013

You could create your own client (probably by subclassing HttpSession in this case) that adds the features you're looking for, then override the constructor of the Locust class to use that one. See #83 for some additional information on the topic.

@robottaway
Copy link
Author

That looks like it may be just right. Let me give it a try tomorrow and get back to you.

@Jahaja Jahaja closed this as completed Nov 29, 2013
@samrusk
Copy link

samrusk commented Mar 21, 2015

Hi, Did anyone solve this issue or can provide some example code for their solution?

I am dealing with the exact same issue, sending requests to various nodes in a cluster all with different IP addresses. Need to implement some sort of load balancing method to switch where to send requests to.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants