Wang Youzhi , um pescador de ouro mútuo que compartilha a tecnologia Java hard-core,
junta-se ao grupo de pessoas de Java que correm com baldes : pessoas de Java que são ricas juntas
No artigo anterior , integramos o Dubbo no aplicativo Spring Boot e registramos um provedor de serviços e um consumidor de serviços. Obviamente, os aplicativos no ambiente de produção geralmente implantam vários nós para garantir alta disponibilidade de serviços, então, como configurar a estratégia de balanceamento de carga do Dubbo?
Vamos usar isso como um ponto de entrada para introduzir a configuração e o uso dos recursos avançados fornecidos pelo Dubbo na governança de serviços . O Dubbo suporta 6 fontes de configuração por padrão:
-
Propriedades do sistema JVM, parâmetro JVM -D
-
Ambiente do sistema, a variável de ambiente do processo JVM
-
Configuração externalizada, configuração externalizada, lida do centro de configuração
-
Application Configuration, a configuração de atributos do aplicativo, extrai o conjunto de atributos começando com "dubbo" do Ambiente do aplicativo Spring
-
A configuração coletada pela interface de programação, como API//annotation, pode ser entendida como uma espécie de fonte de configuração, que é um método de coleta de configuração diretamente orientado para a programação do usuário
-
Leia o arquivo de configuração dubbo.properties do classpath
No conteúdo de hoje, abordaremos apenas os três métodos de configuração comuns de Configuração de aplicativo, XML e anotações .
Dicas : Este artigo é o conteúdo básico, com foco em configuração e uso , e não envolve nenhum princípio de implementação e princípios de algoritmo.
balanceamento de carga
Nos microsserviços, o balanceamento de carga refere-se à distribuição "razoável" de solicitações entre diferentes nós do serviço, de modo a otimizar o uso de recursos, fornecer alto throughput e reduzir o tempo de resposta. O Dubbo 3.X fornece 7 estratégias de balanceamento de carga:
algoritmo | característica | valor de configuração | alocação padrão | ilustrar |
---|---|---|---|---|
Balanceamento de carga aleatório ponderado | aleatório ponderado | aleatório | sim | O algoritmo padrão , o peso padrão é o mesmo |
RoundRobin LoadBalance | round robin ponderado | rodízio | não | Com base no algoritmo round-robin ponderado suave do Nginx, o peso padrão é o mesmo, |
Balanço de Carga Menos Ativo | Menos prioridade ativa + aleatório ponderado | menos ativo | não | Por trás disso está a ideia de que quem pode trabalhar mais |
LoadBalance de resposta mais curta | Resposta mais curta primeiro + aleatório ponderado | resposta mais curta | não | Preste mais atenção à capacidade de resposta |
Equilíbrio de Carga de Hash Consistente | hashing consistente | hash consistente | não | Parâmetros de entrada determinados, provedor determinado, adequado para solicitações com informações de estado |
Balanço de Carga P2C | Poder de duas escolhas | p2c | não | Depois de selecionar aleatoriamente dois nós, continue selecionando o nó com o menor "número de conexões". |
Balanceamento de carga adaptável | Balanceamento de carga adaptável | adaptativo | não | Com base no algoritmo P2C, selecione o nó com a menor carga entre os dois |
O Dubbo suporta a configuração de políticas de balanceamento de carga tanto para o provedor de serviço quanto para o consumidor de serviço. Quando ambos são configurados com políticas de balanceamento de carga, a política de balanceamento de carga do consumidor de serviço prevalecerá.
Primeiro, vamos ver o método de configuração do arquivo XML. Por meio do arquivo XML, você pode configurar a estratégia de balanceamento de carga para a interface e o método.DubboDemoService
Primeiro , configure a estratégia de balanceamento de carga para a interface do provedor de serviços :
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" loadbalance="roundrobin"/>
DubboDemoService#say
Em seguida , configuramos a estratégia de balanceamento de carga para o consumidor do serviço ao chamar o método:
<dubbo:reference id="DubboDemoService" interface="com.wyz.api.DubboDemoService">
<dubbo:method name="say" loadbalance="roundrobin"/>
</dubbo:reference>
Em seguida, usamos o arquivo Application para configurar a estratégia de balanceamento de carga. Através do arquivo Application , podemos configurar a estratégia global de balanceamento de carga do aplicativo Dubbo . O conteúdo é o seguinte:
dubbo:
provider:
loadbalance: roundrobin
consumer:
loadbalance: roundrobin
Por fim , configure a estratégia de balanceamento de carga na forma de anotações. Você pode definir a configuração da estratégia de balanceamento de carga para a interface e o método . O código é o seguinte:
@DubboService(loadbalance = "roundrobin")
public class DubboDemoServiceImpl implements DubboDemoService {
@Override
@DubboService(loadbalance = "leastactive")
public String say(String message) {
return "DubboProvider say : " + message;
}
}
tolerância a falhas de cluster
Após configurar a estratégia de balanceamento de carga, o programa está rodando de forma estável. Mas, de repente, um dia, um nó no cluster está indisponível. Quando a solicitação "atingir" o nó indisponível, como o Dubbo lidará com isso?
Dubbo fornece a capacidade de tolerância a falhas de cluster e implementa 9 soluções para falha de nó no cluster:
Estratégia | valor de configuração | alocação padrão | característica | Cenário de Aplicação |
---|---|---|---|---|
Cluster de Failover | failover | sim | Comutação automática em caso de falha, quando ocorrer falha, tente novamente outros servidores | Geralmente usado para operações de leitura, o número de tentativas pode ser configurado |
Cluster à prova de falhas | failfast | não | Falha rápido, relata o erro imediatamente após a falha | Geralmente usado para operações de gravação não idempotentes |
Cluster à prova de falhas | à prova de falhas | não | Fail safe, quando ocorrer uma exceção, apenas ignore | Geralmente usado para gravar logs de auditoria |
Cluster de Failback | failback | não | Recupere-se automaticamente de falhas, registre solicitações com falha em segundo plano e reenvie-as em intervalos regulares | Geralmente usado para notificação de mensagem |
Agrupamento de bifurcação | bifurcação | não | Chame vários servidores em paralelo e retorne, desde que seja bem-sucedido | Geralmente usado para operações de leitura com altos requisitos de tempo real |
Cluster de transmissão | transmissão | não | Transmita chamadas para todos os provedores, um por um, se algum relatar um erro, ele reportará um erro | atualização de cache |
Cluster disponível | disponível | não | Chame a instância atualmente disponível (apenas uma é chamada), se nenhuma instância estiver disponível no momento, lance uma exceção | Cenários que não requerem balanceamento de carga |
Cluster que pode ser mesclado | mesclável | não | Agregue os resultados da chamada no cluster e retorne os resultados, geralmente usados em conjunto com o grupo | / |
Cluster ZoneAware | / | não | Cenário de assinatura de vários registros, balanceamento de carga entre clusters de registro | / |
A forma do arquivo XML ainda fornece configuração de política tolerante a falhas de cluster na interface e no nível do método de interface :
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" cluster="failover" retries="2"/>
Entre eles retries
está o parâmetro da política Failover Cluster, que define o número de retentativas da interface (excluindo o número de chamadas normais) Por exemplo, na configuração acima, após a falha da chamada normal, ela será chamada no máximo duas vezes. A política de tolerância a falhas de cluster no nível do método de configuração XML é consistente com a política de balanceamento de carga de configuração, portanto, não entrarei em detalhes aqui.
A política global de tolerância a falhas do cluster pode ser configurada no arquivo Application , da seguinte forma:
dubbo:
provider:
cluster: failover
retries: 2
Finalmente, o método de configuração de anotação ainda é usado para @DubboService
configurar a estratégia de tolerância a falhas do cluster na interface e no nível do método de interface. O código é o seguinte:
@DubboService(cluster = "failover", retries = 2)
public class DubboDemoServiceImpl implements DubboDemoService {
@Override
@DubboService(cluster = "failover", retries = 2)
public String say(String message) {
return "DubboProviderXML say : " + message;
}
}
rebaixamento de serviço
A função de downgrade do serviço fornecida pelo próprio Dubbo é relativamente simples e fornece apenas a função simulada. Se você deseja experimentar funções como limitação de corrente e fusão com funções completas, pode usar componentes técnicos profissionais suportados pelo Dubbo, como Sentinel, Hystrix , e Resiliência4j. Como a função de downgrade do serviço do Dubbo é relativamente simples, aqui só precisamos entender a configuração da função de downgrade do serviço por meio de três métodos de configuração de arquivo XML.
Método de configuração um
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" mock="true"/>
Mock
Nesta forma de configuração, é necessário ter uma classe de implementação com o nome da classe + sufixo no mesmo pacote , por exemplo: DubboDemoServiceMock
.
public class DubboDemoServiceMock implements DubboDemoService {
@Override
public String say(String message) {
return "服务出错了!";
}
}
Método de configuração dois
Configurado por meio do nome totalmente qualificado da classe Mock:
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" mock="com.wyz.api.DubboDemoServiceMock"/>
Método de configuração três
Use a expressão definida por Dubbo: mock="[fail|force]return|throw xxx"
.
-
[fail|force]
, o valor padrão é fail, o que significa que após a chamada falhar, ou aplicar diretamente o método simulado sem chamada de método; -
return xxx
, que significa retornar o resultado especificado, que precisa estar de acordo com o tipo de retorno da interface; -
throw xxx
, indicando que a exceção especificada é lançada.
Vamos dar alguns exemplos:
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" mock="return fail"/>
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" mock="force:return false"/>
<dubbo:service interface="com.wyz.api.DubboDemoService" ref="dubboDemoServiceImpl" mock="fail:throw java.lang.NullPointException"/>
grupo de serviço
Diferentes implementações da mesma interface podem ser distinguidas por agrupamento. Por exemplo: Adicione duas implementações diferentes DubboXMLServiceImpl e NewDubboXMLServiceImpl para a interface DubboXMLService.
public interface DubboXMLService {
String say(String message);
}
public class DubboXMLServiceImpl implements DubboXMLService {
@Override
public String say(String message) {
return "DubboProviderXML say : " + message;
}
}
public class NewDubboXMLServiceImpl implements DubboXMLService {
@Override
public String say(String message) {
return "NewDubboProviderXML say : " + message;
}
}
A primeira é configurar o provedor de serviço através do arquivo XML:
<bean id="dubboXMLServiceImpl" class="com.wyz.service.impl.DubboXMLServiceImpl"/>
<dubbo:service interface="com.wyz.api.DubboXMLService" ref="dubboXMLServiceImpl" group="XML-Provider"/>
<bean id="newDubboXMLServiceImpl" class="com.wyz.service.impl.NewDubboXMLServiceImpl"/>
<dubbo:service interface="com.wyz.api.DubboXMLService" ref="newDubboXMLServiceImpl" group="New-XML-Provider"/>
Em seguida, observe a configuração do consumidor de serviço:
<dubbo:reference id="dubboXMLService" interface="com.wyz.api.DubboXMLService" group="XML-Provider"/>
<dubbo:reference id="newDubboXMLService" interface="com.wyz.api.DubboXMLService" group="New-XML-Provider"/>
Também é muito simples de usar, você pode @Autowired
injetar diretamente serviços de diferentes grupos por meio de:
public class DubboConsumerXMLService implements CommandLineRunner {
@Autowired
DubboXMLService dubboXMLService;
@Autowired
DubboXMLService newDubboXMLService;
@Override
public void run(String... args) {
String message = dubboXMLService.say("wyz");
System.out.println(message);
String newMessage = newDubboXMLService.say("wyz");
System.out.println(newMessage);
}
}
Vejamos como configurar por meio de anotações:
@DubboService(group = "Annotation-Provider")
public class DubboAnnotationServiceImpl implements DubboAnnotationService {
@Override
public String say(String message) {
return "DubboProviderAnnotation say : " + message;
}
}
@DubboService(group = "New-Annotation-Provider")
public class NewDubboAnnotationServiceImpl implements DubboAnnotationService {
@Override
public String say(String message) {
return "NewDubboProviderAnnotation say : " + message;
}
}
Finalmente, os serviços de diferentes grupos são usados através de anotações. Observe que @DubboReference
o Bean injetado é usado aqui:
@Component
public class DubboConsumerAnnotationService implements CommandLineRunner {
@DubboReference(group = "Annotation-Provider")
DubboAnnotationService dubboAnnotationService;
@DubboReference(group = "New-Annotation-Provider")
DubboAnnotationService newDubboAnnotationService;
@Override
public void run(String... args) {
String message = dubboAnnotationService.say("wyz-Annotation");
System.out.println(message);
String newMessage = newDubboAnnotationService.say("wyz-Annotation");
System.out.println(newMessage);
}
}
Dicas : Não é recomendável configurar pelo arquivo do aplicativo.
versão do serviço
No Dubbo, uma interface não pode determinar exclusivamente um serviço, apenas uma interface clara + grupo + número da versão pode determinar exclusivamente um serviço , por exemplo:
<dubbo:service interface="com.wyz.api.DubboXMLService" ref="dubboXMLServiceImpl" group="XML-Provider" version="1.0.0"/>
Versões diferentes de serviços são comuns no cenário de verificação de liberação de versão. Alguns nós no cluster atualizam serviços e trocam uma pequena quantidade de tráfego. Após a verificação bem-sucedida, os nós são atualizados em grande escala, o que pode reduzir os riscos trazidos por atualizações de serviço .
A configuração e utilização da versão do serviço é a mesma do grupo de serviço, sendo mostrada aqui apenas a configuração do arquivo XML:
<bean id="dubboXMLServiceImpl" class="com.wyz.service.impl.DubboXMLServiceImpl"/>
<dubbo:service interface="com.wyz.api.DubboXMLService" ref="dubboXMLServiceImpl" version="1.0.0"/>
A configuração do arquivo XML do consumidor de serviço:
<dubbo:reference id="dubboXMLService" interface="com.wyz.api.DubboXMLService" version="1.0.0"/>
O método de configuração do arquivo XML pode ser usado diretamente @Autowired
para injetar diferentes versões do serviço, portanto não entraremos em detalhes aqui.
Hoje, entendemos e aprendemos como configurar e usar os recursos de governança de serviço fornecidos pelo Dubbo.
Além dos recursos de governança de serviço mencionados acima, o Dubbo também fornece recursos de roteamento de serviço. Antes do Dubbo 2.7, as <dubbo:route>
regras de roteamento podiam ser configuradas por meio de rótulos, mas após o Dubbo 2.7, o rótulo oficial foi removido e um conjunto de registros dependentes <dubbo:route>
foi introduzido. será acompanhado de um artigo extra, que irá migrar a central de cadastro para Nacos e aprender a configurar as regras de roteamento.
Se este artigo for útil para você, dê-lhe muitos elogios e apoio. Se houver algum erro no artigo, por favor, critique e corrija. Por fim, dê as boas-vindas a todos para prestar atenção em Wang Youzhi, um pescador , e até a próxima!