ninjaframework / ninja

Ninja is a full stack web framework for Java. Rock solid, fast and super productive.
http://www.ninjaframework.org
Apache License 2.0
1.91k stars 521 forks source link

Ninja 6.9.0 : Configure Jetty ThreadPool #748

Closed danielsawan closed 2 years ago

danielsawan commented 2 years ago

Hello,

I am trying to deeply configure Jetty used in Ninja because I feel like I have a problem holding many connexions simultaneously. I think the problem is coming from the limited number of HTTP connexions accept or thread pools in Jetty. I actually manage to hold around 25 connexions in parallel then the next requests are in the queue.

The main idea is to allow more parallel connexion in Jetty.

I read this in the Ninja docs

ninja.jetty.configuration allows you to supply a comma-delimited list of jetty.xml configuration files to configure the server. Anything Jetty can do is now available. Please note that if this property is supplied then the host/port property is skipped and you’ll need to configure that in the jetty.xml configuration file. (eg -Dninja.jetty.configuration=jetty.xml,jetty-ssl.xml) Please refer to Jetty distribution for example config files. For each jetty configuration file the local filesystem is searched first, followed by the classpath, and if multiple files are included then each one is applied in order.

So i tried this using the Jetty 9.3 configuration XML files.

-Dninja.jetty.configuration=jetty.xml,jetty-http.xml

I put those xml configurations files in my ClassPath

jetty.xml

<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
      <Set name="secureScheme"><Property name="jetty.httpConfig.secureScheme" default="https" /></Set>
      <Set name="securePort"><Property name="jetty.httpConfig.securePort" deprecated="jetty.secure.port" default="8443" /></Set>
      <Set name="outputBufferSize"><Property name="jetty.httpConfig.outputBufferSize" deprecated="jetty.output.buffer.size" default="32768" /></Set>
      <Set name="outputAggregationSize"><Property name="jetty.httpConfig.outputAggregationSize" deprecated="jetty.output.aggregation.size" default="8192" /></Set>
      <Set name="requestHeaderSize"><Property name="jetty.httpConfig.requestHeaderSize" deprecated="jetty.request.header.size" default="8192" /></Set>
      <Set name="responseHeaderSize"><Property name="jetty.httpConfig.responseHeaderSize" deprecated="jetty.response.header.size" default="8192" /></Set>
      <Set name="sendServerVersion"><Property name="jetty.httpConfig.sendServerVersion" deprecated="jetty.send.server.version" default="true" /></Set>
      <Set name="sendDateHeader"><Property name="jetty.httpConfig.sendDateHeader" deprecated="jetty.send.date.header" default="false" /></Set>
      <Set name="headerCacheSize"><Property name="jetty.httpConfig.headerCacheSize" default="1024" /></Set>
      <Set name="delayDispatchUntilContent"><Property name="jetty.httpConfig.delayDispatchUntilContent" deprecated="jetty.delayDispatchUntilContent" default="true"/></Set>
      <Set name="maxErrorDispatches"><Property name="jetty.httpConfig.maxErrorDispatches" default="10"/></Set>
      <Set name="blockingTimeout"><Property name="jetty.httpConfig.blockingTimeout" default="-1"/></Set>
      <Set name="persistentConnectionsEnabled"><Property name="jetty.httpConfig.persistentConnectionsEnabled" default="true"/></Set>
      <Set name="cookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>

      <!-- Uncomment to enable handling of X-Forwarded- style headers
      <Call name="addCustomizer">
        <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
      </Call>
      -->
    </New>
</Configure>

And the jetty-http.xml file

