El paquete jar para su proyecto SpringBoot es delgado y delgado. Los tutoriales buscados en línea no se han utilizado.

Adelgace el paquete jar para su proyecto SpringBoot


El método de empaquetado predeterminado de Spring Boot es el paquete de dependencia completa (también conocido como paquete fat), que no solo es lento en empaquetado, sino también de gran tamaño y lento en transmisión. Hoy te enseñaré cómo adelgazar Spring Boot.

Antecedentes
Ahora la arquitectura de microservicios se está volviendo cada vez más popular y es común tener más de 10 módulos de servicio basados ​​en Spring Boot para un proyecto. Suponiendo que un módulo de servicio empaquetado en un paquete jar tiene 100M, es posible que una versión completa requiera cargar un archivo 1G. Puede que no se sienta mucho cuando la situación de la red es buena, pero si es necesario copiar el código a la intranet para su publicación o cargarlo en algunos servidores externos, afectará seriamente la eficiencia del trabajo.

Entonces, ¿hay alguna forma de reducir el tamaño del paquete de bota de primavera que escribimos?
La respuesta es sí, a través de configuraciones relevantes, cuando se empaqueta Spring Boot, solo se cargan algunos paquetes de dependencia que cambian con frecuencia, como el módulo común del proyecto, algunos módulos API que llaman a la interfaz fingida y esos paquetes de dependencia fijos se cargan directamente. al servidor En el directorio especificado, puede especificar el directorio cargado por el paquete lib a través del comando cuando se inicia el proyecto. De esta manera, el paquete jar que escribimos tiene menos de unos pocos M como máximo, lo que reduce en gran medida el tamaño del paquete jar del proyecto Spring Boot y mejora la eficiencia de la publicación y el lanzamiento.

Suplemento:
fat jar: Fat jar, el paquete jar de salida contiene todos los paquetes dependientes.
La ventaja es que se puede ejecutar directamente sin agregar otros comandos, la desventaja es que el volumen es demasiado grande y la transmisión es difícil.

**thin jar:** es un paquete ligero. El paquete jar de salida solo contiene algunos paquetes dependientes que cambian con frecuencia, que generalmente son módulos públicos en el proyecto o algunos módulos dependientes de la interfaz API.
La ventaja es que el tamaño es pequeño, lo que favorece la eficiencia del lanzamiento del proyecto;
la desventaja es que los paquetes de dependencia externos pueden tener riesgos de seguridad. Si las dependencias maven del proyecto cambian con frecuencia, será más problemático mantener el lib en el servidor, lo que no favorece la ubicación del problema.

Ejercicio de adelgazamiento
1. Modificar los parámetros de empaquetado de maven

<build>
ᅠ ᅠ ᅠ ᅠ <plugins>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ <plugin>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ <groupId>org.springframework.boot</groupId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ <artifactId>spring-boot-maven-plugin</artifactId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ <configuration>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ <layout>ZIP</layout>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<includes>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<include>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<groupId>nothing</groupId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<artifactId>nothing</artifactId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ</include>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<include>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<groupId>com.huacloud.tax.rpc</groupId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ<artifactId>common</artifactId>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ</include>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ</includes>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ </configuration>
ᅠ ᅠ ᅠ ᅠ ᅠ ᅠ </plugin>
ᅠ ᅠ ᅠ ᅠ </plugins>
ᅠ ᅠ </build>



ilustrar:

El diseño
se utiliza para configurar el tipo de clase principal en el paquete jar ejecutable. Aquí debe configurarse en ZIP, de modo que la clase principal en el paquete jar escrito sea PropertiesLauncher.

include
deberá conservar el paquete jar, de acuerdo con groupId y artefactoId (tenga en cuenta que ambos son obligatorios) include.
Nothing representa paquetes dependientes no existentes, lo que significa que no se introducen paquetes dependientes en
el módulo de servicio público importado en común.

2. Ejecute el paquete maven
Primero ejecute mvn clean, luego ejecute el paquete mvn

Copie el paquete empaquetado en el directorio de destino al directorio D:\web y cámbiele el nombre a tax-ws-thin-zip.jar.

Vea el archivo MANIFEST.MF en el directorio META-INF en tax-ws-thin-zip.jar a través de la herramienta de descompresión:

Se descubre que el valor de Main-Class de hecho ha cambiado a PropertiesLauncher, lo que indica que nuestra configuración fue exitosa.
(En cuanto a por qué es necesario configurar Main-Class como PropertiesLauncher, lo presentaré más adelante)

3. Compare el volumen de FatJar y ThinJar:

