如何为多个用户隔离Jetty HttpClient? [英] How to isolate Jetty HttpClient for multiple users?

查看:78
本文介绍了如何为多个用户隔离Jetty HttpClient?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