依赖配置

  • SpringCloud 2021.0.1
  • Dubbo 3.0.6
  • 文章中使用的项目链接: RuoYi-Cloud-Plus

根pom中:
spring cloud版本:

<spring-cloud.version>2021.0.3</spring-cloud.version>

...

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-dependencies</artifactId>
  <version>${spring-cloud.version}</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

ruoyi-common-alibaba-bom中的pom:
引入dubbo

<dubbo.version>3.0.10</dubbo.version>

<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId>
  <version>${dubbo.version}</version>
</dependency>

<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-spring-boot-actuator</artifactId>
  <version>${dubbo.version}</version>
</dependency>

<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo</artifactId>
  <version>${dubbo.version}</version>
</dependency>

这里解释一下为什么不用 Spring-Cloud-Alibaba 的 Dubbo 依赖

<dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-dubbo</artifactId>
        <version>2021.1</version>
      </dependency>

这个依赖主要是负责处理兼容 Feign 的 Dubbo 代理配置 通过 Feign 做服务发现
项目中 如果统一使用 Dubbo 则不需要使用这个依赖 在后续版本 官方也宣布此模块从主分支移除
况且 Dubbo 3.0 已经支持 基于应用服务的发现机制 故完全没必要与 Feign 做兼容处理
application-common.yml中:
注意,registry必须通过group和namespace和nacos进行隔离,否则会出现异常

dubbo:
  application:
    logger: slf4j
    # 元数据中心 local 本地 remote 远程 这里使用远程便于其他服务获取
    metadataType: remote
    # 可选值 interface、instance、all,默认是 all,即接口级地址、应用级地址都注册
    register-mode: instance
    service-discovery:
      # FORCE_INTERFACE,只消费接口级地址,如无地址则报错,单订阅 2.x 地址
      # APPLICATION_FIRST,智能决策接口级/应用级地址,双订阅
      # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
      migration: FORCE_APPLICATION
  protocol:
    # 设置为 tri 即可使用 Triple 3.0 新协议
    # 性能对比 dubbo 协议并没有提升 但基于 http2 用于多语言异构等 http 交互场景
    # 使用 dubbo 协议通信
    name: dubbo
    # dubbo 协议端口(-1表示自增端口,从20880开始)
    port: -1
    # 指定dubbo协议注册ip
    # host: 192.168.0.100
  # 注册中心配置
  registry:
    address: nacos://${spring.cloud.nacos.server-addr}
    group: DUBBO_GROUP
    parameters:
      namespace: ${spring.profiles.active}
  # 消费者相关配置
  consumer:
    # 结果缓存(LRU算法)
    # 会有数据不一致问题 建议在注解局部开启
    cache: false
    # 支持校验注解
    validation: true
    # 超时时间
    timeout: 3000
    # 初始化检查
    check: false
  scan:
    # 接口实现类扫描
    base-packages: com.ruoyi.**.dubbo
  # 自定义配置
  custom:
    # 全局请求log
    request-log: true
    # info 基础信息 param 参数信息 full 全部
    log-level: info

业务中使用

远程接口

ruoyi-api中新建一个xiaoqiang-api-crm,ruoyi-api用于所有远程访问模块存放,根据各个微服务名称进行分别命名。

Dubbo 还是 OpenFeign dubbo与feign_spring boot

xiaoqiang-api-crm 中的pom,因为使用了bo,所以需要引入excel依赖。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <parent>
    <artifactId>ruoyi-api</artifactId>
    <groupId>com.ruoyi</groupId>
    <version>1.2.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>

  <artifactId>xiaoqiang-api-crm</artifactId>
  <description>
    xiaoqiang-api-crm
  </description>

  <dependencies>

    <!-- RuoYi Common Core-->
    <dependency>
      <groupId>com.ruoyi</groupId>
      <artifactId>ruoyi-common-core</artifactId>
    </dependency>
    <dependency>
      <groupId>com.ruoyi</groupId>
      <artifactId>ruoyi-common-excel</artifactId>
    </dependency>

  </dependencies>
</project>

