Um dos principais problemas ao desenvolver e operar microsserviços é a configuração correta e cuidadosa de suas instâncias. Na minha opinião, um novo framework pode ajudar nisso. . Ele permite resolver de maneira bastante elegante algumas tarefas rotineiras de configuração de aplicativos.
Se você tem muitos microsserviços, e cada um vem com seu próprio arquivo(s) de configuração, há uma grande probabilidade de cometer um erro em um deles, que pode ser muito difícil de detectar sem a devida prática e sistema de registro. A principal tarefa que o framework se propõe é minimizar os parâmetros de configuração duplicados da instância, reduzindo assim a probabilidade de erros.
Vamos considerar um exemplo. Suponha que você tenha um aplicativo simples com um arquivo de configuração yaml. Isso pode ser qualquer microsserviço em qualquer linguagem. Vamos ver como o framework pode ser aplicado a este serviço.
Mas antes, para maior conveniência, vamos criar um projeto vazio no Idea IDE, previamente instalando o plugin microconfig.io:

Configuramos a configuração de inicialização do plugin, podendo usar a configuração padrão, como na captura de tela acima.
Nosso serviço se chama order, então no novo projeto vamos criar uma estrutura semelhante:

Na pasta com o nome do serviço, colocamos o arquivo de configuração — application.yaml. Todos os microsserviços são executados em algum ambiente, então, além de criar a configuração do próprio serviço, é necessário descrever o ambiente: para isso, criaremos uma pasta envs e adicionaremos um arquivo com o nome do nosso ambiente de trabalho. Assim, o framework criará arquivos de configuração para os serviços no ambiente dev, pois esse é o parâmetro definido nas configurações do plugin.
A estrutura do arquivo dev.yaml será bastante simples:
mainorder:
components:
- orderO framework trabalha com configurações que são agrupadas em grupos. Para nosso serviço, vamos escolher um nome para o grupo mainorder. O framework encontra cada um desses grupos de aplicativos no arquivo de ambientes e cria configurações para todos eles, encontrando-as nas pastas correspondentes.
No próprio arquivo de configurações do serviço order vamos indicar por enquanto apenas um parâmetro:
spring.application.name: orderAgora, vamos executar o plugin, e ele gerará a configuração necessária do nosso serviço com base no caminho especificado nas propriedades:

É possível sem a instalação do plugin, apenas baixando a distribuição do framework e executando-o a partir da linha de comando.
Essa solução é adequada para uso no servidor de compilação.
Vale ressaltar que o framework entende perfeitamente property sintaxe, ou seja, arquivos de propriedade comuns que podem ser usados juntamente com yaml as configurações.
Vamos adicionar mais um serviço payment e ao mesmo tempo complicar o existente.
Em 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.100Em 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.100O principal problema dessas configurações é a presença de uma grande quantidade de cópias das configurações dos serviços. Vamos ver como o framework ajudará a resolver isso. Começaremos pela mais óbvia: a existência da configuração eureka na descrição de cada microsserviço. Criaremos um novo diretório com um arquivo de configuração e adicionaremos uma nova configuração a ele:

E em cada um dos nossos projetos agora adicionaremos a linha #include eureka.
O framework encontrará automaticamente a configuração eureka e a copiará para os arquivos de configuração dos serviços, enquanto uma configuração eureka separada não será criada, uma vez que não a indicaremos no arquivo de ambiente dev.yaml. Serviço order:
#include eureka
server.port: 9999
spring.application.name: order
db.url: 192.168.0.100Além disso, podemos extrair as configurações do banco de dados em uma configuração separada, alterando a linha de importação para #include eureka, oracle.
É importante notar que cada alteração durante a regeneração dos arquivos de configuração é monitorada pelo framework e registrada em um arquivo especial ao lado do arquivo de configuração principal. A entrada em seu log aparece assim: “Stored 1 property changes to order/diff-application.yaml”. Isso permite identificar rapidamente alterações em grandes arquivos de configuração.
Extrair partes comuns da configuração ajuda a eliminar múltiplas cópias desnecessárias, mas não permite criar configurações flexíveis para diferentes ambientes — os endpoints de nossos serviços são únicos e estão hardcoded, o que é um problema. Vamos tentar corrigir isso.
Uma boa solução será manter todos os endpoints em uma única configuração, a qual as outras poderiam referenciar. Para isso, o framework implementou suporte a placeholders. Veja como o arquivo de configuração será alterado. eureka:
cliente:
serviceUrl:
defaultZone: http://${endpoints@eurekaip}:6782/eureka/Agora vamos ver como funciona esse placeholder. O sistema encontra o componente chamado endpoints e procura nele o valor eurekaip, então insere na nossa configuração. Mas como lidar com diferentes ambientes? Para isso, vamos criar um arquivo de configurações com endpoints o seguinte formato application.dev.yaml. O framework determina automaticamente, pelo tipo de arquivo, a qual ambiente essa configuração pertence e a carrega:

