Gerenciamento Centralizado de Configurações com Spring Cloud Config

O Spring Cloud Config fornece suporte para configurações externas em sistemas distribuídos, tanto do lado do servidor quanto do cliente. Com o Config Server, centraliza-se o gerenciamento de todas as propriedades de aplicativos em diferentes ambientes (desenvolvimento, teste, produção).

Configuração do Servidor (Config Server)

Para criar um servidor de configuração, é necessário iniciar um projeto Spring Boot e incluir a dependência do servidor de configuração. Neste exemplo, utilizaremos o GitHub como repositório para os arquivos de propreidades.

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-config-server</artifactId>
</dependency>

No arquivo application.properties do servidor, definimos as configurações de integração com o Git e o registro no Eureka:

server.port=8888
spring.application.name=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

# Integração com Repositório Git
spring.cloud.config.server.git.uri=https://github.com/seu-usuario/repositorio-config.git
spring.cloud.config.server.git.search-paths=config-repo
spring.cloud.config.label=main
spring.cloud.config.server.git.username=usuario
spring.cloud.config.server.git.password=senha

A classe principal deve ser anotada com @EnableConfigServer para ativar as funcionalidades de servidor:

@EnableConfigServer
@EnableDiscoveryClient
@SpringBootApplication
public class CentralConfigApplication {
   public static void main(String[] args) {
       SpringApplication.run(CentralConfigApplication.class, args);
   }
}

Tratamento de Codificação de Caracteres

Em sistemas Windows ou ao lidar com caracteres especiais em arquivos .properties, pode ocorrer corrupção de caracteres. Para garantir a leitura correta em UTF-8, podemos implementar um carregador customizado:

public class CodificacaoPropertiesHandler extends PropertiesPropertySourceLoader {
   @Override
   public String[] getFileExtensions() {
       return new String[]{"properties", "xml"};
   }

   @Override
   public List<PropertySource<?>> load(String nome, Resource recurso) throws IOException {
       Properties propriedades = new Properties();
       try (InputStreamReader leitor = new InputStreamReader(recurso.getInputStream(), StandardCharsets.UTF_8)) {
           propriedades.load(leitor);
       }
       
       List<PropertySource<?>> lista = new ArrayList<>();
       if (!propriedades.isEmpty()) {
           lista.add(new PropertiesPropertySource(nome, propriedades));
       }
       return lista;
   }
}

Para ativar esse handler, crie o arquivo src/main/resources/META-INF/spring.factories:

org.springframework.boot.env.PropertySourceLoader=com.exemplo.config.CodificacaoPropertiesHandler

Configuração do Cliente (Config Client)

O cliente precisa de uma dependência específica para se comunicar com o servidor de configuração:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

É fundamental utilizar o arquivo bootstrap.properties (ou bootstrap.yml) no cliente, pois ele é processado antes do application.properties durante a fase de inicialização do contexto:

spring.application.name=app-cliente
spring.cloud.config.profile=dev
spring.cloud.config.label=main

# Localização do Config Server via URL direta
spring.cloud.config.uri=http://localhost:8888/

# Ou via Service Discovery (Eureka)
# spring.cloud.config.discovery.enabled=true
# spring.cloud.config.discovery.service-id=config-server

Para testar o recebimento dos valores, utilize a anotação @Value em um controlador:

@RestController
@SpringBootApplication
public class ClienteApplication {
   
   @Value("${custom.config.mensagem:Padrao}")
   private String mensagem;

   @GetMapping("/msg")
   public String obterMensagem() {
       return "Valor remoto: " + mensagem;
   }

   public static void main(String[] args) {
       SpringApplication.run(ClienteApplication.class, args);
   }
}

Atualização Dinâmica de Parâmetros

Por padrão, o cliente lê as configurações no momento da inicialização e as mantém em cache. Se houver mudanças no repositório Git, o Config Server as detecta, mas o cliente não as atualiza automaticamente. Para resolver isso, utilizamos o módulo Actuator.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Adicione a anotação @RefreshScope no Bean que utiliza os valores injetados:

@RefreshScope
@RestController
public class MensagemController {
   @Value("${config.usuario.nome}")
   private String nomeUsuario;
   
   // ... métodos
}

No Spring Boot 2.x e superiores, os endpoints do Actuator são restritos por padrão. É necessário expor o endpoint de refresh nas configurações do cliente:

management.endpoints.web.exposure.include=refresh

Para forçar a atualização dos dados sem reiniciar a aplicação, envie uma requisição HTTP POST para o endpoint /actuator/refresh do cliente:

curl -X POST http://localhost:8080/actuator/refresh

Tags: spring-cloud-config spring-boot microservices java cloud-native

Publicado em 7-17 07:53