注意,所有的参与传输的实体类都需要implements Serializable

Dubbo 还是 OpenFeign dubbo与feign_spring boot_02

bo的父类实现了Serializable

Dubbo 还是 OpenFeign dubbo与feign_Dubbo 还是 OpenFeign_03

Dubbo 还是 OpenFeign dubbo与feign_spring_04

ruoyi-api-bom中的pom定义好版本,这样其他模块调用时就不用引入版本了。

Dubbo 还是 OpenFeign dubbo与feign_Dubbo 还是 OpenFeign_05

Dubbo 还是 OpenFeign dubbo与feign_Dubbo 还是 OpenFeign_06

xiaoqiang-api-crm中创建RemoteCompanyService
一个简单的实现,取得company的list

package com.xiaoqiang.crm.api;

import com.xiaoqiang.crm.api.bo.CompanyBo;
import com.xiaoqiang.crm.api.vo.CompanyVo;

import java.util.List;

public interface RemoteCompanyService {

    List<CompanyVo> queryList(CompanyBo bo);
}

接口实现

提供者

实现现在了xiaoqiang-crm微服务中,直接参考ruoyi cloud plus的目录结构规范:

Dubbo 还是 OpenFeign dubbo与feign_Dubbo 还是 OpenFeign_07

xiaoqiang-crm的pom中需增加依赖:

<dependency>
  <groupId>com.ruoyi</groupId>
  <artifactId>xiaoqiang-api-crm</artifactId>
</dependency>

由于api中的vo,bo与微服务中的包不一致,会发生冲突,简单的办法就是直接在mapper中定义了专属远程的RemoteCompanyMapper

package com.xiaoqiang.crm.mapper;

import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import com.xiaoqiang.crm.domain.Company;
import com.xiaoqiang.crm.api.vo.CompanyVo;

/**
 * 客户关系-公司管理Mapper接口
 *
 * @author xiaoqiang
 * @date 2022-09-19
 */
public interface RemoteCompanyMapper extends BaseMapperPlus<RemoteCompanyMapper, Company, CompanyVo> {

}

dubbo中的RemoteCompanyServiceImpl
编写提供者接口实现
注意 注解为 @DubboService 标注为dubbo的service服务实现

package com.xiaoqiang.crm.dubbo;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.utils.StringUtils;
import com.xiaoqiang.crm.api.RemoteCompanyService;
import com.xiaoqiang.crm.api.bo.CompanyBo;
import com.xiaoqiang.crm.api.vo.CompanyVo;
import com.xiaoqiang.crm.domain.Company;
import com.xiaoqiang.crm.mapper.RemoteCompanyMapper;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@RequiredArgsConstructor
@Service
@DubboService
public class RemoteCompanyServiceImpl implements RemoteCompanyService {

    private final RemoteCompanyMapper remoteCompanyMapper;

    @Override
    public List<CompanyVo> queryList(CompanyBo bo) {
        LambdaQueryWrapper<Company> lqw = buildQueryWrapper(bo);
        return remoteCompanyMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Company> buildQueryWrapper(CompanyBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Company> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), Company::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getTel()), Company::getTel, bo.getTel());
        return lqw;
    }

}

消费者

使用ruoyi-system作为消费者
其pom中需要添加依赖:

<dependency>
  <groupId>com.ruoyi</groupId>
  <artifactId>xiaoqiang-api-crm</artifactId>
</dependency>

SysDictTypeServiceImpl中

Dubbo 还是 OpenFeign dubbo与feign_spring_08

实现了一个简单的打印调用

Dubbo 还是 OpenFeign dubbo与feign_spring_09

提供者响应:

Dubbo 还是 OpenFeign dubbo与feign_spring_10

消费者响应:

Dubbo 还是 OpenFeign dubbo与feign_java_11

nacos生成的元数据:

Dubbo 还是 OpenFeign dubbo与feign_Dubbo 还是 OpenFeign_12

服务中成功隔离的不同分组的服务:

Dubbo 还是 OpenFeign dubbo与feign_java_13

大功告成!