Se puede encontrar que el volumen del paquete delgado tax-ws-thin.jar es mucho menor que el del paquete grueso.

4. Copie el paquete lib del paquete fatJar al directorio D:\web

5. Inicie el paquete jar mediante comando

D:\web>java -Dloader.path="D:\web\lib" -jar tax-ws-thin.jar
1
Configure la ruta de carga del paquete de dependencia externa a través del parámetro de inicio loader.path.

El inicio exitoso del proyecto indica que la carga del paquete de dependencia subcontratado que configuramos ha tenido efecto.

Exploración de principios
¿Por qué configurar la clase principal del paquete jar ejecutable en PropertiesLauncher puede especificar la ruta de carga del paquete dependiente configurando el parámetro de inicio loader.path?
En primer lugar, comprendemos el Lanzador en el principio de implementación del paquete jar ejecutable Spring Boot.

Lo siguiente es un extracto del sitio web oficial de Spring Boot:
La clase org.springframework.boot.loader.Launcher es una clase de arranque especial que se utiliza como punto de entrada principal para el archivo ejecutable. Es la clase principal real en el archivo jar la que establece el URLClassLoader apropiado y finalmente llama al método main().

Hay tres subclases de lanzadores (JarLauncher, WarLauncher y PropertiesLauncher). Su propósito es cargar recursos (archivos .class, etc.) desde archivos jar anidados o archivos war en directorios (en lugar de archivos explícitamente en el classpath). Para JarLauncher y WarLauncher, las rutas anidadas son fijas. JarLauncher se encuentra en BOOT-INF/lib/, mientras que WarLauncher se encuentra en WEB-INF/lib/ y WEB-INF/lib-provided/. Se pueden agregar frascos adicionales en estas ubicaciones si lo desea. De forma predeterminada, PropertiesLauncher busca en BOOT-INF/lib/ en el archivo de su aplicación. Puede agregar ubicaciones adicionales configurando una variable de entorno llamada LOADER_PATH o loader.path en loader.properties (que es una lista separada por comas de directorios, archivos o directorios dentro de un archivo).
———————————————

Es decir, el lanzador Launcher carga recursos dependientes para el inicio del proyecto. Hay 3 lanzadores (JarLauncher, WarLauncher y PropertiesLauncher). Las rutas para que JarLauncher y WarLauncher carguen recursos son fijas y PropertiesLauncher puede usar la variable de entorno loader.path. .Especifica dónde cargar los recursos.


Descripción del valor del atributo de diseño:

JAR, el jar ejecutable habitual
Main-Class: org.springframework.boot.loader.JarLauncher

WAR, la guerra ejecutable habitual, requiere dependencias de contenedores de servlets ubicadas en la
clase principal: org.springframework.boot.loader.warLauncher

ZIP, es decir, DIR, es similar a JAR
Main-Class: org.springframework.boot.loader.PropertiesLauncher
(solo recuerde esto, hay menos escenarios de aplicación adicionales)

Configuración del atributo PropertiesLauncher

PropertiesLauncher tiene algunas características especiales que se pueden habilitar a través de propiedades externas (propiedades del sistema, variables de entorno, entradas de manifiesto o loader.properties). La siguiente tabla describe estas propiedades:

Propósito clave
La ruta de carga del paquete loader.path lib
loader.home se utiliza para resolver la ruta relativa en loader.path. Por ejemplo, dado loader.path = lib, entonces ${loader.home}/lib es la ubicación de la ruta de clases (y todos los archivos jar en ese directorio). Esta propiedad también se utiliza para buscar el archivo loader.properties, como se muestra en el ejemplo /opt/app a continuación. El valor predeterminado es ${user.dir}.
loader.args Argumentos predeterminados para el método principal (separados por espacios).
loader.main El nombre de la clase principal a iniciar (por ejemplo, com.app.Application)
loader.config.name La ruta al archivo de propiedades (por ejemplo, classpath:loader.properties). El valor predeterminado es loader.properties.
loader.system Bandera booleana que indica que todas las propiedades deben agregarse a las propiedades del sistema. El valor predeterminado es falso.
Para obtener más información, puede ver la documentación del sitio web oficial sobre el paquete jar ejecutable Spring Boot: The Executable Jar Format

Corrección de trampa
He visto un método en Internet antes que no configura el diseño = ZIP, pero después de empaquetarlo directamente en un paquete delgado, use -Djava.ext.dirs para especificar la ruta de carga del paquete de dependencia externa en el comando de inicio .

