最近给一个mybatis-plus框架的项目整合nacos、dubbo,经历了No provider available from registry、com.alibaba.dubbo.rpc.RpcException Failed to invoke the
method、java.lang.NoClassDefFoundError:
org/apache/commons/lang3/StringUtils等一系列错误,现在把我的创建过程分享一下。
环境:Springboot2.3,Dubbo2.7.8,mybatis-plus,nacosServer1.4.3
由于是在已有项目基础上整合,所以会缺少一部分无关紧要的代码,适合有一定经验的开发者阅读
搭建步骤
1. 创建一个公共模块
我这里创建的是dubbo-common,名称自己定
我的项目结构如下:
pom.xml引入nacos、dubbo依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</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>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- 此依赖是为了解决java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils 错误-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
2.建立提供者(生产者)模块
pom引入对公共模块的依赖:
<dependency>
<groupId>com.zhongrui.uthink</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
建立启动类:
@SpringBootApplication
@EnableDiscoveryClient
@EnableDubbo
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
建立服务实现类:
//引入的接口要和刚才在common建立的一致
import service.huawei.DeviceBindingService;
//引入dubboservice
import org.apache.dubbo.config.annotation.DubboService;
@Service
//供dubbo暴露的接口,要指定版本号
@DubboService(version = "1.0.0",group = "db1")
public class DeviceBindingServiceImpl extends ServiceImpl<DeviceBindingDao, DeviceBinding> implements DeviceBindingService {
//服务实现代码
}
applicaiton配置参数(重要)
我的配置:
#提供者的服务名,一定要记住
spring.application.name=userservice
#dubbo
#协议名为dubbo
dubbo.protocol.name=dubbo
#端口号,配置为-1代表自增长
dubbo.protocol.port=-1
#配置nacos注册中心地址
dubbo.registry.address=nacos://localhost:8848
#在提供者需要加上这一配置
dubbo.consumer.check=false
#设置订阅的服务
dubbo.cloud.subscribed-services=userservice
#重要,一定要和注解了DubboService的包目录一致
dubbo.scan.base-packages=com.zhongrui.uthink.business.impl
spring.main.allow-bean-definition-overriding=true
注:dubbo.scan.base-packages要配置正确,这里的配置比较重要
3. 建立消费者模块
pom引入dubbo-common依赖,与提供者一致
<dependency>
<groupId>com.zhongrui.uthink</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
建立消费者实现类:
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
//这是要调用的接口,和生产者import的一致
import service.huawei.DeviceBindingService;
@Service
@Slf4j
public class PushReceiveServiceImpl {
//使用DubboReference注解,括号内的内容要和提供者的一致
@DubboReference(version = "1.0.0",group = "db1")
DeviceBindingService bindingService;
//其他实现代码...
}
建立消费者Controller
@RestController
@Api(tags = "推送数据接口")
@RequestMapping("/receive")
public class ReceiveController {
@Resource
private PushReceiveServiceImpl pushReceiveService;
@PostMapping("/test")
@ResponseBody
@ApiOperation("测试云推送")
public ResponseEntity pushReceiverTest(@RequestBody String jsonString) throws Exception {
System.out.println(jsonString);
return new ResponseEntity(HttpStatus.OK);
}
}
配置文件:
#消费者名称
spring.application.name=huaweiservice
#dubbo
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.registry.address=nacos://localhost:8848
#订阅服务的名称,要和提供者的应用名一致
dubbo.cloud.subscribed-services=userservice
4.先后启动提供者、消费者服务
启动提供者服务之后,再启动消费者服务。
最后应在nacos-server看到provider和consumer的名称,如下图所示:
(我这里有其它的服务,没有在代码中体现出来)
注意,consumer和provider后面的名称需要完全一致,否则会出现No provider available from registry的错误。
如果没有发现注册的providers服务,请检查@DubboService注解是否正确标明,以及dubbo.scan.base-packages是否配置正确
4.调用测试
在浏览器访问测试消费者模块提供的接口:
如上图所示,返回200,表成功访问。
5.常见问题
- 在使用了mybatis-plus框架的项目中,如果在服务接口使用的时候有wrapper的传输,会报com.alibaba.dubbo.rpc.RpcException Failed to invoke the…错误,需要在impl里将涉及直接使用wrapper的地方在Service中为其新建一个接口
例如这种代码:
需要在提供者的bindingServiceImpl里面为其新建一个接口:
再到消费者调用:
这样来避免wrapper的直接传输。
- 调用服务时提示No provider available for the service xxx from registry xxx on the consumer
这个问题解决起来比较复杂,要检查服务名称、扫描包等配置项,可先到nacos查看已经注册的服务是否包含需要的provider,如果没有则检查配置包是否扫描到,如果有则检查服务名是否一致等。
第一次接触Dubbo,如有不对,请多指教