El equipo de migración de Spring para GraalVM lanzó recientemente su primer lanzamiento importante, Spring Native Beta. Junto con los creadores de GraalVM, pudieron corregir muchos errores tanto en el compilador como en la primavera. Ahora el proyecto tiene soporte oficial, su propio ciclo de lanzamiento y puedes sentirlo.
El obstáculo más importante al migrar código de JVM a binarios es el problema de usar chips inherentes solo en java: reflexión, trabajo con classpath, carga dinámica de clases, etc.
Según la documentación, las diferencias clave entre una JVM normal y una implementación nativa son las siguientes:
El análisis estático de toda la aplicación se realiza en el momento de la compilación.
Los componentes no utilizados se eliminan durante el montaje.
La reflexión, los recursos y los proxies dinámicos solo se pueden configurar con configuraciones adicionales.
En el momento de la compilación, todos los componentes se fijan en Classpath.
Sin carga diferida de la clase: al cargar, todo lo que viene en los ejecutables se cargará en la memoria. Por ejemplo, para que la llamada a Class.forName ("myClass") funcione correctamente, debe tener myClass en el archivo de configuración. Si no se encuentra ninguna clase en el archivo de configuración que se solicita para cargar dinámicamente la clase, se lanzará una ClassNotFoundException
Parte del código se ejecutará en el momento de la compilación para vincular correctamente los componentes. Por ejemplo, pruebas.
, , , - .
Spring AOT, Graal VM .
Spring AOT native-image.properties
, reflection-config.json
, proxy-config.json
resource-config.json
.
Graal VM , META-INF/native-image
.
, Spring AOT. maven spring-aot-maven-plugin
, gradle - spring-aot-gradle-plugin.
, gradle :
plugins {id 'org.springframework.experimental.aot' version '0.9.0'}
, , .
, , . , .
, WebClient
org.springframework.nativex.hint
, :
@TypeHint(types = Data.class, typeNames = "com.example.webclient.Data$SuperHero")
@SpringBootApplication
public class WebClientApplication {
// ...
}
, Data
, SuperHero
. , .
graavlvm , java.lang.reflect.Proxy
@ProxyHint
.
, , :
@ProxyHint(types = {
org.hibernate.Session.class,
org.springframework.orm.jpa.EntityManagerProxy.class
})
- , @ResourceHint.
, :
@ResourceHint(patterns = "com/mysql/cj/TlsSettings.properties")
/ , @InitializationHint:
@InitializationHint(types = org.h2.util.Bits.class,
initTime = InitializationTime.BUILD)
, @NativeHint
:
@Repeatable(NativeHints.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface NativeHint
, , :
@NativeHint(
trigger = Driver.class,
options = "--enable-all-security-services",
types = @TypeHint(types = {
FailoverConnectionUrl.class,
FailoverDnsSrvConnectionUrl.class,
// ...
}), resources = {
@ResourceHint(patterns = "com/mysql/cj/TlsSettings.properties"),
@ResourceHint(patterns = "com.mysql.cj.LocalizedErrorMessages",
isBundle = true)
})
, , classpath .
Graal VM Spring AOT.
Spring Native , start.spring.io. JPA spring , CRUD . Graal VM , BP_NATIVE_IMAGE_BUILD_ARGUMENTS
Spring AOT, Buildpacks, “<buildArgs>
” pom.xml
, native-image-maven-plugin
.
En realidad, ejecutamos los comandos mvn spring-boot: build-image o gradle bootBuildImage
- y comenzará la construcción de la imagen. Cabe destacar que el colector necesita más de 7 GB de memoria, para que el montaje se haya completado con éxito. En mi máquina, el montaje, junto con la descarga de las imágenes, no tomó más de 5 minutos. Al mismo tiempo, la imagen resultó ser muy compacta, solo 60 MB. ¡La aplicación se inició en 0.022 segundos! Este es un resultado increíble. Teniendo en cuenta que cada vez más empresas se están cambiando a K8 y están iniciando una aplicación, además de que los recursos utilizados son muy importantes en el mundo moderno, esta tecnología permite que Spring se convierta en el marco número uno para todo tipo de microservicios, incluso para las implementaciones de FaaS. donde la velocidad en frío es muy importante.