Uno de los principales problemas al desarrollar y posteriormente operar microservicios es la correcta y cuidadosa configuración de sus instancias. En esto, a mi parecer, puede ayudar un nuevo marco. . Permite resolver de manera bastante elegante algunas tareas rutinarias de configuración de aplicaciones.
Si tienes muchos microservicios, y cada uno de ellos viene con su propio archivo/archivos de configuración, hay una alta probabilidad de cometer un error en uno de ellos, que sin la debida habilidad y un sistema de registro puede ser muy difícil de detectar. La tarea principal que se plantea el marco es minimizar los parámetros redundantes de configuración de la instancia, reduciendo así la probabilidad de introducir errores.
Veamos un ejemplo. Supongamos que hay una aplicación simple con un archivo de configuración. yamlEsto puede ser cualquier microservicio en cualquier lenguaje. Veamos cómo se puede aplicar el marco a este servicio.
Pero antes, para mayor comodidad, crearemos un proyecto vacío en Idea IDE, habiendo instalado previamente el complemento microconfig.io.

Configuramos la configuración de lanzamiento del complemento; se puede usar la configuración predeterminada, como en la captura de pantalla de arriba.
Nuestro servicio se llama order, entonces en el nuevo proyecto crearemos una estructura similar:

En la carpeta con el nombre del servicio colocamos el archivo de configuración - application.yaml. Todos los microservicios se ejecutan en algún entorno, por lo que, además de crear la configuración del propio servicio, es necesario describir el entorno: para esto crearemos una carpeta envs y agregaremos en ella un archivo con el nombre de nuestro entorno de trabajo. De esta manera, el marco creará archivos de configuración para los servicios en el entorno dev, ya que en la configuración del complemento se ha establecido precisamente este parámetro.
Estructura del archivo dev.yaml será bastante simple:
mainorder:
components:
- orderEl marco trabaja con configuraciones que están agrupadas. Para nuestro servicio elegiremos un nombre para el grupo mainorder. El marco encuentra cada uno de estos grupos de aplicaciones en el archivo de entornos y crea configuraciones para todos ellos que se encuentran en las carpetas correspondientes.
En el propio archivo de configuración del servicio order indiquemos por ahora solo un parámetro:
spring.application.name: orderAhora ejecutaremos el complemento, y generará la configuración necesaria para nuestro servicio según la ruta especificada en las propiedades:

Se puede y sin necesidad de instalar un plugin, simplemente descargando la distribución del framework y ejecutándolo desde la línea de comandos.
Esta solución es adecuada para su uso en un servidor de compilación.
Cabe destacar que el framework entiende perfectamente property la sintaxis, es decir, archivos de propiedades comunes que se pueden utilizar junto con yaml configuraciones.
Agreguemos otro servicio payment y al mismo tiempo complejizaremos el existente.
En order:
eureka:
instance.preferIpAddress: true
client:
serviceUrl:
defaultZone: http://192.89.89.111:6782/eureka/
server.port: 9999
spring.application.name: order
db.url: 192.168.0.100En payment:
eureka:
instance.preferIpAddress: true
client:
serviceUrl:
defaultZone: http://192.89.89.111:6782/eureka/
server.port: 9998
spring.application.name: payments
db.url: 192.168.0.100El principal problema de estas configuraciones es la gran cantidad de código repetido en la configuración de los servicios. Veamos cómo el framework puede ayudar a eliminarlo. Comencemos con lo más obvio: la presencia de la configuración eureka en la descripción de cada microservicio. Crearemos un nuevo directorio con un archivo de configuración y añadiremos una nueva configuración:

Y en cada uno de nuestros proyectos ahora añadiremos la línea #include eureka.
El framework encontrará automáticamente la configuración de eureka y la copiará en los archivos de configuración de los servicios, mientras que no se creará una configuración de eureka separada, ya que no la especificaremos en el archivo de entorno dev.yaml. El servicio order:
#include eureka
server.port: 9999
spring.application.name: order
db.url: 192.168.0.100También podemos extraer la configuración de la base de datos en una configuración separada, cambiando la línea de importación a #include eureka, oracle.
Cabe destacar que cada cambio al regenerar los archivos de configuración es rastreado por el framework y se coloca en un archivo especial junto al archivo de configuración principal. La entrada en su registro se ve así: “Stored 1 property changes to order/diff-application.yaml”. Esto permite detectar rápidamente cambios en archivos de configuración grandes.
Extraer partes comunes de la configuración ayuda a eliminar mucho código repetido innecesario, pero no permite crear configuraciones flexibles para diferentes entornos: los endpoints de nuestros servicios son únicos y están codificados, lo cual es malo. Intentemos eliminarlo.
Una buena solución sería mantener todos los endpoints en una sola configuración a la que los demás pudieran referirse. Para ello, el framework ha implementado el soporte de placeholders. Así es como cambiará el archivo de configuración eureka:
client:
serviceUrl:
defaultZone: http://${endpoints@eurekaip}:6782/eureka/Ahora veamos cómo funciona este placeholder. El sistema encuentra el componente llamado endpoints y busca en él el valor eurekaip, luego lo integra en nuestra configuración. Pero, ¿cómo manejar diferentes entornos? Para ello, crearemos un archivo de configuración en endpoints el siguiente formato application.dev.yaml. El framework, de acuerdo con la extensión del archivo, decide a qué entorno pertenece esta configuración y la carga:

