sentinela
Sentinel é um componente de proteção de tráfego de alta disponibilidade para arquitetura de serviços distribuídos. Ele usa principalmente o tráfego como ponto de entrada para ajudar os desenvolvedores a garantir a estabilidade dos microsserviços em múltiplas dimensões, como limitação de corrente, modelagem de tráfego, degradação do disjuntor, proteção de carga do sistema e proteção de ponto de acesso.sexo.
1. Avalanche de serviços em microsserviços
O efeito avalanche de serviços é um fenômeno em que “a indisponibilidade do prestador de serviço” (a causa) leva à “indisponibilidade do chamador do serviço” (o resultado), e a indisponibilidade é gradativamente ampliada.
2. Solução para avalanche
Existem muitos motivos para a avalanche de serviços, incluindo motivos de hardware, motivos de rede, motivos de software, etc. Aqui, falamos apenas de diversas soluções e rotinas para solucionar avalanches de serviços do ponto de vista do software, de forma a entender a origem e o motivo da utilização das pilhas de tecnologia relevantes na arquitetura de microsserviços.
-
Definir tempo limite:
- A compressão do thread é causada pelo fato de a chamada remota síncrona não receber resposta por um longo tempo, portanto, definir o tempo limite pode reduzir a ocupação de longo prazo do thread e evitar a compressão do thread. Restrições de trânsito:
- Limite o fluxo do serviço para evitar que ele trave devido à simultaneidade excessiva. Rebaixamento do disjuntor:
- Para serviços que foram desligados, nenhuma chamada é feita diretamente, mas os resultados são retornados diretamente. Isso é um disjuntor. Isto evita o impacto do serviço interrompido no chamador. Modo anteparo:
-
O modo Bulkhead isola os principais recursos para cada carga de trabalho ou serviço, como pools de conexões, memória e CPU.
Use anteparas Evita que uma única carga de trabalho (ou serviço) consuma todos os recursos , fazendo com que outros serviços falhem.
Este modelo aumenta principalmente a resiliência do sistema, evitando falhas em cascata causadas por um serviço.
Uma das principais razões para o naufrágio do Titanic foi uma falha no projeto de suas anteparas, que permitiu que a água vazasse pelos conveses acima e para o topo das anteparas, causando a inundação de todo o casco.
Chaves primárias para gerenciamento de tráfego: hystrix:netflix e sentinela:Alibaba
3. Use sentinela
Abra o console sentinela
para configurar o disjuntor de controle de fluxo e degradação dos microsserviços conectados ao console.
Execute o pacote jar do sentinela
e acesse a interface do console
http://localhost:8080Conta
e senha: sentinela/sentinel
O acesso de microsserviço à plataforma sentinela
(1) introduz dependências
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2)Configuração
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
(3) Acesse qualquer interface de microsserviços
Clique no botão de controle de fluxo atrás de recurso/pedido/{orderId} para abrir o formulário. Regras de controle de fluxo podem ser adicionadas ao formulário, conforme mostrado na figura abaixo:
O significado é limitar o QPS de máquina única do recurso /order/{orderId} a 1, ou seja, apenas uma solicitação é permitida por segundo. As solicitações que excederem o limite serão interceptadas e um erro será relatado.
3.1 Três modos de controle de fluxo
Ao adicionar regras de limitação de fluxo, clique em Opções Avançadas para escolher entre três modos de controle de fluxo:
- Direto: conta solicitações de recursos atuais e limita diretamente os recursos atuais quando o limite é acionado. Este também é o modo padrão.
- Associação: Estatísticas sobre outro recurso relacionado ao recurso atual. Quando o limite é acionado, o recurso atual é limitado.
- Link: Conta as solicitações de acesso a este recurso a partir do link especificado. Quando o limite é acionado, o link especificado será limitado por fluxo.
3.1.1 Modo de associação
Modo de associação: conta outro recurso relacionado ao recurso atual. Quando o limite é acionado, o recurso atual é limitado.
- Cenário de uso: Por exemplo, o usuário precisa modificar o status do pedido no momento do pagamento e, ao mesmo tempo, o usuário precisa consultar o pedido. As operações de consulta e modificação competirão por bloqueios de banco de dados e causarão competição.
- O requisito de negócios é o pagamento limitado e o negócio de atualização de pedidos, portanto, quando o limite de acionamento do pedido de negócios é modificado, o fluxo de negócios do pedido de consulta precisa ser limitado.
Quando o limite de acesso ao recurso /write for acionado, o recurso /read será limitado para evitar afetar o recurso /write.
O modo de associação pode ser usado se as seguintes condições forem atendidas:
- Dois recursos concorrentes
- Um com maior prioridade e outro com menor prioridade
3.1.2 Modo de ligação
Modo de link: Faça estatísticas apenas sobre solicitações de acesso a este recurso a partir do link especificado para determinar se o limite foi excedido.
Por exemplo, existem dois links de solicitação:
-
/test1 -》 /comum
-
/test2 -》 /comum
Se você quiser contar apenas solicitações de /test2 para /common, poderá configurá-lo assim:
- O Sentinel marca apenas métodos no Controller como recursos por padrão. Se você quiser marcar outros métodos, será necessário usar a anotação @SentinelResource. Exemplo:
- O Sentinel integrará o método Controller ao contexto por padrão, fazendo com que o controle de fluxo do modo de link falhe. Você precisa modificar o application.yml e adicionar a configuração:
4. Efeito de controle de fluxo
O efeito de controle de fluxo refere-se às medidas que devem ser tomadas quando a solicitação atinge o limite de controle de fluxo, incluindo três tipos:
- Falha rápida: após atingir o limite, novas solicitações serão rejeitadas imediatamente e uma FlowException será lançada. Este é o método de processamento padrão.
- aquecimento: modo de aquecimento, solicitações que excedem o limite também são rejeitadas e exceções são lançadas. Mas este limite de modo muda dinamicamente, aumentando gradualmente de um valor menor até o limite máximo.
- Enfileiramento e espera: enfileire todas as solicitações para execução em ordem. O intervalo entre duas solicitações não pode ser menor que o tempo especificado.
4.1 aquecimento
O aquecimento, também chamado de modo de aquecimento, é uma solução para inicialização a frio de serviços. O valor inicial do limite de solicitação é limite/coldFactor. Após um período de tempo especificado, ele aumentará gradualmente até o valor limite. O valor padrão de coldFactor é 3.
Por exemplo, se eu definir o limite de QPS para 10 e o tempo de aquecimento para 5 segundos, o limite inicial será 10/3, que é 3, e aumentará gradualmente para 10 após 5 segundos.
4.2 Esperando na fila
Quando as solicitações excedem o limite de QPS, a falha rápida e o aquecimento rejeitarão novas solicitações e gerarão uma exceção. Enfileirar e esperar consiste em colocar todas as solicitações em uma fila e executá-las em sequência de acordo com o intervalo de tempo permitido pelo limite. As solicitações subsequentes devem aguardar a conclusão da execução anterior. Se o tempo de espera esperado da solicitação exceder a duração máxima, ela será rejeitada.
Por exemplo: QPS = 5, o que significa que uma solicitação na fila é processada a cada 200 ms; timeout = 2.000, o que significa que o esperadoSolicitações que aguardam mais de 2.000 ms serão rejeitadas e uma exceção será lançada.
5. Limitação de corrente do parâmetro Hotspot
A limitação atual do parâmetro Hotspot é inválida para recursos SpringMVC por padrão
6. Disjuntor e downgrade
6.1 Integração de openfeign e sentinela
(1) Ative a função sentinela do feign
# 开启openfeign的sentinel功能
feign:
sentinel:
enabled: true
(2) Crie uma classe rebaixada e implemente a interface FallbackFactory.A versão genérica desta interface é a classe de interface simulada.
@Component
@Slf4j
public class ProductFeignFactory implements FallbackFactory<ProductFeign>{
@Override
public ProductFeign create(Throwable throwable) {
return new ProductFeign() {
@Override
public Product getById(Long pid) {
log.error("商品微服务故障"+throwable.getMessage());
//默认的一个商品对象
Product product=new Product();
return product;
}
};
}
}
(3) Use a classe rebaixada ao chamar feign
//value:调用远程微服务的名称 fallbackFactory:降级类工厂
@FeignClient(value = "shop-product",fallbackFactory = ProductFeignFactory.class)
public interface ProductFeign {
@GetMapping("/product/getById/{pid}")
public Product getById(@PathVariable Long pid);
}
6.2 Isolamento de thread (modo anteparo)
Ao adicionar uma regra de limitação atual, você pode escolher entre dois tipos de limite:
- QPS: É o número de solicitações por segundo, que foi demonstrado no início rápido
- Número de threads: É o número máximo de threads do Tomcat que podem ser utilizadas por este recurso. Ou seja, ao limitar o número de threads, o modo bulkhead é alcançado.
Quais são os dois métodos de isolamento de thread?
Isolamento de semáforo
Isolamento do pool de threads
Quais são as características do isolamento do semáforo?
- Baseado no modo contador, sobrecarga simples e baixa
Quais são as características do isolamento do pool de threads?
- Com base no modo pool de threads, há sobrecarga adicional, mas o controle de isolamento é mais forte
6.3 Degradação do disjuntor
A degradação do disjuntor é um meio importante para resolver o problema da avalanche. A idéia é que o disjuntor conte a proporção anormal e a proporção de solicitações lentas das chamadas de serviço. Se o limite for excedido, o serviço será cortado . Ou seja, todas as solicitações de acesso ao serviço são interceptadas; e quando o serviço for restabelecido, o disjuntor liberará as solicitações de acesso ao serviço.
Existem três estratégias de fusão de disjuntores: chamada lenta, proporção anormal e número anormal.
-
Chamada lenta: uma solicitação cujo tempo de resposta do serviço (RT) é maior que o tempo especificado é considerada uma solicitação de chamada lenta. Dentro do tempo especificado, se o número de solicitações exceder o número mínimo definido e a taxa de chamadas lentas for maior que o limite definido, o disjuntor será acionado. Por exemplo:
Interpretação: Chamadas com RT superior a 500 ms são chamadas lentas. Conte as solicitações nos últimos 10.000 ms. Se o número de solicitações exceder 10 vezes e a proporção de chamadas lentas não for inferior a 0,5, o disjuntor será acionado e o a duração do disjuntor é de 5 segundos. Em seguida, entre no estado semiaberto e libere uma solicitação para teste. -
Proporção anormal ou número de exceções: Contagem de chamadas dentro de um período especificado. Se o número de chamadas exceder o número especificado de solicitações e a proporção de exceções atingir o limite de proporção definido (ou exceder o número especificado de exceções), um disjuntor será acionado . Por exemplo:
Interpretação: Contar as solicitações nos últimos 1000 ms. Se o número de solicitações exceder 10 vezes e a taxa de anormalidade não for inferior a 0,5, o disjuntor será acionado e a duração do disjuntor será de 5 segundos. Em seguida, entre no estado semiaberto e libere uma solicitação para teste.
Quais são as estratégias para o downgrade do disjuntor Sentinel?
Proporção de chamadas lentas: As chamadas que excedem a duração especificada são chamadas lentas. A proporção de chamadas lentas dentro da duração da unidade é contada. Se o limite for excedido, o disjuntor será desligado.
Proporção anormal: estatística da proporção de chamadas anormais dentro da duração da unidade. Se ultrapassar o limite, o disjuntor será desligado.
Número de exceções: conta o número de chamadas anormais dentro de uma unidade de tempo. Se o limite for excedido, o disjuntor será desligado.
7. sentinela define persistência
Com tantas regras escritas acima, as regras serão perdidas quando o cliente de microsserviço for reiniciado.
Quais são os três modos de gerenciamento de configuração do Sentinel?
Modo bruto: salve na memória
Modo pull: salve-o em um arquivo local ou banco de dados e leia-o regularmente, o desempenho será baixo.
Modo push: salve em nacos, monitore alterações e atualize em tempo real, atualmentePromovido por empresas.
Nacos no sentinle não fornece a necessidade de modificar o código-fonte do sentinela. Após a modificação, empacote o código-fonte em um jar e reinicie o pacote jar.
7.1 modo de puxar
Garantia de regras para arquivos locais
(1) Definir classes persistidas em arquivos
package com.aaa.order.rule;
import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.datasource.*;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Value;
import java.io.File;
import java.io.IOException;
import java.util.List;
//用于规则持久化到文件中
public class FilePersistence implements InitFunc {
@Value("${spring.application.name}")
private String appcationName;
@Override
public void init() throws Exception {
String ruleDir = "D:/sentinel-rules/shop-order" ;
String flowRulePath = ruleDir + "/flow-rule.json";
String degradeRulePath = ruleDir + "/degrade-rule.json";
String systemRulePath = ruleDir + "/system-rule.json";
String authorityRulePath = ruleDir + "/authority-rule.json";
String paramFlowRulePath = ruleDir + "/param-flow-rule.json";
this.mkdirIfNotExits(ruleDir);
this.createFileIfNotExits(flowRulePath);
this.createFileIfNotExits(degradeRulePath);
this.createFileIfNotExits(systemRulePath);
this.createFileIfNotExits(authorityRulePath);
this.createFileIfNotExits(paramFlowRulePath);
// 流控规则
ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
flowRuleListParser
);
FlowRuleManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
flowRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
// 降级规则
ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
degradeRulePath,
degradeRuleListParser
);
DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
degradeRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
// 系统规则
ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
systemRulePath,
systemRuleListParser
);
SystemRuleManager.register2Property(systemRuleRDS.getProperty());
WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
systemRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
// 授权规则
ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
authorityRulePath,
authorityRuleListParser
);
AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
authorityRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
// 热点参数规则
ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(
paramFlowRulePath,
paramFlowRuleListParser
);
ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
paramFlowRulePath,
this::encodeJson
);
ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
}
private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<FlowRule>>() {
}
);
private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<DegradeRule>>() {
}
);
private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<SystemRule>>() {
}
);
private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<AuthorityRule>>() {
}
);
private Converter<String, List<ParamFlowRule>> paramFlowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<ParamFlowRule>>() {
}
);
private void mkdirIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
}
private void createFileIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
}
private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
(2) Adicionar configuração.
Crie o diretório de configuração META-INF/services em recursos e, em seguida, adicione arquivos
com.alibaba.csp.sentinel.init.InitFunc
Adicione o caminho completo para a classe de configuração no arquivo
com.aaa.rule.FilePersistence
7.2 modo de pressão
Empurre para o centro de configuração nacos
sentinel persistence, queremos isto:
- Você pode editar a configuração de limitação atual no console do sentinela e sincronizá-la com nacos para persistência.
- A configuração de limitação atual foi modificada no nacos e também pode ser sincronizada com o console sentinela.
Para implementar a primeira função acima, você precisa entender o código-fonte do console sentinela e modificá-lo de acordo.
Mas alguém no GitHub já o modificou e fez uma versão aprimorada do console.
https://github.com/CHENZHENNAME/sentinel-dashboard-nacos
7.2.1 Modificar sentinela
- Abra o URL acima e baixe-o localmente
- Descompacte os arquivos acima:
- Abra pom.xml no diretório raiz e modifique a versão sentinela
- Digite o diretório raiz do projeto, cmd, e execute o comando
mvn clean package
- Após o empacotamento, ele é produzido no diretório de destino.
- Execute o comando para iniciar o console:
java -Dserver.port=8080 -Dnacos.serverAddr=localhost:8848 -jar sentinel-dashboard.jar
-Dserver.port número da porta do console
-Dnacos.serverAddr: endereço nacos
-Dnacos.namespace: o namespace nacos onde seu projeto está localizado. Se o namespace for público, você poderá omitir esse parâmetro.
7.2.2 Cliente de microsserviço acessa painel de controle sentinela
- Introduzir dependências
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.1</version>
</dependency>
- Modificar arquivo de configuração
Iniciar microsserviço
Em seguida, o navegador acessa: http://localhost:8080. A princípio não há nada. Em seguida, acesse qualquer interface do seu próprio projeto que precise ter fluxo limitado. Em seguida, o nome do serviço aparecerá à esquerda. Clique no ponto de cluster link.
Novo Adicionar uma regra de controle de fluxo:
Observe que clique naquele com 2. Somente aquele com 2 pode ser enviado para nacos. Adicioná-lo na opção de regra de controle de fluxo não funcionará. Você só pode enviar para nacos clicando na caixa azul.
${application-name}-flow-rules
Após a adição ser bem-sucedida, um arquivo de configuração no formato do namespace especificado será gerado automaticamente no nacos.
Quando você adiciona ou modifica regras no console do sentinela, elas serão sincronizadas com o nacos; pelo contrário, modifique o limite atual do arquivo de configuração em nacos. As regras também serão sincronizadas com o sentinela.