如何为多个用户隔离Jetty HttpClient? [英] How to isolate Jetty HttpClient for multiple users?
问题描述
我正在使用Eclipse Jetty HttpClient将POST请求发送到服务器,以进行负载测试.
I am using Eclipse Jetty HttpClient to send POST requests to a server, for load testing.
TL; DR:有没有办法使用具有多个用户凭据集的单个HttpClient实例到单个目标URL?
TL;DR: Is there a way to use a single HttpClient instance with multiple user credential sets to a single destination URL?
为此,我需要以单独的用户身份登录到被测服务器.尽管HttpClient是线程安全的,但由于其共享的身份验证存储,它似乎不支持单个实例.
For this purpose, I need to log in to the server-under-test as separate users. Even though HttpClient is thread safe, it does not appear to support this with a single instance, due to its shared authentication store.
该解决方案似乎很简单,只需为每个用户或每个线程使用一个HttpClient.
The solution seems easy, just use one HttpClient per user, or per thread.
这很好,除了HttpClient为每个实例创建了多个线程(看起来是5到10个),因此我的负载测试需要很大的堆,否则在尝试创建新线程时它将开始抛出OutOfMemory异常
This works okay, except that HttpClient creates a number of threads (5 to 10 it seems) for each instance, and so my load test needs a very large heap or else it will start throwing OutOfMemory exceptions when trying to create new threads.
例如,在此非常基本的测试中,第一组凭据用于所有后续POST:
For example, in this very basic test, the first set of credentials is used for all subsequent POSTs:
public class Test
{
static class User
{
String username;
String password;
User(String username, String password)
{
this.username = username;
this.password = password;
}
}
public static void main(String[] args) throws Exception
{
SslContextFactory sslContextFactory = new SslContextFactory.Client();
HttpClient httpClient = new HttpClient(sslContextFactory);
httpClient.start();
List<User> users = new ArrayList<>();
users.add(new User("fry", "1234"));
users.add(new User("leela", "2345"));
users.add(new User("zoidberg", "3456"));
URI uri = new URI("http://localhost:8080/myapi");
for (User user : users)
{
AuthenticationStore auth = httpClient.getAuthenticationStore();
auth.addAuthentication(new DigestAuthentication(uri, DigestAuthentication.ANY_REALM, user.username, user.password));
Request request = httpClient.newRequest(uri);
request.method("POST");
ContentResponse result = request.send();
System.out.println(result.getStatus());
}
}
}
现在,我意识到在这个人为设计的测试中,我可以在两者之间调用 httpClient.getAuthenticationStore().clearAuthenticationResults()
和 httpClient.getAuthenticationStore().clearAuthentications();
循环,但是不适用于我的实际测试,因为我同时有多个线程发布.
Now, I realize in this contrived test that I can call httpClient.getAuthenticationStore().clearAuthenticationResults()
and httpClient.getAuthenticationStore().clearAuthentications();
between loops, however that does not work for my actual testing, where I have multiple threads posting at the same time.
我是否为每个用户使用单独的HttpClient实例?
Am I stuck using a separate HttpClient instance for each user?
感谢任何想法!
推荐答案
您可以通过抢先"完成所需的操作.每个请求的身份验证标头,如文档中所解释的 .
What you need can be done by "preempting" the authentication headers for every request, as explained in the documentation.
这是您要执行的操作:
// Single HttpClient instance.
HttpClient httpClient = new HttpClient();
// The server URI.
URI uri = URI.create("http://example.com/secure");
// The authentication credential for each user.
Authentication.Result authn1 = new BasicAuthentication.BasicResult(uri, "user1", "password1");
Authentication.Result authn2 = new BasicAuthentication.BasicResult(uri, "user2", "password2");
// Create a request instance.
Request request1 = httpClient.newRequest(uri);
// Add the authorization headers for user1.
authn1.apply(request1);
request1.send();
Request request2 = httpClient.newRequest(uri);
// Add the authorization headers for user2.
authn2.apply(request2);
request2.send();
发送请求并不需要像上面的简单示例中那样顺序发送或使用阻止API.
Sending the requests does not need to be sequential or using the blocking APIs like in the simple example above.
例如,您可以从 for
循环中执行此操作,并随机选择一个用户(及其相应的授权),并使用异步API以获得更好的性能.
You can do it from a for
loop, and pick a user (and its correspondent authorization) randomly, for example, and use the asynchronous APIs for better performance.
这篇关于如何为多个用户隔离Jetty HttpClient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!