Alibaba spring cloud Dubbo使用(基于Zookeeper或者基于Nacos+泛化调用完整代码一键启动)

Quick Start

Dubbo!用更优雅的方式来实现RPC调用吧 - 掘金

dubbo+zookeeper demo

项目结构:

在这里插入图片描述

RpcService

仅仅是提供服务的接口:

public interface HelloService {
    String sayHello(String name);
}

DubboServer

pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>DubboServer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DubboServer</name>
    <description>DubboServer</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

        <!-- Dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!-- Spring Context Extras -->
        <dependency>
            <groupId>com.alibaba.spring</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.12</version>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>RpcService</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <!-- 这是个编译java代码的 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

DubboServerApplication:

package com.example.dubboserver;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.example.dubboserver"})
public class DubboServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboServerApplication.class, args);
    }

}

HelloServiceImpl实现dubbo服务:

package com.example.dubboserver;

import com.alibaba.dubbo.config.annotation.Service;
import com.example.rpcservice.HelloService;
import org.springframework.stereotype.Component;

@Component
@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "hello " + name + "!";
    }
}

配置文件application.yaml:

dubbo:
  application:
    name: example-provider
  registry:
    address: zookeeper://43.143.229.22:2181
  protocol:
    name: dubbo
    port: 20880

zookeeper是我的一台云服务器,zookeeper需要先部署好。

DubboClient

pom文件与Server相似:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>DubboClient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DubboClient</name>
    <description>DubboClient</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>RpcService</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

        <!-- Dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!-- Spring Context Extras -->
        <dependency>
            <groupId>com.alibaba.spring</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.12</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>

</project>

DubboClientApplication:

package com.example.dubboclient;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.example.dubboclient"})
public class DubboClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboClientApplication.class, args);
    }

}

RpcService:

package com.example.dubboclient;

import com.alibaba.dubbo.config.annotation.Reference;
import com.example.rpcservice.HelloService;
import org.springframework.stereotype.Service;

@Service
public class RpcService {
    @Reference
    private HelloService helloService;

    public String getHelloServiceResponse(String name) {
        return helloService.sayHello(name);
    }
}

通过Reference注解标识这是一个dubbo服务接口。

TriggerController:(通过get方法触发dubbo调用,debug用)

package com.example.dubboclient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo/dubbo")
public class TriggerController {
    @Autowired
    private RpcService rpcService;

    @GetMapping("/{name}")
    public String getTime(@PathVariable("name") String name) {
        return rpcService.getHelloServiceResponse(name);
    }

}

配置文件:

server:
  port: 8081
dubbo:
  application:
    name: example-consumer
  registry:
    address: zookeeper://43.143.229.22:2181
    client: curator
  protocol:
    name: dubbo
  server: false
  consumer:
    timeout: 3000

dubbo使用nacos作为注册中心

dubbo也可以用nacos作为注册中心。使用docker一键启动nacos2: docker run --name nacos-quick -e MODE=standalone -p 8848:8848 -p 9848:9848 -p 9849:9849 -d nacos/nacos-server:2.0.2 ,如果是部署在云服务器上的话记得防火墙暴露接口。

client和server的代码与上面zookeeper的一致,但是依赖和配置换了,依赖采用alibaba-spring-cloud来提供。这里我为了方便没有创建父项目写dependencyManagement,而是直接在子项目写来管理包版本,这种做法不是很规范。

Server

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>DubboServer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DubboServer</name>
    <description>DubboServer</description>
    <properties>
        <spring-cloud-clibaba.version>2021.0.1.0</spring-cloud-clibaba.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- spring cloud 版本控制 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring cloud alibaba 版本控制 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-clibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- nacos 配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

        <dependency>
            <groupId>com.example</groupId>
            <artifactId>RpcService</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <!-- 这是个编译java代码的 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

application.yaml:

spring:
  main:
    # spring boot 2.6.3默认不允许循环依赖, dubbo的这个版本存在循环依赖
    allow-circular-references: true
  application:
    name: demo-server
  cloud:
    nacos:
      config:
        enable: false
      discovery:
        server-addr: 123.56.98.228:8848
        namespace: public

