前言

在日常的开发过程中,都开始从传统架构项目转化为微服务架构模式,把整体项目按照功能模块或者业务等做拆分,形成很多个服务,那么服务与服务之间就会产生调用关系。

常见的远程调用有两种,一种是Feign,另一种是Rpc。在本文介绍Dubbo Rpc与Alibaba SpringCloud、Nacos的集成。


提示:以下是本篇文章正文内容,下面案例可供参考

一、创建提供方项目

项目命名为server-dubbo-provider

  1. 引入pom依赖
<dependencies>
  <!-- 提供方Api定义 -->
    <dependency>
        <groupId>com.lee</groupId>
        <artifactId>server-dubbo-provider-api</artifactId>
        <version>1.0.0</version>
    </dependency>
    <!--阿里巴巴 nacos 服务发现-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!-- cloud-dubbo依赖 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-dubbo</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>
</dependencies>
  1. 创建bootstrap.yml文件
server:
    port: 10201

spring:
    application:
        name: server-dubbo-provider #项目名称
    cloud:
        nacos:
            discovery:
                namespace: ed82a624-eb8b-49d7-a7d7-4ad2c63d8b47 # 命名空间id
                server-addr: 192.168.0.130:8848  #注册中心地址
    main:
        allow-bean-definition-overriding: true
    mvc:
        throw-exception-if-no-handler-found: true

# Dubbo服务配置
dubbo:
    scan:
        base-packages: com.lee.provider.service #扫描包范围
    protocol:
        name: dubbo # 遵循的协议
        port: 19003 #dubbo服务端口
    registry:
        address: spring-cloud://localhost # 将dubbo挂载到注册中心,和<dubbo-registry address='zk地址'>一样

management:
    endpoints:
        web:
            exposure:
                include: '*'

上述配置说明

1. spring.cloud.nacos.discovery.namespace:命名空间id
2. spring.cloud.nacos.discovery.server-addr :注册中心地址
3. dubbo.scan.base-packages:扫描包范围
4. dubbo.protocol.name:遵循的协议
5. dubbo.protocol.port:dubbo服务端口
6. dubbo.registry.address=将dubbo挂载到注册中心,和<dubbo-registry address='zk地址'>一样
  1. 在server-dubbo-provider-api项目中创建服务接口
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@RequestMapping("/dubboProvider")
public interface IDubboProviderService {

    /**
     * 获取信息
     * @param info
     * @return
     */
    @GetMapping("/getRemoteDubboInfo")
    String getRemoteDubboInfo(@RequestParam(value = "info") String info);
}
  1. 在server-dubbo-provider中实现IDubboProviderService接口
    server-dubbo-provider-api模块已引入在server-dubbo-provider中
@org.apache.dubbo.config.annotation.Service
public class DubboProviderServiceImpl implements IDubboProviderService {
    public String getRemoteDubboInfo(String info) {
        return "Dubbo Provider Response :"+info;
    }
}

Service注解一定要使用dubbo.config包中的。

二、创建消费方项目

项目命名为server-dubbo-consumer

  1. 引入pom依赖
<!-- 引入provider-api -->
<dependency>
     <groupId>com.lee</groupId>
     <artifactId>server-dubbo-provider-api</artifactId>
     <version>1.0.0</version>
 </dependency>
 <!--nacos config配置中心依赖-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-alibaba-nacos-config</artifactId>
 </dependency>
 <!-- feign依赖 -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
     <version>2.2.5.RELEASE</version>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
     <exclusions>
         <exclusion>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-tomcat</artifactId>
         </exclusion>
     </exclusions>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-undertow</artifactId>
 </dependency>
 <!--阿里巴巴 nacos 服务发现-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
 <!-- cloud-dubbo依赖 -->
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-dubbo</artifactId>
     <version>2.1.1.RELEASE</version>
 </dependency>
  1. 创建bootstrap.yml文件
server:
    port: 10301

