2
votes

Le démarrage de l'EmbeddedServer de Micronaut extrêmement lent

J'ai créé un micronaute "Hello World!" application et un test JUnit selon le guide de l'utilisateur Micronaut:

https://docs.micronaut.io/latest/guide/index.html#creatingClient

sur macOS Mojave (10.14) avec Java 1.8.0_25-b17.

Test de l'unité:

22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Finding candidate beans for type: interface io.micronaut.http.server.netty.ssl.ServerSslBuilder
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [] for type: interface io.micronaut.http.server.netty.ssl.ServerSslBuilder
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Resolving beans for type: io.netty.channel.ChannelOutboundHandler
22:55:06.833 [main] TRACE i.m.context.DefaultBeanContext - Looking up existing beans for key: io.netty.channel.ChannelOutboundHandler
22:55:06.833 [main] TRACE i.m.context.DefaultBeanContext - No beans found for key: io.netty.channel.ChannelOutboundHandler
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Finding candidate beans for type: interface io.netty.channel.ChannelOutboundHandler
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [] for type: interface io.netty.channel.ChannelOutboundHandler
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Found no possible candidate beans of type [io.netty.channel.ChannelOutboundHandler] for qualifier: null 
22:55:06.833 [main] TRACE i.m.context.DefaultBeanContext - Looking up existing bean for key: io.micronaut.http.server.netty.EventLoopGroupFactory
22:55:06.833 [main] TRACE i.m.context.DefaultBeanContext - No existing bean found for bean key: io.micronaut.http.server.netty.EventLoopGroupFactory
22:55:06.833 [main] DEBUG i.m.context.DefaultBeanContext - Finding candidate beans for type: interface io.micronaut.http.server.netty.EventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Finding candidate beans for type: class io.micronaut.http.server.netty.EpollEventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [] for type: class io.micronaut.http.server.netty.EpollEventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Finding candidate beans for type: class io.micronaut.http.server.netty.KQueueEventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [] for type: class io.micronaut.http.server.netty.KQueueEventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [Definition: io.micronaut.http.server.netty.NioEventLoopGroupFactory] for type: interface io.micronaut.http.server.netty.EventLoopGroupFactory
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Finalized bean definitions candidates: [Definition: io.micronaut.http.server.netty.NioEventLoopGroupFactory]
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Found concrete candidate [Definition: io.micronaut.http.server.netty.NioEventLoopGroupFactory] for type: io.micronaut.http.server.netty.EventLoopGroupFactory 
22:55:06.834 [main] DEBUG io.micronaut.context.lifecycle - Created bean [io.micronaut.http.server.netty.NioEventLoopGroupFactory@4b1c0397] from definition [Definition: io.micronaut.http.server.netty.NioEventLoopGroupFactory] with qualifier [null]
22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Registering singleton bean io.micronaut.http.server.netty.NioEventLoopGroupFactory@4b1c0397 for type [io.micronaut.http.server.netty.EventLoopGroupFactory] using bean key io.micronaut.http.server.netty.NioEventLoopGroupFactory
22:56:22.040 [main] DEBUG io.micronaut.context.lifecycle - Created bean [io.micronaut.http.server.netty.NettyHttpServer@2fe88a09] from definition [Definition: io.micronaut.http.server.netty.NettyHttpServer] with qualifier [null]
22:56:22.041 [main] DEBUG i.m.context.DefaultBeanContext - Registering singleton bean io.micronaut.http.server.netty.NettyHttpServer@2fe88a09 for type [io.micronaut.runtime.server.EmbeddedServer] using bean key io.micronaut.http.server.netty.NettyHttpServer
22:56:22.042 [main] DEBUG i.n.c.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
22:56:22.050 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
22:56:22.050 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
22:56:22.056 [main] DEBUG i.n.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
22:56:22.063 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@2ca6546f
22:56:22.063 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@6b63d445
22:56:22.063 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@7578e06a
22:56:22.064 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@30b2b76f
22:56:22.064 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@56da52a7
22:56:22.064 [main] TRACE io.netty.channel.nio.NioEventLoop - instrumented a special java.util.Set into: sun.nio.ch.KQueueSelectorImpl@23ee75c5

Le "Hello World!" l'application démarre rapidement (environ une seconde). Cependant, le test JUnit prend plus de 75 secondes. Il se bloque sur la ligne suivante pendant 75 secondes:

22:55:06.834 [main] DEBUG i.m.context.DefaultBeanContext - Registering singleton bean io.micronaut.http.server.netty.NioEventLoopGroupFactory@4b1c0397 for type [io.micronaut.http.server.netty.EventLoopGroupFactory] using bean key io.micronaut.http.server.netty.NioEventLoopGroupFactory
22:56:22.040 [main] DEBUG io.micronaut.context.lifecycle - Created bean [io.micronaut.http.server.netty.NettyHttpServer@2fe88a09] from definition [Definition: io.micronaut.http.server.netty.NettyHttpServer] with qualifier [null]

Le correctif suggéré dans / etc / hosts ne fonctionne pas

J'ai essayé cette solution suggérée (en ajoutant le nom d'hôte à / etc / hosts après les entrées "127.0.0.1 localhost" et ":: 1 localhost" - avec et sans le suffixe '.local'):

https://docs.micronaut.io/latest/guide/index.html#problems

Jvm prend beaucoup de temps pour résoudre l'adresse IP de l'hôte local

sans chance. J'ai redémarré ma machine après les modifications apportées à / etc / hosts.

La résolution du nom d'hôte ne semble pas être le problème cependant; Je l'ai testé avec le inetTester.jar mentionné dans le lien ci-dessus (téléchargez ici: https://github.com/thoeni/inetTester ), cela ne prend que 6ms. Je suppose que ça doit être autre chose.

(D'un autre côté, tous ceux qui ont eu des problèmes avec le temps de démarrage de l'application micronaut (ce que je n'ai pas) sur macOS, et l'ont corrigé en ajoutant le nom d'hôte à / etc / hosts, mentionnent également ce même délai d'environ 75 secondes - cela ne peut pas vraiment une coïncidence?)

Fichier journal

Les deux lignes du fichier journal, avant et après la pause de 75 secondes:

server = ApplicationContext.run(EmbeddedServer.class);

Et un peu de contexte:

package hello;

import io.micronaut.http.HttpStatus;
import io.micronaut.http.client.RxHttpClient;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;

import static org.junit.jupiter.api.Assertions.assertEquals;

@MicronautTest
public class HelloControllerTest {

    @Inject
    EmbeddedServer embeddedServer;

    @Test
    public void testIndex() throws Exception {
        // or (instead of the @Inject): 
        // EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer.class);

        try(RxHttpClient client = embeddedServer.getApplicationContext().createBean(RxHttpClient.class, embeddedServer.getURL())) {
            assertEquals(HttpStatus.OK, client.toBlocking().exchange("/hello").status());
        }
    }
}


7 commentaires

Cela semble définitivement être le même problème. Je m'assurerais que vous avez correctement édité le fichier hosts. Vous pouvez faire un test simple en utilisant le projet dans la réponse SO que vous avez liée pour vérifier avec certitude si c'est le problème ou non.


J'ai vérifié mes modifications dans le fichier / etc / hosts et mis à jour ma question. Rien ne peut vraiment se tromper là-bas, j'ai un fichier hosts simple mort avec seulement les entrées "127.0.0.1 localhost" et ":: 1 localhost" et "255.255.255.255 broadcasthost" et rien d'autre. Je l'ai testé avec et sans l'entrée "255.255.255.255 broadcasthost". Également testé la résolution du nom d'hôte avec l'outil inetTester.jar mentionné et cela ne prend qu'environ 6 ms. Le démarrage d'EmbeddedServer prend encore 75 secondes ...


"L'application" Hello World! "Démarre rapidement (environ une seconde). Cependant, le test JUnit démarre un EmbeddedServer:" L'application typique de Hello World démarre également un serveur intégré


Merci. Reformulé la question.


@TikusKucing une solution à ce sujet?


@GAlexMES Pas encore de solution


@GAlexMES regarde ma réponse - cela m'a aidé.


4 Réponses :


0
votes

J'ai eu le même problème où dans mon cas, c'était 2 minutes et 20 secondes d'attente. Une solution simple consiste à spécifier un port de serveur dans la configuration de l'application Micronaut comme suit:

micronaut:
  server:
    host: localhost
    port: 8080

Mais cela ne fonctionnera pas lorsque vous souhaitez exécuter plusieurs tests à la fois.

Je pense que le problème est causé par la recherche de tout port disponible implémenté dans SocketUtils.findAvailableTcpPort() et exécuté dans le constructeur de la classe NettyHttpServer lorsqu'aucun port n'est spécifié et que l'environnement est Environment.TEST .

Mise à jour: d' après mon expérience, le problème n'apparaît que sur certains réseaux. Par exemple, je n'ai aucun problème dans mon réseau domestique mais j'ai eu ce problème dans un réseau d'hôtel. La recherche de nom de domaine peut probablement influencer cela - alors pourquoi ne pas essayer de changer de serveur DNS?


4 commentaires

Merci. J'ai maintenant ce comportement: [A] test unitaire d'IntelliJ: la méthode de test et la classe de test prennent 75 sec. [Un '] test unitaire d'IntelliJ, avec votre ajout à application.yml: la méthode de test réussit en <1 sec, la classe s'exécute toujours pendant 75 secondes. Lorsque (après 75 secondes) le prochain test unitaire de la suite démarre, j'obtiens "NettyHttpServer - Impossible de démarrer le serveur. Port déjà utilisé 8080." [B] et [B '] "mvn clean test" depuis IntelliJ: même comportement que [A] et [A'] [C] et [C '] "mvn clean test" depuis le terminal: méthode de test et classe de test finissent dans secondes.


Donc, mon problème de 75 secondes est apparemment un problème IntelliJ. Avec ou sans votre ajout à application.yml, dans IntelliJ (maven ou non) le test prend 75 secondes, mais avec maven d'un terminal (bash) cela fonctionne très bien. Tant que je n'ai pas compris pourquoi exécuter des tests micronaut à partir d'IntelliJ est si lent, je vais simplement exécuter les suites de tests à partir de la ligne de commande.


Le "port déjà utilisé 8080" est bien sûr un problème complètement différent. Je dois découvrir comment arrêter le @Injected EmbeddedServer avant la fin de la classe de test unitaire.


Vous avez raison, ce n'est pas une bonne solution lorsque vous devez exécuter toute la suite et avoir un port différent pour chaque test. Il n'est applicable que pour une seule exécution de test. C'est fou qu'aujourd'hui c'est rapide pour moi aussi sans préciser le port. Le vrai est que j'ai redémarré le système après environ un mois. Quelle version de Java et quel système d'exploitation utilisez-vous?



0
votes

cela semble provenir du réseau. quand j'ai branché mon câble et mon wifi, j'avais ça:

12:34:31.324 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [test]
12:34:32.061 [main] WARN  i.netty.util.internal.MacAddressUtil - Failed to find a usable hardware address from the network interfaces; using random bytes: 11:02:e9:bf:a8:0e:df:83

et mon test s'est déroulé en 267 ms (sans environ 30 s)


0 commentaires

0
votes

J'ai eu un problème similaire où l'image native compilée prenait plus de 40 secondes pour démarrer. Le problème dans mon cas était la détection de l'environnement, la désactivation a résolu mon problème. Je l'ai fait en code, vous pouvez le faire via les propriétés comme expliqué dans leur documentation.

fun main(args: Array<String>) {
            Micronaut.build()
                .packages("com.example")
                .deduceEnvironment(false)  // this line did the trick
                .mainClass(Application.javaClass)
                .start()
        }


0 commentaires

0
votes

Pour quiconque vient avec le même problème pour moi, seule l'édition des hôtes le corrige. Pour moi, le démarrage normal dure entre 1,6 et 6 à 8 secondes selon ce qui se trouve dans le fichier hosts /etc/hosts .

127.0.0.1 localhost -> démarrage 6-8s

127.0.0.1 localhost MacBook-Pro.local -> Démarrage 1.6s.

Donc, ajoutez simplement $ hostname à votre route 127.0.0.1 dans le fichier hosts.


0 commentaires