Ao configurar a interoperabilidade entre serviços Dubbo 3 e APIs Spring Cloud, é comum encontrar desafios, especialmente ao consumir serviços Feign a partir de uma aplicação Dubbo. Um erro frequente é No provider available from registry RegistryDirectory, indicando que o consumidor Dubbo não consegue localizar a instância do serviço Spring Cloud registrada.
Este problema geralmente se manifesta mesmo com configurações de registro aparentemente corretas, onde o serviço Spring Cloud está devidamente registrado no Nacos e acessível por outros clientes Spring Cloud. A seguir, detalharemos um cenário de configuração inicial que pode levar a esse erro e, posteriormente, a solução.
Configuração Inicial e o Problema
Considere um consumidor Dubbo configurado para interagir com um serviço Spring Cloud denominado servico-produto-sc. As dependências Maven típicas em um projeto consumidor Dubbo que tenta integrar-se ao Spring Cloud Feign seriam:
<dependencies>
<!-- Dubbo Spring Boot Starter para integração com Spring Boot -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.3.1</version> <!-- Versão mais recente que pode causar o problema -->
</dependency>
<!-- Conector do Dubbo para o registro Nacos -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- Starter do Spring Cloud OpenFeign para chamadas HTTP declarativas -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
</dependencies>
O arquivo application.yml do consumidor Dubbo é configurado para apontar para o servidor Nacos:
dubbo:
application:
name: consumidor-dubbo-nacos
qos-enable: false
registry:
address: nacos://127.0.0.1:8848
register-mode: instance # Modo de registro como instância no Nacos
A interface Feign, que o consumidor Dubbo utilizará para invocar o serviço Spring Cloud (garantindo que o serviço Spring Cloud correspondente esteja devidamente registrado e em execução no Nacos), seria definida como:
package com.example.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// A anotação @FeignClient mapeia para o nome do serviço Spring Cloud registrado no Nacos.
@FeignClient(name = "servico-produto-sc")
public interface ServicoSaudacao {
// Define um endpoint GET para o caminho /saudacao/{entrada}
@GetMapping(path = "/saudacao/{entrada}")
String saudar(@PathVariable("entrada") String entrada);
}
A classe principal da aplicação consumidora Dubbo incluiria as anotações necessárias para habilitar o Dubbo e o Feign:
package com.example.consumer;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDubbo // Habilita o suporte ao Dubbo na aplicação Spring Boot
@EnableFeignClients // Habilita a varredura de interfaces Feign
public class AplicacaoConsumidoraDubbo {
public static void main(String[] args) {
SpringApplication.run(AplicacaoConsumidoraDubbo.class, args);
}
}
Para testar a invocação, um componente implementando CommandLineRunner pode ser usado para executar lógica após a inicialização da aplicação:
package com.example.consumer;
import com.example.service.ServicoSaudacao;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class OrquestradorServico implements CommandLineRunner {
// Injeta a referência Dubbo para a interface Feign.
// 'providedBy' deve ser o nome do serviço Spring Cloud no Nacos.
// 'check = false' evita falha na inicialização se o provedor não estiver imediatamente disponível.
@DubboReference(providedBy = "servico-produto-sc", check = false)
private ServicoSaudacao servicoSaudacao;
@Override
public void run(String... args) throws Exception {
String mensagem = "Mundo do Dubbo";
String resultado = servicoSaudacao.saudar(mensagem);
System.out.println("Resposta recebida do serviço Spring Cloud: " + resultado);
}
}
Ao executar a aplicação com as configurações acima, o resultado esperado foi uma falha com o erro No provider available from registry RegistryDirectory, apesar do serviço Spring Cloud estar ativo e acessível no Nacos.
Identificação e Resolução do Problema
A pesquisa em repositórios oficiais do Dubbo e discussões da comunidade confirmou que a integração com clientes Feign é um recurso suportado pelo Dubbo 3.x. No entanto, a persistência do erro sugeriu uma causa mais sutil do que uma simples configuração incorreta ou falta de suporte.
A hipótese de uma incompatibilidade de versão ou de uma dependência transitiva ausente para o cliente HTTP subjacente do Feign surgiu. Tentativas iniciais de atualizar o Dubbo para versões ainda mais recentes não resolveram o problema. Contudo, a estratégia de reverter para uma versão ligeiramente mais antiga do Dubbo e adicionar explicitamente um cliente HTTP ao projeto foi a chave para a solução. Parecia que, em certas versões mais novas do Dubbo (ou em certas combinações de dependências), o cliente HTTP necessário para o Feign não estava sendo incluído automaticamente ou a maneira como era resolvido havia mudado.
A configuração de dependências que finalmente resolveu o problema é a seguinte:
<dependencies>
<!-- Versão do Dubbo Spring Boot Starter ajustada para uma anterior -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.17</version> <!-- Versão que demonstrou funcionalidade -->
</dependency>
<!-- Adição explícita do cliente HTTP OkHttp, essencial para o Feign -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
</dependency>
<!-- As demais dependências devem manter a coerência de versão com o Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
<version>3.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
</dependencies>
Com essa alteração nas dependências do projeto consumidor Dubbo, especificamente o downgrade do dubbo-spring-boot-starter para a versão 3.2.17 e a adição explícita da dependência do cliente HTTP okhttp (versão 4.11.0), a aplicação conseguiu se conectar com sucesso ao serviço Spring Cloud via Feign, invocando a API e exibindo a resposta esperada no console.