【问题标题】:HTTP/2 priority & dependency test with Jetty使用 Jetty 进行 HTTP/2 优先级和依赖性测试
【发布时间】:2015-12-04 21:58:09
【问题描述】:

优先级和依赖性:

在这里我做了简单的测试。但结果似乎不太好。 我尝试在同一个连接的for循环中发出100个请求(请求url相同,我想知道这部分是否影响结果)。

如果索引是i,那么我的请求stream_id是i,而依赖stream_id是100+i。如果我们的假设是正确的,那么请求永远不会得到响应,因为没有从 101 到 200 的 stream_id。

但是结果显示设置依赖和不设置没有区别。我一帧一帧的拿到了响应数据,没有超时也没有等待。 还有一些其他相关的测试,起点是让依赖于其他流的流先发送,然后依赖流。但结果是一样的。 我还在思考结果的原因。谁能帮我?非常感谢。

代码在这里:

public void run() throws Exception
{
    host = "google.com";
    port = 443;
    //client init
    HTTP2Client client = new HTTP2Client();
    SslContextFactory sslContextFactory = new SslContextFactory(true);
    client.addBean(sslContextFactory);
    client.start();       

    //connect init
    FuturePromise<Session> sessionPromise = new FuturePromise<>();
    client.connect(sslContextFactory, new InetSocketAddress(host, port), new ServerSessionListener.Adapter(), sessionPromise);
    Session session = sessionPromise.get(10, TimeUnit.SECONDS);

    //headers init
    HttpFields requestFields = new HttpFields();
    requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);

    final Phaser phaser = new Phaser(2);

    //multiple request in one connection
    for(int i=0;i<100;i++)
    {
        MetaData.Request metaData = new MetaData.Request("GET", new HttpURI("https://" + host + ":" + port + "/"), HttpVersion.HTTP_2, requestFields);
        PriorityFrame testPriorityFrame = new PriorityFrame(i, 100+i, 4, true);
        HeadersFrame headersFrame = new HeadersFrame(0, metaData, testPriorityFrame, true);

        //listen header/data/push frame
    session.newStream(headersFrame, new Promise.Adapter<Stream>(), new Stream.Listener.Adapter()
    {
        @Override
        public void onHeaders(Stream stream, HeadersFrame frame)
        {
            System.err.println(frame+"headId:"+frame.getStreamId());
            if (frame.isEndStream())
                phaser.arrive();
        }

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback)
        {
            System.err.println(frame +"streamid:"+ frame.getStreamId());
            callback.succeeded();
            if (frame.isEndStream())
                phaser.arrive();
        }

        @Override
        public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
        {
            System.err.println(frame+"pushid:"+frame.getStreamId());
            phaser.register();
            return this;
        }


    });
    }
    phaser.awaitAdvanceInterruptibly(phaser.arrive(), 5, TimeUnit.SECONDS);

    client.stop();
}

【问题讨论】:

    标签: java http jetty http2


    【解决方案1】:

    Jetty 项目(还没有)实现 HTTP/2 请求优先级。

    我们正在讨论这对服务器是否有用,服务器关心的是尽快写回响应。

    如果一个客户端改变了对请求优先级的看法,或者在发出请求时知道实际上它首先想要另一个请求得到服务,那么对于同时必须为其他 10,000 个客户端提供服务的服务器来说,工作量很大连接到它。

    当我们服务器重新计算依赖请求的优先级树时,它可能已经为请求提供服务了。

    当客户端意识到它必须更改请求的优先级时,它的整个响应可能已经在进行中。

    话虽如此,我们当然对服务器执行的请求优先级产生真正性能改进的实际用例感兴趣。我们只是还没有看到它。

    我很想听听您为什么对请求优先级排序以及如何利用它感兴趣。您的回答可能会推动 Jetty 项目实施 HTTP/2 优先级。

    【讨论】:

    • 因为我的研究兴趣是网络安全。我想知道一些黑客可能会利用 HTTP/2 的优先级特性来攻击服务器。所以我想使用 Jetty 客户端来做这样的测试。顺便说一句,我在javadoc 9.3.3中看到了PriorityFrame,为什么你说你还没有实现它。另一件事是,当客户意识到它必须更改请求的优先级时,它的整个响应可能已经在飞行中。我可以使用 Jetty 构建具有某些关系的多个特定请求,就像我的测试。
    • PriorityFrame 存在是因为服务器必须解析它,但它会立即被丢弃,并且没有执行优先级逻辑(目前)。您可以使用 Jetty HTTP2Client 来构建具有优先级和依赖关系的请求,但是您需要找到一个服务器来实现它来触发行为,为此我建议 nghttpx。欢迎加入Jetty mailing list 进行进一步讨论。
    • 如果我理解正确,你的意思是我可以使用 HTTP2Client 来构建具有优先级和依赖关系的请求,看来我需要使用 PriorityFrame 来构建依赖关系。但是你也说没有优先逻辑。所以即使我用优先级和依赖关系构建请求,仍然没有用。我对吗?我还尝试了向支持优先级和依赖性的 h2o 服务器发出请求的代码。但结果还是一样。
    • 是的,您可以使用HTTP2Client 来构建具有优先级和依赖关系的请求。当我说“没有优先级逻辑”时,我指的是服务器。除了发送帧之外,客户端没有任何逻辑。当你与 H2O 交谈时,什么结果保持不变?
    • 我明白了,我的意思是当我使用上面的代码与 h2o 对话时,设置依赖项和不设置依赖项没有区别。我一一拿到数据帧,没有超时或等待。我猜你的解释(到我们......可能已经满足了请求的时候。到客户......它可能已经在飞行中。)是正确的。如果我使用多个线程同时发送请求,您认为结果可能会有所不同吗?我不清楚如何在客户端和服务器中实现优先级。你有什么推荐的材料吗?非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2011-05-13
    • 2015-05-16
    • 2012-10-22
    • 2011-09-18
    • 2020-04-08
    相关资源
    最近更新 更多