spring:
    application:
        name: server-dubbo-consumer # 项目名称
    cloud:
        nacos:
            discovery:
                namespace: ed82a624-eb8b-49d7-a7d7-4ad2c63d8b47 # 命名空间
                server-addr: 192.168.0.130:8848 #注册中心地址
            config:
                namespace: ed82a624-eb8b-49d7-a7d7-4ad2c63d8b47 # 命名空间
                server-addr: 192.168.0.130:8848 #配置中心地址
    main:
        allow-bean-definition-overriding: true
    mvc:
        throw-exception-if-no-handler-found: true
# Dubbo服务配置
dubbo:
    protocol:
        name: dubbo # 遵循的协议
        port: 18002 # dubbo端口号,保持唯一
    registry:
        address: spring-cloud://localhost # 将dubbo挂载到注册中心
    cloud:
        subscribed-services: server-dubbo-provider #订阅的服务,可有多个,如果有多个,以逗号隔开。与Dubbo一样
management:
    endpoints:
        web:
            exposure:
                include: '*'

上述配置说明:

dubbo.cloud.subscribed-services:订阅的服务,可有多个,如果有多个,以逗号隔开。与Dubbo一样
  1. 编写controller调用
import com.lee.consumer.feign.ProviderFeign;
import com.lee.service.IDubboProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private ProviderFeign providerFeign ;
    @Value("${consumer.name}")
    private String consumerName ;
	@Value("${age}")
    private String age ;
    @org.apache.dubbo.config.annotation.Reference
    private IDubboProviderService iDubboProviderService ;

    /**
     * dubbo 远程调用
     * @param info
     * @return
     */
    @GetMapping("/getDubboRemoteInfo")
    public String getDubboRemoteInfo(@RequestParam("info") String info){

        return iDubboProviderService.getRemoteDubboInfo(info+",消费者名称:"+consumerName+",年龄:"+age);
    }

    /**
     * feign 远程调用
     * @param info
     * @return
     */
    @GetMapping("/getFeignRemoteInfo")
    public String getFeignRemoteInfo(@RequestParam("info") String info){

        return providerFeign.getRemoteFeignInfo(info+",消费者名称:"+consumerName);
    }
}

上述配置描述

1. @Value("${consumer.name}")表示从nacos上获取配置
2. @org.apache.dubbo.config.annotation.Reference:生成代理对象,就像调用本地方法一样调用远程业务方法	
3. 配置文件读取规则:
spring.cloud.nacos.config.prefix:为Data ID,默认为服务名称 server-dubbo-consumer
spring.cloud.nacos.config.file-extension:默认为.properties
spring.cloud.nacos.config.group:默认为DEFAULT_GROUP
如果在多环境配置下可以使用spring.profile.active=online来区分加载生产或者测试环境配置
完整的规则为${spring.cloud.nacos.config.prefix}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
  1. 如果有其他的一些公共配置或者比较特殊配置加载,可以使用 ext-config来实现
nacos:
  discovery:
      namespace: ed82a624-eb8b-49d7-a7d7-4ad2c63d8b47 # 命名空间
      server-addr: 192.168.0.130:8848 #注册中心地址
  config:
      namespace: ed82a624-eb8b-49d7-a7d7-4ad2c63d8b47 # 命名空间
      server-addr: 192.168.0.130:8848 #配置中心地址
      ext-config:
          - data-id: test.properties
            group: DEFAULT_GROUP
            refresh: true
  1. 配置中心详情
  2. 以项目名称命名的配置文件:server-dubbo-consumer.properties
  3. dubbo和nacos区别 nacos与dubbo集成_ide


  4. 以ext-config:扩展的配置文件test.properties详情:
  5. dubbo和nacos区别 nacos与dubbo集成_ide_02

  6. 访问接口
    http://localhost:10301/consumer/getDubboRemoteInfo?info=消费者消费dubbo和nacos区别 nacos与dubbo集成_命名空间_03
    可以看到consumer.name属性不会被ext-config扩展配置覆盖,而年龄这个属性只在扩展配置中存在,所以ext-config优先级小于第一种配置规则。