Configuração XML do Dubbo para Exemplo de Início Rápido

O Apache Dubbo é um framework de serviços de alto desempenho desenvolvido pela Alibaba e atualmente mantido como projeto top-level pelo Apache. Ele oferece capacidades essenciais de comunicação RPC e governança de microserviços. Ao desenvolver microserviços com Dubbo, eles conseguem descobrir e se comunicar remotamente entre si, além de utiilzar as poderosas funcionalidades de governança para implementar soluções como descoberta de serviços, balanceamento de carga e roteamento de tráfego. Este artigo apresenta a integração do Dubbo com o SpringMvc através de configuração via arquivo XML, executando o exemplo básico em um ambiente web. O código fonte estará disponível ao final deste artigo.

Para informações detalhadas sobre Dubbo, visite o site oficial: https://dubbo.apache.org/zh/index.html

1. Configuração do Registro Zookeeper

O diagrama arquitetural oficial do Dubbo mostra que uma aplicação mínima requer três componentes: o registro, provedor de serviço e consumidor de serviço. Não abordaremos monitoramento neste momento, pois o próprio projeto não oferece ferramentas adequadas, mas isso será tratado em um próximo artigo com a instalação do DubboAdmin.

O funcionamento do Dubbo é intuitivo: o provedor registra seus endereços de interface no registro, o consumidor recupera esses endereços e chama os métodos remotos. Quando há mudanças nos endereços, o registro notifica automaticamente o consumidor. Geralmente, provedores e consumidores estão em máquinas distintas, ocultando complexidade da comunicação remota, tornando-a tão simples quento chamadas locais, aumentando significativamente a produtividade no desenvolvimento distribuído.

O registro mais utilizado é o Zookeeper, uma excelente ferramenta de coordenação distribuída. A instalação em Windows é direta. Como tenho limitações de hardware, optei por mostrar a instalação no Windows.

Baixe o Zookeeper no site oficial: https://zookeeper.apache.org/releases.html

Descompacte o pacote baixado (ex: apache-zookeeper-3.7.1-bin.tar.gz). Mude o nome da pasta para "zookeeper" e crie uma subpasta "zkdata" para armazenar dados:

Edite o arquivo zoo.cfg na pasta conf, alterando apenas:

dataDir=D:/Develop/zookeeper/zkdata
clientPort=2181

Execute o script zkServer.cmd na pasta bin para iniciar o servidor.

Para instalar como serviço Windows, utilize o nssm.exe (download: http://www.nssm.cc/download), copie o executável para a pasta bin do Zookeeper e execute:

D:\Develop\zookeeper\bin\nssm.exe install

Preencha os campos solicitados, especificando o caminho completo do zkServer.cmd, diretório de inicialização e nome do serviço (ex: ZookeeperService).

2. Definição de Interface Comum

Este exemplo usa Maven com módulos separados: interface compartilhada, serviço Dubbo e cliente Dubbo.

Na interface compartilhada, defina a interface TestService:

package com.jobs.service;

public interface TestService {
    String GetMsg(String name);
    int GetCal(int a, int b);
}

3. Servidor Dubbo

O servidor precisa implementar a interface e registrar o serviço no Zookeeper. Para manter o servidor ativo, integre com SpringMvc em um contexto web.

Dependências necessárias:

<dependencies>
    <dependency>
        <groupId>com.jobs</groupId>
        <artifactId>dubbo_interface</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
    </dependency>
</dependencies>

Implementação do serviço:

package com.jobs.service.impl;

import com.jobs.service.TestService;
import org.apache.dubbo.config.annotation.Service;

@Service
public class TestServiceImpl implements TestService {
    @Override
    public String GetMsg(String name) {
        return "Hello " + name;
    }

    @Override
    public int GetCal(int a, int b) {
        return a + b;
    }
}

Arquivo de configuração SpringConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <dubbo:application name="dubbo-service"/>
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <dubbo:annotation package="com.jobs.service.impl" />
    <dubbo:protocol name="dubbo" port="20880"/>
    <dubbo:metadata-report address="zookeeper://localhost:2181" />
</beans>

Configuração web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:SpringConfig.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

4. Cliente Dubbo

O cliente conecta-se ao registro, obtém os endereços dos serviços e realiza chamadas. Para testes, integramos ao SpringMvc com endpoints REST.

package com.jobs.controller;

import com.jobs.service.TestService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/test")
public class TestController {
    @Reference
    private TestService testService;

    @RequestMapping("/getmsg")
    public String GetMsg(String name) {
        return testService.GetMsg(name);
    }

    @GetMapping("/getcal/{num1}/{num2}")
    public int GetCal(@PathVariable("num1") int a, @PathVariable("num2") int b) {
        return testService.GetCal(a, b);
    }
}

Configuração SpringMvcConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <mvc:annotation-driven/>
    <context:component-scan base-package="com.jobs.controller"/>

    <dubbo:application name="dubbo-client">
        <dubbo:parameter key="qos.port" value="22223"/>
    </dubbo:application>
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <dubbo:annotation package="com.jobs.controller"/>
</beans>

web.xml para cliente:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:SpringMvcConfig.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

Execute primeiro o servidor Dubbo, depois o cliente, e teste acessando os endpoints.

Versões das dependências do projeto pai:

<properties>
    <spring.version>5.3.18</spring.version>
    <dubbo.version>2.7.4.1</dubbo.version>
    <zookeeper.version>4.0.0</zookeeper.version>
    <slf4j.version>1.7.21</slf4j.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.jobs</groupId>
            <artifactId>dubbo_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Download do exemplo: https://files.cnblogs.com/files/blogs/699532/DubboDemo.zip

Tags: dubbo zookeeper SpringMVC XML configuracao

Publicado em 10-21 05:43