在微服务整合dubbo,以为微服务版的若依为例
- 一、环境
- 二、整合过程
- 1、父模块依赖
- 2、生产者
- 3、消费者
- 三、修改若依的服务调用方式为dubbo
- 1、改造系统模块
- 2、改造认证授权中心
- 四、整合过程遇到的问题
- 1、出现循环引用
- 2、出现依赖冲突
- 3、启动出现端口号被占用
- 4、出现某个类找不到
- 5、找不到生产者
一、环境
微服务版若依3.6.3
dubbo2021.0.1
nacos2.2.1
二、整合过程
1、父模块依赖
<?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"><modelVersion>4.0.0</modelVersion><groupId>com.ruoyi</groupId><artifactId>ruoyi</artifactId><version>3.6.3</version><name>human</name><url>http://www.ruoyi.vip</url><description>若依管理系统</description><properties><ruoyi.version>3.6.3</ruoyi.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-boot.version>2.7.13</spring-boot.version><spring-cloud.version>2021.0.8</spring-cloud.version><spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version><spring-boot-admin.version>2.7.10</spring-boot-admin.version><swagger.fox.version>3.0.0</swagger.fox.version><swagger.core.version>1.6.2</swagger.core.version><tobato.version>1.27.2</tobato.version><kaptcha.version>2.3.3</kaptcha.version><pagehelper.boot.version>1.4.7</pagehelper.boot.version><druid.version>1.2.16</druid.version><dynamic-ds.version>3.5.2</dynamic-ds.version><commons.io.version>2.11.0</commons.io.version><velocity.version>2.3</velocity.version><fastjson.version>2.0.34</fastjson.version><jjwt.version>0.9.1</jjwt.version><minio.version>8.2.2</minio.version><poi.version>4.1.2</poi.version><transmittable-thread-local.version>2.14.3</transmittable-thread-local.version><dubbo.version>2021.0.1.0</dubbo.version><hutool-all.version>5.8.16</hutool-all.version><lombok.version>1.18.24</lombok.version><minio.version>8.2.2</minio.version><guava.version>33.0.0-jre</guava.version></properties><!-- 依赖声明 --><dependencyManagement><dependencies><!-- SpringCloud 微服务 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringCloud Alibaba 微服务 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringBoot 依赖配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- FastDFS 分布式文件系统 --><dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>${tobato.version}</version></dependency><!-- Swagger 依赖配置 --><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>${swagger.core.version}</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>${swagger.core.version}</version></dependency><!-- 验证码 --><dependency><groupId>pro.fessional</groupId><artifactId>kaptcha</artifactId><version>${kaptcha.version}</version></dependency><!-- pagehelper 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper.boot.version}</version></dependency><!-- io常用工具类 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons.io.version}</version></dependency><!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version></dependency><!-- 代码生成使用模板 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>${velocity.version}</version></dependency><!-- JSON 解析器和生成器 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>${fastjson.version}</version></dependency><!-- JWT --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><!-- 线程传递值 --><dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>${transmittable-thread-local.version}</version></dependency><!-- 核心模块 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-core</artifactId><version>${ruoyi.version}</version></dependency><!-- 接口模块 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-swagger</artifactId><version>${ruoyi.version}</version></dependency><!-- 安全模块 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-security</artifactId><version>${ruoyi.version}</version></dependency><!-- 权限范围 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datascope</artifactId><version>${ruoyi.version}</version></dependency><!-- 多数据源 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datasource</artifactId><version>${ruoyi.version}</version></dependency><!-- 分布式事务 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-seata</artifactId><version>${ruoyi.version}</version></dependency><!-- 日志记录 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-log</artifactId><version>${ruoyi.version}</version></dependency><!-- 缓存服务 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-redis</artifactId><version>${ruoyi.version}</version></dependency><!-- 系统接口 --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-api-system</artifactId><version>${ruoyi.version}</version></dependency><!-- Dubbo --><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId><version>${dubbo.version}</version></dependency><!-- hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool-all.version}</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- Minio --><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>${minio.version}</version></dependency><!--这个依赖是整合dubbo时要用到的--><!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency></dependencies></dependencyManagement><modules><module>ruoyi-auth</module><module>ruoyi-gateway</module><module>ruoyi-visual</module><module>ruoyi-modules</module><module>ruoyi-api</module><module>ruoyi-common</module></modules><packaging>pom</packaging><dependencies><!-- bootstrap 启动器 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></pluginManagement></build><repositories><repository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></project>
2、生产者
因为我要调用若依的文件服务,所以直接将文件服务作为生产者。依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>com.ruoyi</groupId><artifactId>ruoyi-modules</artifactId><version>3.6.3</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ruoyi-modules-file</artifactId><description>ruoyi-modules-file文件服务</description><dependencies><!-- SpringCloud Alibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- SpringCloud Alibaba Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- SpringBoot Actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- FastDFS --><dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId></dependency><!-- RuoYi Api System --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-api-system</artifactId></dependency><!-- RuoYi Common Swagger --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-swagger</artifactId></dependency><!-- Dubbo --><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId></dependency><!-- hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!-- Minio --><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId></dependency><!-- Mysql Connector --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- RuoYi Common DataSource --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datasource</artifactId></dependency><!-- RuoYi Common DataScope --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datascope</artifactId></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
主要是这个依赖
<!-- Dubbo -->
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId><version>2021.0.1.0</version>
</dependency>
先在文件服务的 bootstrap.yml 加上如下配置,解决循环引用
# Tomcat
server:port: 9300# Spring
spring:application:# 应用名称name: ruoyi-filemain:allow-circular-references: true # 中断循环引用profiles:# 环境配置active: devcloud:nacos:discovery:# 服务注册地址server-addr: 127.0.0.1:8848config:# 配置中心地址server-addr: 127.0.0.1:8848# 配置文件格式file-extension: yml# 共享配置shared-configs:- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
如何在nacos中对应的配置文件中添加如下配置:
# dubbo相关配置
dubbo:protocol:name: dubbo # dubbo协议port: -1 # -1表示端口从20880开始递增,不会造成端口冲突registry:address: nacos://127.0.0.1:8848# check: false # dubbo默认有启动检查scan:base-packages: com.ruoyi.file.service
接着在启动类中加上 @EnableDubbo 注解
接着是dubbo的接口,接口放在这里
具体如下:
package com.ruoyi.system.api;import com.ruoyi.system.api.domain.SysFileInfo;
import org.springframework.web.multipart.MultipartFile;import java.util.List;/*** dubbo文件接口** @author:gan* @date: 2024-01-30 09:58*/
public interface DubboFileService {/*** 文件上传接口原始** @param file 上传的文件* @return 访问地址* @throws Exception*/String uploadFile(MultipartFile file) throws Exception;/*** 文件上传接口(自定义)** @param file 上传的文件* @param secondPath 文件二级路径* @return 访问地址* @throws Exception*/SysFileInfo upload(MultipartFile file, String secondPath) throws Exception;/*** 文件上传接口(自定义)** @param file 上传的文件* @return 访问地址* @throws Exception*/SysFileInfo upload(MultipartFile file) throws Exception;/*** 根据文件id查询文件* @param params* @return*/List<SysFileInfo> getSysFileInfoList(SysFileInfo params);
}
对应的实现类
package com.ruoyi.file.service;import com.ruoyi.system.api.DubboFileService;
import com.ruoyi.system.api.domain.SysFileInfo;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.util.List;/*** dubbo文件服务** @author:gan* @date: 2024-02-21 17:53*/
@DubboService(version = "1.0.0")
public class DubboFileServiceImpl implements DubboFileService {@Resourceprivate IMinioSysFileService minioSysFileService;@Overridepublic String uploadFile(MultipartFile file) throws Exception {return minioSysFileService.uploadFile(file);}@Overridepublic SysFileInfo upload(MultipartFile file, String secondPath) throws Exception {return minioSysFileService.upload(file, secondPath);}@Overridepublic SysFileInfo upload(MultipartFile file) throws Exception {return minioSysFileService.upload(file);}@Overridepublic List<SysFileInfo> getSysFileInfoList(SysFileInfo params) {return minioSysFileService.getSysFileInfoList(params);}
}
其实要用的方法都在 IMinioSysFileService 的实现类中写好了,这里只是为了使用 @DubboService 注解。
然后启动文件服务
再查看nacos中的服务列表
可以看到生产者已经启动成功了。
3、消费者
在 ruoyi-modules 模块下新建了一个 名为 common-test 的模块作为消费者,依赖如下:
<?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-modules</artifactId><groupId>com.ruoyi</groupId><version>3.6.3</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common-test</artifactId><dependencies><!-- SpringCloud Alibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- SpringCloud Alibaba Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- SpringBoot Actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- Swagger UI --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.fox.version}</version></dependency><!-- Mysql Connector --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- RuoYi Api System --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-api-system</artifactId></dependency><!-- RuoYi Common DataSource --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datasource</artifactId></dependency><!-- RuoYi Common DataScope --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datascope</artifactId></dependency><!-- RuoYi Common Swagger --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-swagger</artifactId></dependency><!-- Dubbo --><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId></dependency><!--这个依赖是整合dubbo时要用到的--><!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency></dependencies></project>
添加项目中的 bootstrap.yml 配置文件,具体内容如下:
# Tomcat
server:port: 9302# Spring
spring:application:# 应用名称name: common-testmain:allow-circular-references: true # 中断循环引用profiles:# 环境配置active: devcloud:nacos:discovery:# 服务注册地址server-addr: 127.0.0.1:8848config:# 配置中心地址server-addr: 127.0.0.1:8848# 配置文件格式file-extension: yml# 共享配置shared-configs:- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
在nacos中添加名为 common-test-dev.yml 的配置,具体内容如下:
# spring配置
spring:servlet:multipart:maxFileSize: 30MBmaxRequestSize: 30MBdatasource:druid:stat-view-servlet:enabled: trueloginUsername: adminloginPassword: 123456dynamic:druid:initial-size: 5min-idle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20filters: stat,slf4jconnectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000connectTimeout: 1800000socketTimeout: 1800000datasource:# 主库数据源master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/hr-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: 123456druid: # 配置数据库连接参数connectTimeout: 1800000socketTimeout: 1800000# mybatis配置
mybatis:# 搜索指定包别名typeAliasesPackage: com.common.test# 配置mapper的扫描,找到所有的mapper.xml映射文件mapperLocations: classpath:mapper/**/*.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# dubbo相关配置
dubbo:protocol:name: dubbo # dubbo协议port: -1 # -1表示端口从20880开始递增,不会造成端口冲突registry:address: nacos://127.0.0.1:8848consumer:check: false # dubbo默认有启动检查retries: 0 # dubbo内置的重试机制
接着在服务启动类中加上 @EnableDubbo 注解
消费者的测试接口
package com.common.test.service;/*** 测试接口** @author:gan* @date: 2024-02-04 16:45*/
public interface CommonService {/*** 测试dubbo调用* @return*/Object testDubbo();
}
接口实现类
package com.common.test.service.impl;import com.common.test.service.CommonService;
import com.ruoyi.system.api.DubboFileService;
import com.ruoyi.system.api.domain.SysFileInfo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;import java.util.List;/*** 测试接口实现类** @author:gan* @date: 2024-02-04 16:47*/
@Service
public class CommonServiceImpl implements CommonService {@DubboReference(version = "1.0.0")private DubboFileService dubboFileService;@Overridepublic Object testDubbo() {SysFileInfo selectSysFileInfoParams = new SysFileInfo();selectSysFileInfoParams.setFileId("1752583940597551104");List<SysFileInfo> sysFileInfoList = dubboFileService.getSysFileInfoList(selectSysFileInfoParams);System.out.println(sysFileInfoList.get(0));return sysFileInfoList.get(0);}
}
测试前端控制器
package com.common.test.controller;import com.common.test.service.CommonService;
import com.ruoyi.common.core.web.domain.AjaxResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 测试controller** @author:gan* @date: 2024-02-04 16:48*/
@RestController
@RequestMapping("/test")
public class CommonController {@Resourceprivate CommonService commonService;@GetMapping("/testDubbo")public AjaxResult test() {AjaxResult result = null;try {result = AjaxResult.success(commonService.testDubbo());} catch (Exception e) {e.printStackTrace();result = AjaxResult.error(e.getMessage());} finally {return result;}}
}
然后启动测试服务
再查看服务列表
可以看到消费者也启动成功了。
这里只是测试,就不需要用token了,在 ruoyi-gateway 的配置文件中加上如下配置:
重启 ruoyi-gateway 服务,再进行接口测试
三、修改若依的服务调用方式为dubbo
在开始之前,先给小伙伴们打个预防针,改造的过程会比较麻烦,这里以依赖冲突为最,若是对dubbo、若依不够熟悉或者怕麻烦的就跳过这一块。这里放个局部修改图:
看到这里如果没有跳过,那就开始吧。
1、改造系统模块
先引入依赖,父依赖和前面的父依赖一样,这里是处理系统模块的依赖,添加如下依赖:
<!-- Dubbo -->
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency><!--这个依赖是整合dubbo时要用到的-->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId>
</dependency>
然后排除掉 openfeign 的依赖,去掉若依自带的日志模块:
如果没有排掉,启动服务时会报 openfeign 和 dubbo 的依赖冲突的错。去掉日志模块是因为日志中也使用了 openfeign 。
完整依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>com.ruoyi</groupId><artifactId>ruoyi-modules</artifactId><version>3.6.3</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ruoyi-modules-system</artifactId><description>ruoyi-modules-system系统模块</description><dependencies><!-- SpringCloud Alibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- SpringCloud Alibaba Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- SpringBoot Actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- Swagger UI --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.fox.version}</version></dependency><!-- Mysql Connector --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- RuoYi Common DataSource --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datasource</artifactId></dependency><!-- RuoYi Common DataScope --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-datascope</artifactId><exclusions><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId></exclusion><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-slf4j</artifactId></exclusion></exclusions></dependency><!-- <!– RuoYi Common Log –>-->
<!-- <dependency>-->
<!-- <groupId>com.ruoyi</groupId>-->
<!-- <artifactId>ruoyi-common-log</artifactId>-->
<!-- </dependency>--><!-- RuoYi Common Swagger --><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-swagger</artifactId></dependency><!-- hutool工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!-- Dubbo --><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId></dependency><!--这个依赖是整合dubbo时要用到的--><!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
然后在启动类中去掉 openfeign 的注解,再加上 dubbo 的注解
然后在 nacos 中系统模块的配置文件中加上 dubbo 的相关配置
# dubbo相关配置
dubbo:protocol:name: dubbo # dubbo协议port: -1 # -1表示端口从20880开始递增,不会造成端口冲突registry:address: nacos://127.0.0.1:8848# check: false # dubbo默认有启动检查scan:base-packages: com.ruoyi.system.service
去掉日志模块再起编译时系统模块的前端控制器应该都会报错,需要把报错的地方注释掉或者去掉,我这里以参数管理的前端控制器为例:
完成了这些系统模块应该能正常启动了。
2、改造认证授权中心
但还没结束,启动系统模块后使用默认的 admin 登录,我们会发现报错 admin 不存在。
查找原因:
一开始以为是 admin 账号误删了,看了一下数据库发现账号还在,看了一下控制台,发现是认证授权中心的 SysLoginService
类中报错了,原来是 SysLoginService 这个类使用了系统接口模块的 RemoteUserService 中的
getUserInfo 方法,也就是使用了 openfeign ,用来调用系统模块的根据用户名查询用户接口,虽然认证授权中心中还存在 openfeign 依赖,但是系统模块的已被排除了,自然就报错了。
解决办法:
注释或者去掉认证授权中心 openfeign 相关的使用,以 dubbo 代之。
同样,先处理依赖的问题,经过观察,发现认证授权中心的 openfeign 相关的依赖在如下依赖中,做出排除
然后加上 dubbo 相关的依赖:
<!-- Dubbo -->
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency><!--这个依赖是整合dubbo时要用到的-->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId>
</dependency>
完整依赖如下:
<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><groupId>com.ruoyi</groupId><artifactId>ruoyi</artifactId><version>3.6.3</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ruoyi-auth</artifactId><description>ruoyi-auth认证授权中心</description><dependencies><!-- SpringCloud Alibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- SpringCloud Alibaba Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- SpringBoot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- SpringBoot Actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- RuoYi Common Security--><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common-security</artifactId><exclusions><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId></exclusion><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-slf4j</artifactId></exclusion></exclusions></dependency><!-- Dubbo --><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId></dependency><!--这个依赖是整合dubbo时要用到的--><!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
然后在 nacos 中认证授权中心的配置文件中加上如下配置:
# dubbo相关配置
dubbo:protocol:name: dubbo # dubbo协议port: -1 # -1表示端口从20880开始递增,不会造成端口冲突registry:address: nacos://127.0.0.1:8848consumer:check: false # dubbo默认有启动检查retries: 0 # dubbo内置的重试机制
接着在启动类中去掉 openfeign 的注解,再加上 dubbo 的注解
然后用 dubbo 的方式写一个接口,以用户服务 RemoteUserService 为例,写一个对应的 DubboUserService 用来替换用户服务 RemoteUserService
完整代码如下:
package com.ruoyi.system.api;import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;/*** dubbo用户服务** @author:gan* @date: 2024-02-28 10:36*/
public interface DubboUserService {/*** 通过用户名查询用户信息* @param username 用户名* @return*/public LoginUser getUserInfo(String username);/*** 注册用户信息** @param sysUser 用户信息* @return 结果*/public Boolean registerUserInfo(SysUser sysUser);
}
其实现类就放在系统模块的包下,完整代码如下:
package com.ruoyi.system.service.impl;import com.ruoyi.common.core.utils.VerifyUtil;
import com.ruoyi.system.api.DubboUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysPermissionService;
import org.apache.dubbo.config.annotation.DubboService;import javax.annotation.Resource;/*** dubbo用户服务 业务处理层** @author:gan* @date: 2024-02-28 10:41*/
@DubboService(version = "1.0.0")
public class DubboUserServiceImpl implements DubboUserService {@Resourceprivate SysUserMapper sysUserMapper;@Resourceprivate ISysPermissionService permissionService;@Resourceprivate ISysConfigService configService;@Overridepublic LoginUser getUserInfo(String username) {SysUser sysUser = sysUserMapper.selectUserByUserName(username);VerifyUtil.checkParam(sysUser, "用户名或密码错误!");LoginUser sysUserVo = new LoginUser();sysUserVo.setSysUser(sysUser);sysUserVo.setRoles(permissionService.getRolePermission(sysUser)); // 角色集合sysUserVo.setPermissions(permissionService.getMenuPermission(sysUser)); // 权限集合return sysUserVo;}@Overridepublic Boolean registerUserInfo(SysUser sysUser) {configService.selectConfigByKey("sys.account.registerUser");if (!Boolean.TRUE.equals(configService.selectConfigByKey("sys.account.registerUser"))) {throw new RuntimeException("当前系统没有开启注册功能!");}String username = sysUser.getUserName();VerifyUtil.checkParam(sysUserMapper.checkUserNameUnique(username), "保存用户'" + username + "'失败,注册账号已存在!");return sysUserMapper.insertUser(sysUser) > 0;}
}
其中 VerifyUtil 是自己写的判空工具类,可以用自己的方式判空。
接着在 SysLoginService 类中注释掉用户服务 RemoteUserService 相关的逻辑,再以dubbo用户服务 DubboUserService 代之:
日志服务 RemoteLogService 也是同理。改造完成,再成功启动后就可以登录了。
这里贴一下我的日志服务代码
完整代码如下:
package com.ruoyi.system.api;import com.ruoyi.system.api.domain.SysLogininfor;
import com.ruoyi.system.api.domain.SysOperLog;/*** dubbo日志服务** @author:gan* @date: 2024-02-28 11:21*/
public interface DubboLogService {/*** 保存系统日志** @param sysOperLog 日志实体* @return 结果*/public Boolean saveLog(SysOperLog sysOperLog);/*** 保存访问记录** @param sysLogininfor 访问实体* @return 结果*/public Boolean saveLogininfor(SysLogininfor sysLogininfor);
}
对应实现类也在系统模块
package com.ruoyi.system.service.impl;import com.ruoyi.system.api.DubboLogService;
import com.ruoyi.system.api.domain.SysLogininfor;
import com.ruoyi.system.api.domain.SysOperLog;
import com.ruoyi.system.mapper.SysLogininforMapper;
import com.ruoyi.system.mapper.SysOperLogMapper;
import org.apache.dubbo.config.annotation.DubboService;import javax.annotation.Resource;/*** dubbo日志服务 服务层处理** @author:gan* @date: 2024-02-28 11:24*/
@DubboService(version = "1.0.0")
public class DubboLogServiceImpl implements DubboLogService {@Resourceprivate SysOperLogMapper operLogMapper;@Resourceprivate SysLogininforMapper logininforMapper;@Overridepublic Boolean saveLog(SysOperLog sysOperLog) {return operLogMapper.insertOperlog(sysOperLog) > 0;}@Overridepublic Boolean saveLogininfor(SysLogininfor sysLogininfor) {return logininforMapper.insertLogininfor(sysLogininfor) > 0;}
}
以dubbo日志服务替换掉 SysRecordLogService 类中的日志服务
四、整合过程遇到的问题
1、出现循环引用
我想着文件模块整合dubbo,引入依赖、加上注解之后报错如下:
***************************
APPLICATION FAILED TO START
***************************Description:The dependencies of some of the beans in the application context form a cycle:targeterBeanPostProcessor defined in class path resource [com/alibaba/cloud/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.class]↓com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository (field private com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.dubboMetadataConfigServiceProxy)↓com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy
┌─────┐
| com.alibaba.cloud.dubbo.autoconfigure.DubboMetadataAutoConfiguration (field private com.alibaba.cloud.dubbo.metadata.resolver.MetadataResolver com.alibaba.cloud.dubbo.autoconfigure.DubboMetadataAutoConfiguration.metadataResolver)
└─────┘Action:Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
虽然他已经提示要加上配置:
# Spring
spring:main:allow-circular-references: true # 中断循环引用
但是我nacos的配置中加上之后没有效果
重启还是报那个错。
应该在对应模块的 bookstrap.yml 文件中加配置
再次重启
看来配置生效了,再看看nacos中有没有dubbo中的服务
2、出现依赖冲突
我想要在系统模块中使用 dubbo ,但引入 dubbo 相关依赖:
<!-- Dubbo -->
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
报错如下:
***************************
APPLICATION FAILED TO START
***************************Description:An attempt was made to call a method that does not exist. The attempt was made from the following location:com.alibaba.cloud.dubbo.metadata.RestMethodMetadata.<init>(RestMethodMetadata.java:80)The following method did not exist:feign.MethodMetadata.queryMapEncoded()ZThe calling method's class, com.alibaba.cloud.dubbo.metadata.RestMethodMetadata, was loaded from the following location:jar:file:/D:/environment/Maven/apache-maven-3.6.0/repository/com/alibaba/cloud/spring-cloud-starter-dubbo/2021.0.1.0/spring-cloud-starter-dubbo-2021.0.1.0.jar!/com/alibaba/cloud/dubbo/metadata/RestMethodMetadata.classThe called method's class, feign.MethodMetadata, is available from the following locations:jar:file:/D:/environment/Maven/apache-maven-3.6.0/repository/io/github/openfeign/feign-core/11.10/feign-core-11.10.jar!/feign/MethodMetadata.classThe called method's class hierarchy was loaded from the following locations:feign.MethodMetadata: file:/D:/environment/Maven/apache-maven-3.6.0/repository/io/github/openfeign/feign-core/11.10/feign-core-11.10.jarAction:Correct the classpath of your application so that it contains compatible versions of the classes com.alibaba.cloud.dubbo.metadata.RestMethodMetadata and feign.MethodMetadata
原来系统模块使用了 openfeign 进行服务调用,引入 dubbo 相关的依赖后就依赖冲突了,可以排除系统模块中的 openfeign 依赖或者移除 dubbo 依赖,我这里选择了前者
3、启动出现端口号被占用
生产者已经启动,消费者启动时报错:
java.lang.IllegalStateException: Failed to execute CommandLineRunnerat org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752)at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)at com.common.test.CommonTestApplication.main(CommonTestApplication.java:19)
Caused by: org.apache.dubbo.rpc.RpcException: Fail to start server(url: dubbo://192.168.1.12:20880/com.alibaba.cloud.dubbo.service.DubboMetadataService?anyhost=true&application=common-test&bind.ip=192.168.1.12&bind.port=20880&channel.readonly.sent=true&codec=dubbo&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=common-test&heartbeat=60000&interface=com.alibaba.cloud.dubbo.service.DubboMetadataService&metadata-type=remote&methods=getAllServiceKeys,getServiceRestMetadata,getExportedURLs,getAllExportedURLs&pid=27496&qos.enable=false&release=2.7.15&revision=2021.0.1.0&service.name=ServiceBean:common-test/com.alibaba.cloud.dubbo.service.DubboMetadataService:1.0.0&side=provider×tamp=1708501506423&version=1.0.0) Failed to bind NettyServer on /192.168.1.12:20880, cause: Address already in use: bindat org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.createServer(DubboProtocol.java:350)at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.openServer(DubboProtocol.java:322)at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.export(DubboProtocol.java:305)at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:64)at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:75)at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:66)at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)at org.apache.dubbo.registry.integration.RegistryProtocol.lambda$doLocalExport$2(RegistryProtocol.java:262)at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)at org.apache.dubbo.registry.integration.RegistryProtocol.doLocalExport(RegistryProtocol.java:260)at org.apache.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:212)at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:62)at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:73)at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:64)at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:518)at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:339)at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:314)at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:238)at com.alibaba.cloud.dubbo.service.DubboMetadataServiceExporter.export(DubboMetadataServiceExporter.java:82)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.getDubboMetadataServiceMetadata(DubboServiceMetadataRepository.java:288)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository$$FastClassBySpringCGLIB$$1.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository$$EnhancerBySpringCGLIB$$1.getDubboMetadataServiceMetadata(<generated>)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.attachDubboMetadataServiceMetadata(DubboServiceRegistrationAutoConfiguration.java:172)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.attachDubboMetadataServiceMetadata(DubboServiceRegistrationAutoConfiguration.java:166)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.lambda$null$0(DubboServiceRegistrationAutoConfiguration.java:131)at java.lang.Iterable.forEach(Iterable.java:75)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.lambda$onDubboBootstrapStarted$1(DubboServiceRegistrationAutoConfiguration.java:130)at java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1597)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.onDubboBootstrapStarted(DubboServiceRegistrationAutoConfiguration.java:129)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344)at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229)at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166)at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)at com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapStartCommandLineRunner.run(DubboBootstrapStartCommandLineRunner.java:46)at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768)... 5 common frames omitted
Caused by: org.apache.dubbo.remoting.RemotingException: Failed to bind NettyServer on /192.168.1.12:20880, cause: Address already in use: bindat org.apache.dubbo.remoting.transport.AbstractServer.<init>(AbstractServer.java:73)at org.apache.dubbo.remoting.transport.netty4.NettyServer.<init>(NettyServer.java:79)at org.apache.dubbo.remoting.transport.netty4.NettyTransporter.bind(NettyTransporter.java:35)at org.apache.dubbo.remoting.Transporter$Adaptive.bind(Transporter$Adaptive.java)at org.apache.dubbo.remoting.Transporters.bind(Transporters.java:56)at org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger.bind(HeaderExchanger.java:44)at org.apache.dubbo.remoting.exchange.Exchangers.bind(Exchangers.java:70)at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.createServer(DubboProtocol.java:348)... 56 common frames omitted
Caused by: java.net.BindException: Address already in use: bindat sun.nio.ch.Net.bind0(Native Method)at sun.nio.ch.Net.bind(Net.java:433)at sun.nio.ch.Net.bind(Net.java:425)at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:141)at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:562)at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1334)at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:600)at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:579)at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:973)at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:260)at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:356)at io.netty.util.concurrent.AbstractEventExecutor.runTask$$$capture(AbstractEventExecutor.java:174)at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java)at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:167)at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java)at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.lang.Thread.run(Thread.java:748)
原因:
这是因为生产者启动时,20880这个端口被占用,消费者尝试使用20880端口启动就报错了
报错日志中也提到了
可以在配置文件中加入指定端口号或者使用端口号递增,这里选择后者。
# dubbo相关配置
dubbo:protocol:name: dubbo # dubbo协议port: -1 # -1表示端口从20880开始递增,不会造成端口冲突registry:address: nacos://127.0.0.1:8848consumer:check: false # dubbo默认有启动检查retries: 0 # dubbo内置的重试机制
4、出现某个类找不到
就是模块启动时报错:Caused by: java.lang.ClassNotFoundException
java.lang.IllegalStateException: Failed to execute CommandLineRunnerat org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752)at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)at com.common.test.CommonTestApplication.main(CommonTestApplication.java:19)
Caused by: java.lang.reflect.UndeclaredThrowableException: Failed to invoke event listener method
HandlerMethod details:
Bean [com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration]
Method [public void com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.onDubboBootstrapStarted(com.alibaba.cloud.dubbo.bootstrap.event.DubboBootstrapStartedEvent)]
Resolved arguments:
[0] [type=com.alibaba.cloud.dubbo.bootstrap.event.DubboBootstrapStartedEvent] [value=com.alibaba.cloud.dubbo.bootstrap.event.DubboBootstrapStartedEvent[source=com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapWrapper@30afac00]]at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:361)at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229)at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166)at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)at com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapStartCommandLineRunner.run(DubboBootstrapStartCommandLineRunner.java:46)at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768)... 5 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/google/common/collect/Mapsat org.apache.dubbo.registry.nacos.util.NacosInstanceManageUtil.<clinit>(NacosInstanceManageUtil.java:39)at org.apache.dubbo.registry.nacos.NacosRegistry.doSubscribe(NacosRegistry.java:187)at org.apache.dubbo.registry.support.FailbackRegistry.subscribe(FailbackRegistry.java:299)at org.apache.dubbo.registry.ListenerRegistryWrapper.subscribe(ListenerRegistryWrapper.java:105)at org.apache.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:232)at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:62)at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:73)at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:64)at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:518)at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:339)at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:314)at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:238)at com.alibaba.cloud.dubbo.service.DubboMetadataServiceExporter.export(DubboMetadataServiceExporter.java:82)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.getDubboMetadataServiceMetadata(DubboServiceMetadataRepository.java:288)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository$$FastClassBySpringCGLIB$$1.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)at com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository$$EnhancerBySpringCGLIB$$1.getDubboMetadataServiceMetadata(<generated>)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.attachDubboMetadataServiceMetadata(DubboServiceRegistrationAutoConfiguration.java:172)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.attachDubboMetadataServiceMetadata(DubboServiceRegistrationAutoConfiguration.java:166)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.lambda$null$0(DubboServiceRegistrationAutoConfiguration.java:131)at java.lang.Iterable.forEach(Iterable.java:75)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.lambda$onDubboBootstrapStarted$1(DubboServiceRegistrationAutoConfiguration.java:130)at java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1597)at com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.onDubboBootstrapStarted(DubboServiceRegistrationAutoConfiguration.java:129)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344)... 14 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.google.common.collect.Mapsat java.net.URLClassLoader.findClass(URLClassLoader.java:382)at java.lang.ClassLoader.loadClass(ClassLoader.java:424)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)at java.lang.ClassLoader.loadClass(ClassLoader.java:357)... 51 common frames omitted
一开始想着是不是dubbo的版本的问题,但生产者都已经启动成功了,而且用的还是同一个依赖,就想着加一下这个类的依赖看看能不能解决,依赖如下:
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>33.0.0-jre</version>
</dependency>
果然启动成功了。
但也纳闷,为什么同样的dubbo依赖,生产者那边就可以,到了消费者这边就不行了?
既然dubbo依赖是相同的,那肯定就是其他依赖的问题,于是对比了其他依赖,最终发现minio的依赖下包含 com.google.guava 依赖
那就注释掉 com.google.guava 依赖,加入 minio 依赖试试,结果发现也能启动成功…
太难了,就这个问题折腾了好久(大哭)
5、找不到生产者
生产者和消费者都启动了,但是消费者调用生产者服务时报如下错:
org.apache.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:8848 for service com.ruoyi.system.api.DubboFileService:1.0.0 on consumer 192.168.1.12 use dubbo version 2.7.15, please check status of providers(disabled, not registered or in blacklist).at org.apache.dubbo.registry.integration.DynamicDirectory.doList(DynamicDirectory.java:168)at org.apache.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:99)at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:297)at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:262)at org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor.intercept(ClusterInterceptor.java:47)at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$InterceptorInvokerNode.invoke(AbstractCluster.java:92)at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:98)at org.apache.dubbo.registry.client.migration.MigrationInvoker.invoke(MigrationInvoker.java:170)at org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker.doInvoke(ZoneAwareClusterInvoker.java:112)at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:265)at org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor.intercept(ClusterInterceptor.java:47)at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$InterceptorInvokerNode.invoke(AbstractCluster.java:92)at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:96)at org.apache.dubbo.common.bytecode.proxy0.getSysFileInfoList(proxy0.java)at com.common.test.service.impl.CommonServiceImpl.testDubbo(CommonServiceImpl.java:27)at com.common.test.controller.CommonController.test(CommonController.java:28)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:90)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:41002)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:748)
分析原因:
我的生产者是若依的文件服务,若依的文件服务原来是用 Feign 进行远程调用的,我只是想把 Feign 改为 dubbo ,就定义了一个和原文件接口相同抽象方法的接口,其实就是接口名不一样,再用文件实现类去实现,这样我就不用重新写方法了,具体如下:
因为启动没报错,nacos中也有看到对应的服务,就没有多想,就是会一直报这个错,后面就想着单独见一个类加上 @DubboService(version = “1.0.0”) 试试
结果就调用成功了…