dubbo:
  consumer:
    retries: 5
  protocol:
    port: -1
    name: dubbo
  scan:
    # 扫描实现类的包路径(可配置多个或数组)
    base-packages: com.example.dubboserver # 更改为自己dubbo实现类的路径
  registry:
    address: nacos://${spring.cloud.nacos.discovery.server-addr}?namespace=${spring.cloud.nacos.discovery.namespace}
  cloud:
    # 默认*订阅所有, 所以在此处写一个不存在的提供者
    # (可订阅多个用,隔开或者用数组的配置方式 -: name)
    subscribed-services: "-"

client

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
        <artifactId>DubboClient</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>DubboClient</name>
    <description>DubboClient</description>

    <properties>
        <spring-cloud-clibaba.version>2021.0.1.0</spring-cloud-clibaba.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- spring cloud 版本控制 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring cloud alibaba 版本控制 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-clibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>RpcService</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- nacos 配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>

</project>

application.yaml:

spring:
  main:
    # spring boot 2.6.3默认不允许循环依赖, dubbo的这个版本存在循环依赖
    allow-circular-references: true
  application:
    name: demo-client
  cloud:
    nacos:
      config:
        enable: false
      discovery:
        server-addr: 123.56.98.228:8848
        namespace: public

dubbo:
  consumer:
    retries: 5
  protocol:
    port: -1
    name: dubbo # 协议名称

测试

先上nacos看看服务 ip:8848/nacos:

在这里插入图片描述

其中有一个是dubbo自己的服务,剩下三个一个是client应用,一个是server应用,一个是暴露的RpcService服务。

浏览器输入:http://localhost:8080/demo/dubbo/dsasdfaasdf

响应:

在这里插入图片描述

没啥问题。

dubbo泛化调用

dubbo泛化调用即在调用方不引入服务方接口包的情况下直接调用服务接口。

适用场景:

比如你做了一个网关项目,网关需要调用后端的多个服务的多个接口,这些接口假如都是dubbo,网关需要引入所有服务的接口包才能调用,这显然不太合理,网关的代码应该和后端服务解耦。

那如何实现泛化调用呢?

  1. 服务方不需要更改配置。
  2. 调用方更改rpc调用的代码。

不使用泛化调用的代码:

@Service
public class RpcService {
    @Reference
    private HelloService helloService; // 普通调用

    public String getHelloServiceResponse(String name) {
        return helloService.sayHello(name); // 普通调用
    }
}

改为泛化调用:

@Service
public class RpcService {

    @DubboReference(interfaceName = "com.example.rpcservice.HelloService", generic = true)
    private GenericService genericService;

    public String getHelloServiceResponse(String name) {
        Object res = genericService.$invoke("sayHello" , new String[]{"java.lang.String"},
                new Object[]{name});
        return (String) res;
    }
}

可以看到将原本的具体的Service接口改为了GenericService, @DubboReference中写明了调用的接口全限定名称,并且generic打开为true。

至此完成泛化调用改动,还是挺简单的。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-23 12:44:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-23 12:44:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-23 12:44:02       82 阅读
  4. Python语言-面向对象

    2024-03-23 12:44:02       91 阅读

热门阅读

  1. springboot 单元测试

    2024-03-23 12:44:02       44 阅读
  2. 富格林:重视平台挑选阻挠虚假

    2024-03-23 12:44:02       45 阅读
  3. 工作量证明机制

    2024-03-23 12:44:02       39 阅读
  4. python课程学习代码:调用接口

    2024-03-23 12:44:02       43 阅读
  5. pytorch中的梯度裁剪

    2024-03-23 12:44:02       41 阅读
  6. 【科普向】什么是数据湖架构

    2024-03-23 12:44:02       41 阅读
  7. LeetCode的LRU缓存实现

    2024-03-23 12:44:02       37 阅读
  8. 69、FIFO缓存发送数据(先入先出)

    2024-03-23 12:44:02       45 阅读
  9. ubuntu生成 设置 core文件

    2024-03-23 12:44:02       38 阅读
  10. Vue 常见面试题(一)

    2024-03-23 12:44:02       39 阅读
  11. 0x01_实验课leetcode

    2024-03-23 12:44:02       41 阅读
  12. [leetcode] 21. 合并两个有序链表

    2024-03-23 12:44:02       45 阅读
  13. 数学系的数字信号处理:傅立叶变换

    2024-03-23 12:44:02       39 阅读
  14. android gdb 调试

    2024-03-23 12:44:02       47 阅读