Hi, If it’s optional but still enabled, I think it’s a good idea to speedup bootstrapping.
Just my $0.01 ;) Regards JB > Le 27 déc. 2020 à 16:15, Romain Manni-Bucau <rmannibu...@gmail.com> a écrit : > > Hi everyone, > > wonder if there is some work planned in tomcat 10 to 1. makes it start > faster and 2. make jmx optional. > > I did some tests and locally a tomcat start is about 400ms. > I was surprised to see that Registry.disableRegistry() was taking already > 65ms whereas it should be almost nothing so refactored the code, added a > RegistryFactory and really noop impl (not even a mock) and went down to > 1ms, way better right? except the remaining 64ms went to the next line (new > StandardHost()). After some investigation time is mainly classloading time > (in all senses). > > So I wonder if it wouldnt make sense to optimize tomcat startup time + > finally make JMX optional since it is no more used by users in most cases - > gues we must keep it as an optional plugin since it is used "historically". > > The proposal would be to: > > 1. reduce classloading tree as much as possible for default case - here > having jmx optional will help a lot > 2. probably generate resource bundle as .java at build time to avoid all > the classloading resource bundle implies (it is like 74 loadClass + as much > getResource for a simple startup and all loadclass are misses) > 2.bis. probably add a mode where StringManager uses the default bundle > without passing through the resource bundle layer > 3. cut dead code when we know it is inactive (typically the case for jmx) > 4. open point: bypassing Context: in "main" mode (as the code shared > after), you just want to bind some logic in a servlet/filter/valve, you > don't always care about handling contexts (or a single one) so wonder if we > shouldnt evaluate the fact to add the user logic in a valve for this kind > of bench and maybe document this case (spring boot could inherit from it > since it almost never use anything else that default spring servlet and > binds everything in it). > > Here is the kind of case I'd like to see insanely fast (<100ms - and it is > possible regarding what it does): > > public class Main { > public static void main(String[] args) throws LifecycleException, > InterruptedException { > final long start = System.nanoTime(); > Registry.disableRegistry(); > final long startDisableRegistry = System.nanoTime(); > > final Host host = new StandardHost(); > host.setName("localhost"); > final long startHost = System.nanoTime(); > > final Engine engine = new StandardEngine(); > engine.setName("Tomcat"); > engine.setDefaultHost("localhost"); > engine.setRealm(new NullRealm()); > engine.addChild(host); > final long startEngine = System.nanoTime(); > > final var protocolHandler = new Http11Nio2Protocol(); > protocolHandler.setPort(8080); > final long startHttp11Nio2Protocol = System.nanoTime(); > > final Service service = new StandardService(); > service.setName("Tomcat"); > service.setContainer(engine); > service.addConnector(new Connector(protocolHandler)); > final long startService = System.nanoTime(); > > final StandardServer server = new StandardServer(); > server.setPort(-1); > server.addService(service); > final long startServer = System.nanoTime(); > > final StandardContext context = new StandardContext(); > context.setUseNaming(false); > context.setClearReferencesStopThreads(false); > context.setClearReferencesStopTimerThreads(false); > context.setClearReferencesHttpClientKeepAliveThread(false); > context.setClearReferencesRmiTargets(false); > context.setClearReferencesThreadLocals(false); > context.setClearReferencesObjectStreamClassCaches(false); > context.setWorkDir(System.getProperty("java.io.tmpdir")); > context.setName(""); > context.setPath(""); > context.setDocBase(null); > context.addLifecycleListener(event -> { > if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { > context.setConfigured(true); > if (context.getLoginConfig() == null) { > context.setLoginConfig(new LoginConfig("NONE", null, > null, null)); > context.getPipeline().addValve(new > NonLoginAuthenticator()); > } > } > }); > context.addServletContainerInitializer((classes, ctx) -> { > ctx.addServlet("default", new DefaultServlet()) > .addMapping("/"); > }, Set.of()); > final long startContext = System.nanoTime(); > > host.addChild(context); > > server.init(); > final long inited = System.nanoTime(); > server.start(); > final long started = System.nanoTime(); > // new CountDownLatch(1).await(); > > final var contextClassLoader = > Thread.currentThread().getContextClassLoader(); > > server.stop(); > server.destroy(); > final long stopped = System.nanoTime(); > > System.out.println(TimeUnit.NANOSECONDS.toMillis(started - start) + > "ms"); > System.out.println(TimeUnit.NANOSECONDS.toMillis(stopped - started) > + "ms"); > System.out.println(); > System.out.println("startDisableRegistry: " + > TimeUnit.NANOSECONDS.toMillis(startDisableRegistry - start) + "ms"); > System.out.println("startHost: " + > TimeUnit.NANOSECONDS.toMillis(startHost - startDisableRegistry) + "ms"); > System.out.println("startEngine: " + > TimeUnit.NANOSECONDS.toMillis(startEngine - startHost) + "ms"); > System.out.println("startHttp11Nio2Protocol: " + > TimeUnit.NANOSECONDS.toMillis(startHttp11Nio2Protocol - startEngine) + > "ms"); > System.out.println("startService: " + > TimeUnit.NANOSECONDS.toMillis(startService - startEngine) + "ms"); > System.out.println("startServer: " + > TimeUnit.NANOSECONDS.toMillis(startServer - startService) + "ms"); > System.out.println("startContext: " + > TimeUnit.NANOSECONDS.toMillis(startContext - startServer) + "ms"); > System.out.println("actualInit: " + > TimeUnit.NANOSECONDS.toMillis(inited - startContext) + "ms"); > System.out.println("actualStart: " + > TimeUnit.NANOSECONDS.toMillis(started - inited) + "ms"); > } > } > > > Current reference output (medium values) is - on java 11: > > 364ms > 22ms > > startDisableRegistry: 58ms > startHost: 19ms > startEngine: 7ms > startHttp11Nio2Protocol: 25ms > startService: 39ms > startServer: 12ms > startContext: 26ms > actualStart: 200ms > > Wdyt? Anyone had a look before? > > > PS: if curious the registry patch i did was: > https://gist.github.com/rmannibucau/e7cb9674fa4a21ccfe9eb956b509fad1 - > indeed since it does not help overall I don't ask to integrate it at all, > just a FYI > > Romain Manni-Bucau > @rmannibucau <https://twitter.com/rmannibucau> | Blog > <https://rmannibucau.metawerx.net/> | Old Blog > <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book > <https://www.packtpub.com/application-development/java-ee-8-high-performance> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org