Dubbo是阿里巴巴开源的基于Java的高性能RPC分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
Spring-cloud-alibaba-dubbo 是基于SpringCloudAlibaba技术栈对dubbo技术的一种封装,目的在于实现基于RPC的服务调用。
本文示例通过Spring-cloud-alibaba-dubbo完成服务调用。
目录
一、抽取接口:提供统一业务api
抽取的接口,需要服务提供者进行接口实现,用于服务消费者进行远程调用。目的在于提供统一业务api。需要放在公共模块当中,方便服务提供者、消费者所处的微服务引用依赖。
package cn.jack.dubboservice;
import cn.jack.domain.Product;
public interface ProductService {
Product findOne();
}
二、服务提供者实现接口
2.1 添加dubbo依赖
<!--dubbo-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
2.2 添加dubbo配置
dubbo:
scan:
base-packages: cn.jack.service.impl # 指定接口实现类所在的包
protocols:
dubbo:
name: dubbo # 服务协议
port: -1 # 服务端口
registry:
address: spring-cloud://localhost # 注册中心
2.3 实现服务接口
package cn.jack.service.impl;
import cn.jack.domain.Product;
import cn.jack.dubboservice.ProductService;
public class ProductServiceImplDubbo implements ProductService {
@Override
public Product findOne() {
Product product = new Product();
product.setPid(-1);
product.setPname("dubbo实现服务远程调用");
return product;
}
}
2.4 暴露服务
三、服务消费者调用接口
3.1 添加dubbo依赖
<!--dubbo-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
3.2 添加dubbo配置
dubbo:
registry:
address: spring-cloud://localhost # 注册中心
cloud:
subscribed-services: service-product # 订阅的服务,值为nacos上的服务名称。默认订阅所有服务
3.3 调用服务
package cn.jack.controller;
import cn.jack.domain.Product;
import cn.jack.dubboservice.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class OrderController6 {
@Reference
private ProductService productService;
/**
* 测试远程调用
* @return
*/
@RequestMapping("/order/test")
public Product orderTest() {
// 通过抽象接口里面的方法,调用远程服务
return this.productService.findOne();
}
}
四、测试
访问测试接口,观察返回结果。
五、注意事项
- 如果远程调用的接口,返回对象,该对象需要实现java.io.Serializable接口,用于序列化网络传输对象。否则会报异常:
java.lang.IllegalStateException: Serialized class cn.jack.domain.Product must implement java.io.Serializable
- Feign和Dubbo都是远程服务调用的解决方案,两者选择其一即可。如果两个都用,可能会有问题。我的项目原本使用的Feign,后边引入Dubbo的依赖进行测试,启动应用报以下异常:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-09-30 15:53:52.666 ERROR [service-order,,,] 7552 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Field productService in cn.jack.service.impl.OrderServiceImpl5 required a single bean, but 2 were found: - feignBuilder: defined by method 'feignBuilder' in class path resource [org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.class] - feignSentinelBuilder: defined by method 'feignSentinelBuilder' in class path resource [com/alibaba/cloud/seata/feign/SeataFeignClientAutoConfiguration.class] Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed