如何为多个用户隔离 Jetty HttpClient?
How to isolate Jetty HttpClient for multiple users?
我正在使用 Eclipse Jetty HttpClient 向服务器发送 POST 请求,以进行负载测试。
TL;DR:有没有办法将具有多个用户凭据集的单个 HttpClient 实例用于单个目标 URL?
为此,我需要以单独的用户身份登录到被测服务器。
尽管 HttpClient 是线程安全的,但由于其共享身份验证存储,它似乎不支持单个实例。
解决方案似乎很简单,只需为每个用户或每个线程使用一个 HttpClient。
这工作正常,除了 HttpClient 为每个实例创建多个线程(看起来是 5 到 10 个),所以我的负载测试需要一个非常大的堆,否则它会在尝试创建时开始抛出 OutOfMemory 异常新话题。
例如,在这个非常基本的测试中,第一组凭据用于所有后续 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();
,但这对我的实际测试不起作用,我有多个线程同时发布时间.
我是否坚持为每个用户使用单独的 HttpClient 实例?
感谢任何想法!
您需要的可以通过为每个请求“抢占”身份验证 headers 来完成,如 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。
您可以从 for
循环开始,随机选择一个用户(及其相应的授权),例如,使用异步 API 以获得更好的性能。
我正在使用 Eclipse Jetty HttpClient 向服务器发送 POST 请求,以进行负载测试。
TL;DR:有没有办法将具有多个用户凭据集的单个 HttpClient 实例用于单个目标 URL?
为此,我需要以单独的用户身份登录到被测服务器。 尽管 HttpClient 是线程安全的,但由于其共享身份验证存储,它似乎不支持单个实例。
解决方案似乎很简单,只需为每个用户或每个线程使用一个 HttpClient。
这工作正常,除了 HttpClient 为每个实例创建多个线程(看起来是 5 到 10 个),所以我的负载测试需要一个非常大的堆,否则它会在尝试创建时开始抛出 OutOfMemory 异常新话题。
例如,在这个非常基本的测试中,第一组凭据用于所有后续 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();
,但这对我的实际测试不起作用,我有多个线程同时发布时间.
我是否坚持为每个用户使用单独的 HttpClient 实例?
感谢任何想法!
您需要的可以通过为每个请求“抢占”身份验证 headers 来完成,如 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。
您可以从 for
循环开始,随机选择一个用户(及其相应的授权),例如,使用异步 API 以获得更好的性能。