<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server"       -->
<!-- by adding an HTTP connector.                                   -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <!-- =========================================================== -->
  <!-- Add an HTTP Connector.                                       -->
  <!-- Configure an o.e.j.server.ServerConnector with a single     -->
  <!-- HttpConnectionFactory instance using the common httpConfig  -->
  <!-- instance defined in jetty.xml                               -->
  <!--                                                             -->
  <!-- Consult the javadoc of o.e.j.server.ServerConnector and     -->
  <!-- o.e.j.server.HttpConnectionFactory for all configuration    -->
  <!-- that may be set here.                                       -->
  <!-- =========================================================== -->
  <Call name="addConnector">
    <Arg>
      <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="acceptors" type="int"><Property name="jetty.http.acceptors" deprecated="http.acceptors" default="-1"/></Arg>
        <Arg name="selectors" type="int"><Property name="jetty.http.selectors" deprecated="http.selectors" default="-1"/></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="httpConfig" /></Arg>
                <Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance" default="RFC7230_LEGACY"/></Arg></Call></Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="host"><Property name="jetty.http.host" deprecated="jetty.host" /></Set>
        <Set name="port"><Property name="jetty.http.port" deprecated="jetty.port" default="8080" /></Set>
        <Set name="idleTimeout"><Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/></Set>
        <Set name="acceptorPriorityDelta"><Property name="jetty.http.acceptorPriorityDelta" deprecated="http.acceptorPriorityDelta" default="0"/></Set>
        <Set name="acceptQueueSize"><Property name="jetty.http.acceptQueueSize" deprecated="http.acceptQueueSize" default="0"/></Set>
        <Set name="reuseAddress"><Property name="jetty.http.reuseAddress" default="true"/></Set>
        <Set name="acceptedTcpNoDelay"><Property name="jetty.http.acceptedTcpNoDelay" default="true"/></Set>
        <Set name="acceptedReceiveBufferSize"><Property name="jetty.http.acceptedReceiveBufferSize" default="-1"/></Set>
        <Set name="acceptedSendBufferSize"><Property name="jetty.http.acceptedSendBufferSize" default="-1"/></Set>
        <Get name="SelectorManager">
          <Set name="connectTimeout"><Property name="jetty.http.connectTimeout" default="15000"/></Set>
        </Get>
      </New>
    </Arg>
  </Call>

</Configure>

And on boot Ninja takes those files into consideration but the application crash on start

5:56:55.155 [NinjaJetty] INFO  ninja.standalone.NinjaJetty - Applying jetty configuration 'file:./jetty.xml'
15:56:55.222 [NinjaJetty] INFO  ninja.standalone.NinjaJetty - Applying jetty configuration 'file:./jetty-http.xml'
15:56:55.247 [NinjaJetty] WARN  o.eclipse.jetty.xml.XmlConfiguration - Config error at <Call name="addConnector"><Arg>
      <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector"><Arg name="server"><Ref refid="Server"/></Arg><Arg name="acceptors" type="int"><Property name="jetty.http.acceptors" deprecated="http.acceptors" default="-1"/></Arg><Arg name="selectors" type="int"><Property name="jetty.http.selectors" deprecated="http.selectors" default="-1"/></Arg><Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory"><Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory"><Arg name="config"><Ref refid="httpConfig"/></Arg><Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance" default="RFC7230_LEGACY"/></Arg></Call></Arg></New>
            </Item></Array>
        </Arg><Set name="host"><Property name="jetty.http.host" deprecated="jetty.host"/></Set><Set name="port"><Property name="jetty.http.port" deprecated="jetty.port" default="8080"/></Set><Set name="idleTimeout"><Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/></Set><Set name="acceptorPriorityDelta"><Property name="jetty.http.acceptorPriorityDelta" deprecated="http.acceptorPriorityDelta" default="0"/></Set><Set name="acceptQueueSize"><Property name="jetty.http.acceptQueueSize" deprecated="http.acceptQueueSize" default="0"/></Set><Set name="reuseAddress"><Property name="jetty.http.reuseAddress" default="true"/></Set><Set name="acceptedTcpNoDelay"><Property name="jetty.http.acceptedTcpNoDelay" default="true"/></Set><Set name="acceptedReceiveBufferSize"><Property name="jetty.http.acceptedReceiveBufferSize" default="-1"/></Set><Set name="acceptedSendBufferSize"><Property name="jetty.http.acceptedSendBufferSize" default="-1"/></Set><Get name="SelectorManager"><Set name="connectTimeout"><Property name="jetty.http.connectTimeout" default="15000"/></Set></Get></New>
    </Arg></Call>
15:56:55.249 [NinjaJetty] ERROR ninja.standalone.NinjaJetty - Unable to configure NinjaJetty
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

I found the configuration files template from the official Jetty website : https://www.eclipse.org/jetty/documentation/jetty-9/index.html

Now I am literally blocked and don't really know what to do.

Is there any way to configure Jetty in the java way without having to rewrite the configuration file completely ?

Any help is appreciated.

Thanks !

danielsawan commented 2 years ago

I just put the content of jetty-http.xml in jetty.xml and it worked...