Configuração de Persistência de Regras no Sentinel
Recentemente, estive envolvido no desenvolvimento de um projeto baseado em API e retomei o estudo do Sentinel da Alibaba Cloud para controle de tráfego. A versão anterior utilizada em um projeto era apenas um protótipo funcional, mas na implantação real notei que as regras criadas não eram persistentes após reinicializações. Decidi resolver esse problema implementando a persistência das regras.
Modos de Gerenciamento de Regras no Sentinel
O Sentinel oferece três modos principais para gerenciar regras de limitação:
- Modo de Memória: As regras são mantidas apenas em memória RAM e são perdidas após a reinicialização do serviço.
- Modo de Puxar (Pull): As regras são armazenadas localmente no projeto, permitindo a persistência sem depender de um console centralizado.
- Modo de Empurrar (Push): As regras são enviadas a partir do console do Sentinel para um repositório centralizado, onde o serviço as consome.
Após análise, optei pelo modo Pull, pois ele não exige alterações no console do Sentinel nem recompilação do mesmo, reduzindo complexidade operacional.
Implementação da Persistência
Para persistir regras básicas de limitação e regras de limitação por parâmetro, criei uma classe de iincialização que carrega e salva regras em arquivos JSON no sistema de arquivos local.
Classe de Inicialização
public class FileDataSourceInitializer implements InitFunc {
private String directoryPath = "/data/sentinel/openapi/";
private String flowRuleFile = "flowRule.json";
private String paramRuleFile = "paramFlowRule.json";
@Override
public void init() throws Exception {
createDirectoryIfNotExists();
registerFlowRules();
registerParamRules();
}
private void createDirectoryIfNotExists() {
File dir = new File(directoryPath);
if (!dir.exists()) {
dir.mkdirs();
}
}
private void registerFlowRules() {
String path = directoryPath + flowRuleFile;
FileRefreshableDataSource flowDataSource = new FileRefreshableDataSource(path, source -> JSON.parseObject((String) source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowDataSource.getProperty());
WritableDataSourceRegistry.registerFlowDataSource(new FileWritableDataSource<List<FlowRule>>(path, this::toJson));
}
private void registerParamRules() {
String path = directoryPath + paramRuleFile;
FileRefreshableDataSource paramDataSource = new FileRefreshableDataSource(path, source -> JSON.parseObject((String) source, new TypeReference<List<ParamFlowRule>>() {}));
ParamFlowRuleManager.register2Property(paramDataSource.getProperty());
}
private <T> String toJson(T object) {
return JSON.toJSONString(object);
}
}
Configuração via SPI
Adicione um arquivo chamado com.alibaba.csp.sentinel.init.InitFunc dentro do diretório META-INF/services do projeto. Nele, inclua o caminho completo da classe acima:
seu.pacote.FileDataSourceInitializer
Persistência de Regras de Limitação por Parâmetro (Hotspot)
Para garantir a persistência das regras de limitação por parâmetro, adciionei uma classe de configuração no Spring Boot que registra uma fonte de dados gravável no momento em que a aplicação é inicializada.
Classe de Configuração Spring Boot
@Configuration
public class SentinelConfig implements ApplicationListener<ApplicationReadyEvent> {
private String directoryPath = "/data/sentinel/openapi/";
private String paramRuleFile = "paramFlowRule.json";
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
String path = directoryPath + paramRuleFile;
ModifyParamFlowRulesCommandHandler.setWritableDataSource(new FileWritableDataSource<List<ParamFlowRule>>(path, this::toJson));
}
private <T> String toJson(T object) {
return JSON.toJSONString(object);
}
}
Com essas implementações, ao configurar regras no console do Sentinel, elas serão automaticamente salvas nos arquivos JSON especificados, garantindo persistência entre reinicializações do serviço.