Spring/Nacos/Duboo 实现远程方法调用

Posted by aclyyx on 07-05,2021

版本说明

一切抛开版本谈技术实现的文章都是偷走我们时间的强盗行为。

  • Sping Boot: 2.4.6
  • Sping Cloud: 2020.0.2
  • Nacos: 2.0.2
  • com.alibaba.cloud:spring-cloud-starter-dubbo: 2021.1

版本尽量(一定)要对应,否则后果自负。

动手做

模块定义

推荐新建两个子模块。一个是用于接口定义,提供者和消费者都需要引入的API接口定义;另一个是提供者,也就是接口的具体功能实现。

接口定义模块

这个模块没什么特别的,就是一个普通的Java(Maven)模块,在src中创建package,并在package中新建interface定义接口方法。

public interface UtilService {

    String generateId();

}

提供者模块

  • pom.xml文件中首先引入上面定义的接口模块,如:
<dependency>
    <groupId>com.aclyyx.xxx</groupId>
    <artifactId>dubbo-service-api</artifactId>
    <version>${project.version}</version>
</dependency>
  • 同时需要引入Spring和Dubbo相关的包:
<!-- 用于自动配置,通过 Nacos 配置 SpringBoot 服务之外,还通过 Nacos 配置 Dubbo 相关服务 -->
<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<!-- 引入 Dubbo 依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
    <version>2021.1</version>
</dependency>
<!-- 相关依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>
  • 实现自定义的接口
import com.alibaba.dubbo.config.annotation.Service;
import com.xnbackpack.web.service.api.UtilService;

@Service(version = "${dubbo.service.version}")
public class UtilServiceImpl implements UtilService {

    @Override
    public String generateId() {
        return String.valueOf(System.currentTimeMillis());
    }
}
  • 创建服务启动类 Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.aclyyx.xxx")
public class ServiceUtilApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceUtilApplication.class, args);
    }
}
  • 配置 bootstrap.yml
spring:
  profiles:
    active: dev
  application:
    name: service-util #定义应用名称
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
  • 配置 application.yaml
server:
  port: 8083

dubbo:
  scan:
    base-packages: com.aclyyx.service
  protocol: # 注意,如果使用Nacos配置中心,该节点需要定义在 application.yaml 文件中,定义在Nacos里不起作用
    name: dubbo
    port: '20881'
  service:
    version: 1.0.0
  registry:
    address: nacos://127.0.0.1:8848
  cloud:
    subscribed-services: service-util

logging:
  level:
    com.alibaba.nacos.client.naming: warn
  • 启动程序

成功启动服务后,在 Nacos 的服务列表中可以看到一下多出3个服务。一个是Application程序本身;一个是自定义的Service服务(本例中为 UtilService);一个是 DubboMetadataService,Dubbo 发现服务中要用到的服务。

Dubbo2021070501

同样的,Nacos 的配置列表中也多出了很多配置信息,如下图:

Dubbo2021070502

消费者模块

  • 消费者模块同样需要引入 自定义的接口依赖和 Dubbo 依赖。
<dependency>
    <groupId>com.aclyyx.xxx</groupId>
    <artifactId>dubbo-service-api</artifactId>
    <version>${project.version}</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
    <version>2021.1</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>
  • 配置 bootstrap.yml
spring:
  profiles:
    active: dev
  application:
    name: webapi #定义应用名称
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.21:8848
      config:
        server-addr: 192.168.1.21:8848
        file-extension: yaml
  • 配置 application.yml
... ....
dubbo:
  protocol:
    name: dubbo
    port: '20882'
  service:
    version: 1.0.0
  registry:
    address: nacos://127.0.0.1:8848
  cloud:
    subscribed-services: service-util
  • 编写 Service 调用 Dubbo 接口
@Service
public class DemoService {

    @Reference(version = "${dubbo.service.version}")
    private UtilService utilService;

    public String generateId() {
        return utilService.generateId();
    }
}