Apache Tomcat with virtual thread

1.1k views Asked by At

I try to use virtual thread on Apache Tomcat 10.1.16 with this configuration:

    <Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/>

    <Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
               useVirtualThreads="true"
               />

But when I make a request, I'm not on a virtual thread : Thread[#76,Thread-14,5,main] . I profiled my application too but no virtual threads are used.

If I use a Http11NioProtocol instead of Http11Nio2Protocol, all requests are on virtual thread : VirtualThread[#65,http-nio-8080-virt-0]/runnable@ForkJoinPool-1-worker-1

    <Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/>
    


    <!-- A "Connector" represents an endpoint by which requests are received org.apache.coyote.http11.Http11Nio2Protocol
         and responses are returned. Documentation at :
         HTTP Connector: /docs/config/http.html
         AJP  Connector: /docs/config/ajp.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
               useVirtualThreads="true"
               />

Http11Nio2Protocol is not working with virtual threads? Has anyone encountered this problem before?

1

There are 1 answers

2
igor.zh On

Yes, your observation is correct. As of Tomcat 10.1.16, Nio2Endpoint does not execute your code on a virtual thread, while NioEndpoint does. While AbstractEndpoint, a common superclass for both, supports the usage of virtual threads, Nio2Endpoint.setSocketOptions method calls AbstractEndpoint.processSocket with parameter dispatch hardcoded to false, with a comment : Continue processing on the same thread as the acceptor is async. I believe it is associated with a potential asynchronicity of NIO2 Tomcat Connector. Interesting that it does create its Acceptor on a virtual thread, but we cannot benefit much from it.

I believe it is a plain bug of this version of Tomcat and it makes sense either to see if it is fixed in its later versions or report it to them.

BTW, it is possible to override Tomcat Connector implementation and the fix seems to be quite easy and the overriding - trivial. Please let me know if you are locked to this version of Tomcat and the virtual nature of your worker threads is important enough and we could try to do it.

Not directly related to your issue, but the line

<Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/>

does not anyhow influence to process of thread creation in our context, instead AbstractEndpoint.createExecutor hardcodes the creation of org.apache.tomcat.util.threads.VirtualThreadExecutor which is not even a org.apache.catalina.Executor, but just a java.util.concurrent.Executor.