Contenido del archivo dev:
eurekaip: 192.89.89.111
dbip: 192.168.0.100Podemos crear una configuración similar para los puertos de nuestros servicios:
server.port: ${ports@order}.Todas las configuraciones importantes se encuentran en un solo lugar, reduciendo así la posibilidad de errores debido a parámetros dispersos en archivos de configuración.
El framework proporciona muchos placeholders ya listos, por ejemplo, se puede obtener el nombre del directorio donde se encuentra el archivo de configuración y asignarlo:
#include eureka, oracle
server.port: ${ports@order}
spring.application.name: ${this@name}Gracias a esto, no es necesario indicar adicionalmente el nombre de la aplicación en la configuración y también se puede extraer en un módulo general, por ejemplo, en la misma eureka:
client:
serviceUrl:
defaultZone: http://${endpoints@eurekaip}:6782/eureka/
spring.application.name: ${this@name}El archivo de configuración order se reducirá a una línea:
#include eureka, oracle
server.port: ${ports@order}Si alguna configuración de la configuración principal no nos es necesaria, podemos indicarla en nuestra configuración y será la que se aplique al generar. Es decir, si por alguna razón necesitamos un nombre único para el servicio order, simplemente dejaremos el parámetro spring.application.name.
Supongamos que en el servicio es necesario agregar configuraciones de registro personalizadas, que se almacenan en un archivo separado, por ejemplo, logback.xml. Crearemos un grupo de configuraciones separado para ello:

En la configuración básica, indicaremos al framework dónde colocar el archivo de configuración de registro necesario mediante el placeholder @ConfigDir:
microconfig.template.logback.fromFile: ${logback@configDir}/logback.xmlEn el archivo logback.xml configuramos los appenders estándar, que a su vez pueden contener placeholders, que el framework modificará durante la generación de configuraciones, por ejemplo:
logs/${this@name}.logAl agregar en la configuración de los servicios la importación logback, automáticamente obtenemos el registro configurado para cada servicio:
#include eureka, oracle, logback
server.port: ${ports@order}Es hora de familiarizarnos más a fondo con todos los placeholders disponibles en el framework:
${this@env} — devuelve el nombre del entorno actual.
${…@name} — devuelve el nombre del componente.
${…@configDir} — devuelve la ruta completa al directorio de configuración del componente.
${…@resultDir} — devuelve la ruta completa al directorio de destino del componente (los archivos obtenidos se colocarán en este directorio).
${this@configRoot} — devuelve la ruta completa al directorio raíz del almacenamiento de configuraciones.
Además, el sistema permite obtener variables de entorno, como la ruta a java:
${env@JAVA_HOME}
O, dado que el marco está escrito en JAVA, podemos obtener variables del sistema de manera similar a la llamada System::getProperty usando una construcción de este tipo:
${system@os.name}
Cabe mencionar el soporte para el lenguaje de expresiones Spring EL. En la configuración se aplican expresiones como las siguientes:
connection.timeoutInMs: #{5 * 60 * 1000}
datasource.maximum-pool-size: #{${this@datasource.minimum-pool-size} + 10} y se pueden usar variables locales en archivos de configuración mediante la expresión #var:
#var feedRoot: ${system@user.home}/feed
folder:
root: ${this@feedRoot}
success: ${this@feedRoot}/archive
error: ${this@feedRoot}/errorPor lo tanto, el marco se presenta como una herramienta bastante potente para la configuración precisa y flexible de microservicios. El marco cumple su tarea principal: eliminar el copiado y pegado de las configuraciones, consolidar ajustes y, como consecuencia, minimizar posibles errores, permitiendo además combinar configuraciones fácilmente y modificar para diferentes entornos.
Si está interesado en este marco, le recomiendo visitar su página oficial y familiarizarse con el completo , o investigar el código fuente .
Fuente: habr.com