Conteúdo do arquivo dev:
eurekaip: 192.89.89.111
dbip: 192.168.0.100Podemos criar a mesma configuração para as portas dos nossos serviços:
server.port: ${ports@order}.Todas as configurações importantes estão em um só lugar, reduzindo assim a probabilidade de erros devido à dispersão de parâmetros em arquivos de configuração.
O framework oferece muitos placeholders já prontos, por exemplo, é possível obter o nome do diretório onde o arquivo de configuração está localizado e atribuí-lo:
#include eureka, oracle
server.port: ${ports@order}
spring.application.name: ${this@name}Graças a isso, não é necessário especificar o nome do aplicativo na configuração, podendo também ser movido para um módulo comum, como o mesmo eureka:
cliente:
serviceUrl:
defaultZone: http://${endpoints@eurekaip}:6782/eureka/
spring.application.name: ${this@name}O arquivo de configuração order será reduzido a uma linha:
#include eureka, oracle
server.port: ${ports@order}Caso alguma configuração da configuração pai não seja necessária, podemos especificá-la em nossa configuração e ela será aplicada na geração. Ou seja, se por algum motivo precisarmos de um nome único para o serviço order, simplesmente deixaremos o parâmetro spring.application.name.
Por exemplo, se o serviço precisar de configurações de logging customizadas, que estão em um arquivo separado, como logback.xml. Vamos criar um grupo separado de configurações para ele:

Na configuração básica, indicaremos ao framework onde alocar o arquivo de configuração de logging necessário através do placeholder @ConfigDir:
microconfig.template.logback.fromFile: ${logback@configDir}/logback.xmlNo arquivo logback.xml configuramos os appenderes padrão, que também podem conter placeholders que o framework modificará durante a geração das configurações, por exemplo:
logs/${this@name}.logAo adicionar nas configurações dos serviços a importação logback, recebemos automaticamente o logging configurado para cada serviço:
#include eureka, oracle, logback
server.port: ${ports@order}É hora de conhecer mais detalhadamente todos os placeholders disponíveis no framework:
${this@env} — retorna o nome do ambiente atual.
${…@name} — retorna o nome do componente.
${…@configDir} — retorna o caminho completo para o diretório de configuração do componente.
${…@resultDir} — retorna o caminho completo para o diretório de destino do componente (os arquivos recebidos serão colocados neste diretório).
${this@configRoot} — retorna o caminho completo para o diretório raiz do repositório de configurações.
O sistema também permite acessar variáveis de ambiente, como o caminho para o java:
${env@JAVA_HOME}
Ou, já que o framework é escrito em JAVA, podemos obter variáveis de sistema semelhantes à chamada System::getProperty com a construção deste tipo:
${system@os.name}
Vale a pena mencionar o suporte à linguagem de expressões. Spring EL. Em configurações, expressões como estas são aplicáveis:
connection.timeoutInMs: #{5 * 60 * 1000}
datasource.maximum-pool-size: #{${this@datasource.minimum-pool-size} + 10} e é possível usar variáveis locais em arquivos de configuração com a expressão. #var:
#var feedRoot: ${system@user.home}/feed
folder:
root: ${this@feedRoot}
success: ${this@feedRoot}/archive
error: ${this@feedRoot}/errorAssim, o framework se mostra uma ferramenta bastante poderosa para configuração detalhada e flexível de microsserviços. O framework cumpriu sua função principal — eliminar o copy-paste nas configurações, consolidar as configurações e, como consequência, minimizar possíveis erros, permitindo ao mesmo tempo combinar configurações facilmente e alterá-las para diferentes ambientes.
Se você se interessou por este framework, recomendo visitar sua página oficial e conferir a documentação completa, , ou explorar os códigos-fonte. .
Fonte: habr.com
