Integração Dubbo 3 e Spring Cloud: Resolvendo o Erro "No Provider Available"

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.

Tags: Dubbo3 SpringCloud Feign Nacos microservices

Publicado em 7-31 17:25