Merge pull request #2831 from eclipse/jetty-9.4.x-2828-http2_connection_listener_contention
Fixes #2828 - AbstractHTTP2ServerConnectionFactory concurrent connect low performance.
This commit is contained in:
commit
6015ad5ead
|
@ -18,13 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.http2.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jetty.http2.BufferingFlowControlStrategy;
|
||||
import org.eclipse.jetty.http2.FlowControlStrategy;
|
||||
import org.eclipse.jetty.http2.HTTP2Connection;
|
||||
import org.eclipse.jetty.http2.api.Session;
|
||||
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
|
||||
import org.eclipse.jetty.http2.frames.Frame;
|
||||
import org.eclipse.jetty.http2.frames.SettingsFrame;
|
||||
|
@ -38,12 +42,14 @@ import org.eclipse.jetty.server.HttpConfiguration;
|
|||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
@ManagedObject
|
||||
public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConnectionFactory
|
||||
{
|
||||
private final Connection.Listener connectionListener = new ConnectionListener();
|
||||
private final HTTP2SessionContainer sessionContainer = new HTTP2SessionContainer();
|
||||
private final HttpConfiguration httpConfiguration;
|
||||
private int maxDynamicTableSize = 4096;
|
||||
private int initialSessionRecvWindow = 1024 * 1024;
|
||||
|
@ -66,6 +72,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
for (String p:protocols)
|
||||
if (!HTTP2ServerConnection.isSupportedProtocol(p))
|
||||
throw new IllegalArgumentException("Unsupported HTTP2 Protocol variant: "+p);
|
||||
addBean(sessionContainer);
|
||||
this.httpConfiguration = Objects.requireNonNull(httpConfiguration);
|
||||
addBean(httpConfiguration);
|
||||
setInputBufferSize(Frame.DEFAULT_MAX_LENGTH + Frame.HEADER_LENGTH);
|
||||
|
@ -234,7 +241,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
|
||||
HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(),
|
||||
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
|
||||
connection.addListener(connectionListener);
|
||||
connection.addListener(sessionContainer);
|
||||
return configure(connection, connector, endPoint);
|
||||
}
|
||||
|
||||
|
@ -245,18 +252,50 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize());
|
||||
}
|
||||
|
||||
private class ConnectionListener implements Connection.Listener
|
||||
@ManagedObject("The container of HTTP/2 sessions")
|
||||
public static class HTTP2SessionContainer implements Connection.Listener, Dumpable
|
||||
{
|
||||
private final Set<Session> sessions = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@Override
|
||||
public void onOpened(Connection connection)
|
||||
{
|
||||
addManaged((LifeCycle)((HTTP2Connection)connection).getSession());
|
||||
Session session = ((HTTP2Connection)connection).getSession();
|
||||
sessions.add(session);
|
||||
LifeCycle.start(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed(Connection connection)
|
||||
{
|
||||
removeBean(((HTTP2Connection)connection).getSession());
|
||||
Session session = ((HTTP2Connection)connection).getSession();
|
||||
if (sessions.remove(session))
|
||||
LifeCycle.stop(session);
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "The number of HTTP/2 sessions", readonly = true)
|
||||
public int getSize()
|
||||
{
|
||||
return sessions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
return ContainerLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
ContainerLifeCycle.dumpObject(out, this);
|
||||
ContainerLifeCycle.dump(out, indent, sessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x[size=%d]", getClass().getSimpleName(), hashCode(), sessions.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue