Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Hallo iedereen op deze blog, hier is het vierde bericht in de Quarkus-serie!

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Vorige bericht ging over hoe Quarkus MicroProfile en Spring combineert. Laten we dat in herinnering brengen kwark is gepositioneerd als “ultrasnel subatomair Java”, oftewel “Kubernetes-georiënteerde Java-stack, op maat gemaakt voor GraalVM en OpenJDK HotSpot en samengesteld uit de beste bibliotheken en standaarden.” Vandaag zullen we aan de hand van het voorbeeld laten zien hoe u bestaande Java-applicaties kunt moderniseren met behulp van de mogelijkheden van Quarkus helloworld-applicaties uit de Red Hat JBoss Enterprise Application Platform (JBoss EAP) Quickstart-repository, dat gebruikmaakt van CDI- en Servlet 3-technologieën die worden ondersteund door Quarkus.

Het is belangrijk op te merken dat zowel Quarkus als JBoss EAP de nadruk leggen op het gebruik van tools die zo veel mogelijk op standaarden zijn gebaseerd. Heeft u geen applicatie die op JBoss EAP draait? Geen probleem, het kan eenvoudig worden gemigreerd van uw huidige applicatieserver naar JBoss EAP Red Hat applicatiemigratietoolkit. Daarna zal de definitieve en werkende versie van de gemoderniseerde code beschikbaar zijn in de repository github.com/mrizzi/jboss-eap-quickstarts/tree/quarkus, in de module Hallo Wereld.

Bij het schrijven van dit bericht hebben we gebruikt Quarkus-handleidingen, eigenlijk Uw eerste toepassing maken en Gebouw A Native uitvoerbaar bestand.

Laten we de code pakken

Laten we eerst een lokale kloon van de repository maken JBoss EAP-snelstartgidsen:

$ git clone https://github.com/jboss-developer/jboss-eap-quickstarts.git
Cloning into 'jboss-eap-quickstarts'...
remote: Enumerating objects: 148133, done.
remote: Total 148133 (delta 0), reused 0 (delta 0), pack-reused 148133
Receiving objects: 100% (148133/148133), 59.90 MiB | 7.62 MiB/s, done.
Resolving deltas: 100% (66476/66476), done.
$ cd jboss-eap-quickstarts/helloworld/

Laten we eens kijken hoe de originele helloworld werkt

Eigenlijk blijkt de essentie van deze applicatie duidelijk uit de naam, maar we zullen de code strikt wetenschappelijk moderniseren. Laten we daarom eerst deze applicatie in zijn oorspronkelijke vorm bekijken.

Hallo wereld implementeren

1. Open een terminal en ga naar de hoofdmap van de JBoss EAP-map (u kunt deze downloaden hier), dat wil zeggen naar de map EAP_HOME.

2. Start de JBoss EAP-server met het standaardprofiel:

$ EAP_HOME/bin/standalone.sh

Opmerking: op Windows Het script EAP_HOMEbinstandalone.bat wordt gebruikt om het programma te starten.

Na een paar seconden zou zoiets in het logboek moeten verschijnen:

[org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) started in 3315ms - Started 306 of 527 services (321 services are lazy, passive or on-demand)

3. Openen in een browser 127.0.0.1:8080 en we zien dit:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 1. JBoss EAP-startpagina.

4. Volg de instructies in de handleiding Bouw en implementeer de Quickstart: vouw helloworld uit en voer (vanuit de hoofdmap van het project) de volgende opdracht uit:

$ mvn clean install wildfly:deploy

Nadat we deze opdracht succesvol hebben uitgevoerd, zien we in het logboek zoiets als het volgende:

[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 8.224 s

De eerste implementatie van de helloworld-applicatie op JBoss EAP duurde dus iets meer dan 8 seconden.

Hallo wereld testen

Strikt volgens de instructies handelen Toegang tot de applicatie, openen in de browser 127.0.0.1:8080/helloworld en we zien dit:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 2. Origineel Hello World van JBoss EAP.

Veranderingen maken

Wijzig de invoerparameter createHelloMessage(String name) van World in Marco:

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Voer de volgende opdracht opnieuw uit:

$ mvn clean install wildfly:deploy

Vervolgens vernieuwen we de pagina in de browser en zien we dat de tekst is gewijzigd:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 3. Hallo Marco in JBoss EAP.

Draai de helloworld-implementatie terug en sluit JBoss EAP af

Dit is optioneel, maar als u de implementatie wilt annuleren, kunt u dit doen met de volgende opdracht:

$ mvn clean install wildfly:undeploy

Om uw JBoss EAP-instantie af te sluiten, drukt u eenvoudigweg op Ctrl+C in het terminalvenster.

Hallo wereld upgraden

Laten we nu de originele helloworld-applicatie moderniseren.

Maak een nieuwe tak aan

We maken een nieuwe werkvertakking nadat het quickstartproject is voltooid:

$ git checkout -b quarkus 7.2.0.GA

Het pom.xml-bestand wijzigen

We beginnen met het wijzigen van de applicatie vanuit het pom.xml-bestand. Om Quarkus toe te staan ​​XML-blokken erin in te voegen, voert u de volgende opdracht uit in de map helloworld:

$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create

Bij het schrijven van dit artikel is versie 0.23.2 gebruikt. Quarkus brengt regelmatig nieuwe versies uit, op de website kunt u zien welke versie de nieuwste is github.com/quarkusio/quarkus/releases/latest.

Met het bovenstaande commando worden de volgende elementen in pom.xml ingevoegd:

  • Eigendom , waarin wordt aangegeven welke versie van Quarkus moet worden gebruikt.
  • Blok om Quarkus BOM (stuklijst) te importeren, om niet voor elke Quarkus-afhankelijkheid een versie toe te voegen.
  • De quarkus-maven-plug-in is verantwoordelijk voor het verpakken van de applicatie en het bieden van de ontwikkelingsmodus.
  • Het native profiel voor het maken van uitvoerbare toepassingen.

Daarnaast brengen we handmatig de volgende wijzigingen aan in pom.xml:

  1. Het label eruit trekken van het blok en plaats deze boven de tag . Omdat we in de volgende stap de blokkade verwijderen , dan moet je opslaan .
  2. Een blok verwijderen , omdat deze applicatie bij gebruik met Quarkus niet langer een parent-pom van JBoss nodig heeft.
  3. Voeg een tag toe en plaats deze onder de tag . U kunt het gewenste versienummer opgeven.
  4. Het label verwijderen , aangezien deze applicatie niet langer een WAR is, maar een gewone JAR.
  5. We wijzigen de volgende afhankelijkheden:
    1. Wijzig de afhankelijkheid javax.enterprise:cdi-api in io.quarkus:quarkus-arc en verwijder mits , omdat (volgens de documenten) deze Quarkus-extensie injectie van CDI-afhankelijkheden biedt.
    2. Wijzig de afhankelijkheid org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec in io.quarkus:quarkus-undertow en verwijder mits , omdat (volgens de documenten) deze Quarkus-extensie ondersteuning biedt voor servlets.
    3. We verwijderen de org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec-afhankelijkheid, omdat deze wordt geleverd met de afhankelijkheden die we zojuist hebben gewijzigd.

De versie van het pom.xml-bestand met alle wijzigingen bevindt zich op github.com/mrizzi/jboss-eap-quickstarts/blob/quarkus/helloworld/pom.xml.

Merk op dat de bovenstaande opdracht mvn io.quarkus:quarkus-maven-plugin:0.23.2:create niet alleen het bestand pom.xml wijzigt, maar ook een aantal componenten aan het project toevoegt, namelijk de volgende bestanden en mappen:

  • Het bestand mvnw en mvnw.cmd en de map .mvn: Met Maven Wrapper kunt u Maven-projecten van een bepaalde Maven-versie uitvoeren zonder die versie te installeren.
  • Docker-map (in de map src/main/): Deze bevat voorbeeld Docker-bestanden voor native en jvm-modi (samen met het .dockerignore-bestand).
  • Map Resources (in de map src/main/): Deze bevat een leeg bestand application.properties en een voorbeeld van een Quarkus index.html-startpagina (zie De gemoderniseerde helloworld uitvoeren voor meer details).

Lanceer Hallo Wereld
Om de applicatie te testen gebruiken we quarkus:dev, waarmee Quarkus in de ontwikkelingsmodus wordt gestart (voor meer details, zie dit gedeelte in de handleiding Ontwikkelmodus).

Opmerking: Deze stap zal naar verwachting resulteren in een fout, omdat we nog niet alle noodzakelijke wijzigingen hebben aangebracht.

Laten we nu de opdracht uitvoeren om te zien hoe het werkt:

$ ./mvnw compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[INFO] Building Quickstart: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Listening for transport dt_socket at address: 5005
INFO  [io.qua.dep.QuarkusAugmentor] Beginning quarkus augmentation
INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Final
ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default]
	- java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- declared on CLASS bean [types=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], qualifiers=[@Default, @Any], target=org.jboss.as.quickstarts.helloworld.HelloWorldServlet]
	at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:841)
	at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:214)
	at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:106)
	at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:249)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:780)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:415)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
	at java.lang.Thread.run(Thread.java:748)
	at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default]
	- java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- declared on CLASS bean [types=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], qualifiers=[@Default, @Any], target=org.jboss.as.quickstarts.helloworld.HelloWorldServlet]
	at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:428)
	at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:371)
	at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:206)
	... 14 more

Het werkt dus niet... Waarom?

De UnsatisfiedResolutionException verwijst naar de klasse HelloService, die lid is van de klasse HelloWorldServlet (java-lid: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Het probleem is dat HelloWorldServlet een geïnjecteerde instantie van HelloService nodig heeft, en deze kan niet worden gevonden (ook al zitten beide klassen in hetzelfde pakket).

Het is tijd om naar terug te keren documentatie en lees hoe het werkt in Quarkus Injecteren, en daarom Contexten en afhankelijkheidsinjectie (CDI). Open daarom de handleiding Contexten en afhankelijkheidsinjectie en in de sectie Ontdekking van bonen lezen we: “Een bonenklasse die geen bonendefiniërende annotatie heeft, wordt niet doorzocht.”

Laten we eens kijken naar de HelloService-klasse: deze heeft echt niet zo'n annotatie. Daarom moet het worden toegevoegd zodat Quarkus de boon kan zoeken en vinden. En aangezien dit een staatloos object is, kunnen we eenvoudig de annotatie @ApplicationScoped als volgt toevoegen:

@ApplicationScoped
public class HelloService {

Opmerking: hier kan de ontwikkelomgeving u vragen om het vereiste pakket toe te voegen (zie onderstaande regel), en u zult dit handmatig moeten doen, zoals dit:

import javax.enterprise.context.ApplicationScoped;

Als u twijfelt over welke scope moet worden gebruikt als deze helemaal niet is gespecificeerd voor de bronbean, lees dan de documentatie JSR 365: Contexten en afhankelijkheidsinjectie voor Java 2.0: standaardbereik.

Nu proberen we opnieuw de applicatie te starten met het commando ./mvnw compile quarkus:dev:

$ ./mvnw compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[INFO] Building Quickstart: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Listening for transport dt_socket at address: 5005
INFO  [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
INFO  [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 576ms
INFO  [io.quarkus] (main) Quarkus 0.23.2 started in 1.083s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile dev activated. Live Coding activated.
INFO  [io.quarkus] (main) Installed features: [cdi]

Nu gaat alles zonder fouten.

Lancering van de gemoderniseerde helloworld
Zoals geschreven in het log, open het in de browser 0.0.0.0:8080 (de standaard Quarkus-startpagina) en we zien dit:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 4. Quarkus dev-startpagina.

De WebServlet-annotatie voor deze toepassing bevat de volgende contextdefinitie:

@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {

Daarom gaan we in de browser naar 0.0.0.0:8080/HelloWorld en we zien het volgende:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 5: De Quarkus-ontwikkelaarspagina voor de Hello World-applicatie.

Nou ja, alles werkt.

Laten we nu wijzigingen in de code aanbrengen. Merk op dat de opdracht ./mvnw compile quakus:dev nog steeds actief is en dat we niet van plan zijn deze te stoppen. Laten we nu proberen dezelfde - zeer triviale - wijzigingen in de code zelf toe te passen en kijken hoe Quarkus het leven gemakkelijker maakt voor de ontwikkelaar:

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Sla het bestand op en vernieuw vervolgens de webpagina om Hallo Marco te zien, zoals weergegeven in de onderstaande schermafbeelding:

Quarkus: Applicatiemodernisering met Helloworld als voorbeeld uit JBoss EAP Quickstart

Rijst. 6. Hallo Marco-pagina in Quarkus dev.

Laten we nu de uitvoer in de terminal controleren:

INFO  [io.qua.dev] (vert.x-worker-thread-3) Changed source files detected, recompiling [/home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/src/main/java/org/jboss/as/quickstarts/helloworld/HelloWorldServlet.java]
INFO  [io.quarkus] (vert.x-worker-thread-3) Quarkus stopped in 0.003s
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Beginning quarkus augmentation
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Quarkus augmentation completed in 232ms
INFO  [io.quarkus] (vert.x-worker-thread-3) Quarkus 0.23.2 started in 0.257s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (vert.x-worker-thread-3) Profile dev activated. Live Coding activated.
INFO  [io.quarkus] (vert.x-worker-thread-3) Installed features: [cdi]
INFO  [io.qua.dev] (vert.x-worker-thread-3) Hot replace total time: 0.371s

Het vernieuwen van de pagina veroorzaakte de detectie van wijzigingen in de broncode en Quarkus voerde automatisch een stop-startprocedure uit. En dit alles werd voltooid in slechts 0.371 seconden (hier is het, dat “ultrasnelle subatomaire Java”).

Helloworld inbouwen in een JAR-pakket
Nu de code naar behoren werkt, gaan we deze verpakken met de volgende opdracht:

$ ./mvnw clean package

Met deze opdracht worden twee JAR-bestanden gemaakt in de map /target: het helloworld-.jar-bestand, een standaardartefact dat door het Maven-team is samengesteld, samen met de klassen en bronnen van het project. En het helloworld-runner.jar-bestand, een uitvoerbaar JAR-bestand.

Houd er rekening mee dat dit geen uber-jar is, omdat alle afhankelijkheden eenvoudigweg worden gekopieerd naar de map /target/lib (niet verpakt in een JAR-bestand). Om deze JAR vanuit een andere map of op een andere host uit te voeren, moet u daarom zowel het JAR-bestand zelf als de map /lib daarheen kopiëren, aangezien het Class-Path-element in het bestand MANIFEST.MF in het JAR-pakket een expliciete lijst met JAR's uit lib-mappen
Raadpleeg de tutorial voor meer informatie over het maken van uber-jar-applicaties Uber-Jar-creatie.

Lanceer helloworld verpakt in JAR

Nu kunnen we onze JAR uitvoeren met behulp van de standaard Java-opdracht:

$ java -jar ./target/helloworld-<version>-runner.jar
INFO  [io.quarkus] (main) Quarkus 0.23.2 started in 0.673s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile prod activated.
INFO  [io.quarkus] (main) Installed features: [cdi]

Nadat dit allemaal is gedaan, gaat u naar uw browser op 0.0.0.0:8080 en controleer of alles naar behoren werkt.

Helloworld compileren in een eigen uitvoerbaar bestand

Onze helloworld draait dus als een zelfstandige Java-applicatie met behulp van Quarkus-afhankelijkheden. Maar u kunt verder gaan en er een eigen uitvoerbaar bestand van maken.

GraalVM installeren
Allereerst moet u hiervoor de benodigde hulpmiddelen installeren:

1. Download GraalVM 19.2.0.1 van github.com/oracle/graal/releases/tag/vm-19.2.0.1.

2. Vouw het gedownloade archief uit:

$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz

3. Ga naar de map untar.

4. Voer de onderstaande opdracht uit om de oorspronkelijke afbeelding te downloaden en toe te voegen:

$ ./bin/gu install native-image

5. Registreer de map die in stap 2 is gemaakt in de omgevingsvariabele GRAALVM_HOME:

$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)

Zie de handleiding voor meer informatie en installatie-instructies voor andere besturingssystemen Een eigen uitvoerbaar bestand bouwen: vereisten.

Helloworld inbouwen in een eigen uitvoerbaar bestand
Het lezen van de handleiding Een eigen uitvoerbaar bestand maken: een eigen uitvoerbaar bestand maken: “Laten we nu een eigen uitvoerbaar bestand voor onze applicatie maken om de opstarttijd en schijfgrootte te verminderen. Het uitvoerbare bestand bevat alles wat nodig is om de applicatie uit te voeren, inclusief de JVM (of beter gezegd, een ingekorte versie ervan, die alleen bevat wat nodig is om de applicatie uit te voeren) en onze applicatie zelf.

Om een ​​eigen uitvoerbaar bestand te maken, moet u het oorspronkelijke Maven-profiel inschakelen:

$ ./mvnw package -Pnative

Onze build duurde één minuut en tien seconden en het laatste helloworld-runner f-bestand werd gemaakt in de map /target.

Voer het oorspronkelijke uitvoerbare bestand helloworld uit

In de vorige stap ontvingen we het uitvoerbare bestand /target/helloworld—runner. Laten we het nu uitvoeren:

$ ./target/helloworld-<version>-runner
INFO  [io.quarkus] (main) Quarkus 0.23.2 started in 0.006s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile prod activated.
INFO  [io.quarkus] (main) Installed features: [cdi]

Open het opnieuw in de browser 0.0.0.0:8080 en controleer of alles naar behoren werkt.

Wordt vervolgd!

Wij zijn van mening dat de methode voor het moderniseren van Java-applicaties met behulp van Quarkus-mogelijkheden die in dit bericht wordt besproken (zij het met een eenvoudig voorbeeld) actief in het echte leven zou moeten worden gebruikt. Als je dit doet, zul je waarschijnlijk een aantal problemen tegenkomen, die we gedeeltelijk zullen behandelen in het volgende bericht, waar we zullen praten over hoe je het geheugenverbruik kunt meten om prestatieverbeteringen te beoordelen, een belangrijk onderdeel van het hele moderniseringsproces van applicaties.

Bron: www.habr.com

Koop betrouwbare hosting voor sites met DDoS-bescherming, VPS VDS-servers 🔥 Koop betrouwbare websitehosting met DDoS-bescherming, VPS- en VDS-servers | ProHoster