D:\web>java -Djava.ext.dirs="D:\web\lib" -jar tax-ws-thin.jar
1
Análisis del principio:
-Djava.ext.dirs anulará la configuración ext del propio Java, java El directorio especificado por ext.dirs es cargado por el cargador ExtClassLoader. Si su programa no especifica esta propiedad del sistema, el cargador carga todos los archivos jar en el directorio $JAVA_HOME/jre/lib/ext de forma predeterminada. Pero si especifica manualmente las propiedades del sistema y olvida agregar la ruta $JAVA_HOME/jre/lib/ext, entonces ExtClassLoader no cargará los archivos jar en $JAVA_HOME/lib/ext, lo que significa que perderá algunas funciones, por ejemplo, Se implementa el algoritmo de cifrado y descifrado que viene con Java.

Por lo tanto, modificar directamente a la fuerza la ruta de carga del cargador de clases de extensión predeterminado de Java a través de este método de escritura puede generar fácilmente algunos problemas. Es mejor no usarlo casualmente.

El problema de que no se puede encontrar el paquete de controladores de Oracle
Al usar -Djava.ext.dirs para configurar la ruta de carga del paquete de dependencia externa, existe el problema de que no se puede cargar el paquete de controladores de Oracle. En este momento, debe agregar
-Doracle.jdbc.thinLogonCapability=o3, configura la compatibilidad de inicio de sesión de Oracle

Expansión: mecanismo de delegación parental
Aquí, en términos de expansión, se trata del mecanismo de carga de delegación parental de Java.


1. BootStrapClassLoader: cargador de clases Bootstrap, el ClassLoader se crea en el momento del arranque y está escrito en el kernel JVM. No es un archivo de código de bytes, sino un código binario escrito en C ++, por lo que los desarrolladores no pueden obtener el cargador de clases bootstrap Una referencia a una clase no puede ser manipulado por referencia. Este cargador carga la biblioteca de clases en $JAVA_HOME/jre/lib (o especificada por el parámetro -Xbootclasspath).

2. EXTClassLoader: cargador de clases extendido, ExtClassLoader cargará la biblioteca de clases en $JAVA_HOME/jre/lib/ext (o especificada por el parámetro -Djava.ext.dirs).

3. AppClassLoader: el cargador de aplicaciones cargará la biblioteca de clases en la ruta especificada por la variable de entorno Java CLASSPATH, y la ruta especificada por CLASSPATH se puede obtener a través de Systemn.getProperty ("java.class.path"), que se puede sobrescribir .

4. CustomClassLoader: el cargador personalizado es el CLassLoader definido por el usuario, por ejemplo, el StandardClassLoader de Tomcat pertenece a esta categoría.

Mecanismo de delegación principal de ClassLoader:
1. Cuando APPClassLoader carga una clase, no cargará la clase por sí mismo primero, sino que delegará la solicitud de carga de clases al cargador de clases principal EXTClassloader para que la complete.

2. Cuando EXTClassLoader carga una clase, no intentará cargar la clase primero, sino que delegará la solicitud de carga de clase a BootStrapClassLoader para que la complete.

3. Si BottStrapClassLoader no se carga, utilizará EXTClassLoader para intentar cargar.

4. Si EXTClassLoader tampoco se carga, utilizará APPClassLoader para cargar. Si APPClassLoader tampoco se carga, informará una ClassNotFundException anormal.

Resumen
1. ¿Por qué es necesario reducir el paquete jar ejecutable para el proyecto Spring Boot?
2. Descripción de los tres tipos de lanzadores para Spring Boot.
3. Cómo configurar el lanzador PropertiesLauncher para cargar dependencias externas.
4. Señalar eso al especificar -Djava.ext. El parámetro dirs se da cuenta del problema de la carga del paquete de dependencia externa
5. La extensión explica el mecanismo de carga de delegación principal de Java
6. La solución al problema de que el paquete de dependencia externa no se puede cargar con el paquete del controlador de Oracle

Finalmente,
gracias por su reciente apoyo. Aunque aprender es asunto mío, es realmente alentador ver los me gusta, comentarios e inquietudes de todos. Gracias.
Continuaré trabajando duro para compartir más artículos técnicos de alta calidad y espero comunicarme y crecer con todos.

Más emocionante, sígueme.

————————————————
Declaración de derechos de autor: este artículo es el artículo original del blogger de CSDN "Dou Zhe_2013", siguiendo el acuerdo de derechos de autor CC 4.0 BY-SA, adjunte el enlace de la fuente original para reimpresión y esta declaración.
Enlace original: https://blog.csdn.net/w1014074794/article/details/106445145

Supongo que te gusta

Origin blog.csdn.net/qq_22905801/article/details/129800023
Recomendado
Clasificación