一、为什么要集成Dubbo RPC
在国内建设微服务有Dubbo和Spring Cloud两种主流方案可供选择。Dubbo是服务治理与RPC实现方案(可能理解为一个分布式通信框架),虽然在国内有着非常大的用户群体,但是其周边设施与组件相对来说并不那么完善。而Spring Cloud则是一套完整的分布式微服务架构解决方案,很多开发者更希望享受Spring cloud全家桶生态。
在Spring Cloud构建的微服务系统中,大多数的开发者使用都是官方提供的Feign组件来进行内部服务通信。这种声明式的HTTP客户端使用起来非常的简洁、方便、优雅,并且和开发平台、语言无关,但是通常情况下,HTTP并不会开启KeepAlive功能,即当前连接为短连接,短连接的缺点是每次请求都需要建立TCP连接,这使得其效率变的相当低下,对外部提供REST API服务是一件非常好的事情,但是如果内部调用也是使用HTTP调用方式,就会显得显得性能低下。这时,我们如果内部服务使用RPC调用,对外使用REST API,将会是一个非常不错的选择。
Spring Cloud Alibaba的出现,使用Nacos作为服务发现与注册,同时兼容使用Feign的HTTP方式和使用Dubbo的RPC方式调用,Spring Cloud使用内部的RPC协议调用几乎就可以零成本完成改造。
RPC属于动态代理,有服务生产端和消费端,生产端基于代理接口提供服务,消费端基于代理接口完成远程过程调用,所以Spring Cloud内部实现Dubbo RPC通信分为定义服务接口、提供服务和服务调用3个步骤完成。
示例代码工程视图如下:
|vtom
|------vtom-common
|----vtom-common-beans
|----vtom-common-...
|------vtom-cloud
|----vtom-cloud-gateway
|----vtom-cloud-...
|------vtom-api
|----vtom-api-sample(服务接口)
|----vtom-api-...
|------vtom-service
|----vtom-service-sample-provider(服务提供)
|----vtom-service-sample-consumer(服务调用)
|----vtom-service-...
由于服务接口是服务提供和服务调用双方的依据,所以在开发上将服务接口定义为一个单独的代码工程(vtom-api-sample),服务提供和服务调用均需要依赖这个代码工程。
package com.vtom.dubbo;
public interface ISampleDubbo {
String sayHello(String name);
}
在该工程父亲工程(vtom-api)的pom.xml中引入Dubbo相关依赖包:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-dubboartifactId>
dependency>
服务提供者为单独的代码工程(vtom-service-sample-provider),实现上面定义的服务接口。这里要注意的是需要使用Dubbo的@Service注解org.apache.dubbo.config.annotation.Service将服务接口的实现注册为Dubbo服务。
package com.vtom.dubbo.provider;
import org.apache.dubbo.config.annotation.Service;
import com.vtom.dubbo.ISampleDubbo;
@Service
public class SampleDubboProvider implements ISampleDubbo {
@Override
public String sayHello(String name) {
return “Hello ,”+name;
}
}
在该工程的pom.xml中引入服务接口定义依赖工程包:
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>vtom-api-sampleartifactId>
<version>${project.version}version>
dependency>
在工程配置文件中增加Dubbo服务注册相关配置:
spring:
application:
name: vtom-service-sample-provider
cloud:
nacos:...
#服务器端口
server:
port: ${random.int[10000,20000]}
....
#Dubbo RPC配置
dubbo:
scan:
#dubbo 服务扫描基准包
base-packages: com.vtom.dubbo
protocol:
#dubbo 协议
name: dubbo
#dubbo 协议端口( -1 表示自增端口,从 20880 开始)
port: -1
registry:
#挂载到 Spring Cloud 注册中心
address: spring-cloud://localhost
...
服务调用者为单独的代码工程(vtom-service-sample-consumer),通过@Reference注解服务接口即可实现服务调用。
package com.vtom.service.impl;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import com.vtom.dubbo.ISampleDubbo;
import com.vtom.service.ISampleService;
@Service
public class SampleServiceImpl implements ISampleService {
@Reference
private ISampleDubbo sampleDubbo;
@Override
public String sayHello(String name) {
return this.sampleDubbo.sayHello(name);
}
}
在该工程的pom.xml中引入服务接口定义依赖工程包:
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>vtom-api-sampleartifactId>
<version>${project.version}version>
dependency>
在工程配置文件中增加Dubbo服务注册相关配置:
spring:
application:
name: vtom-service-sample-consumer
cloud:
nacos:...
#服务器端口
server:
port: ${random.int[10000,20000]}
....
#Dubbo RPC配置
dubbo:
scan:
#dubbo 服务扫描基准包(Dubbo提供者配置)
base-packages: com.vtom.dubbo
protocol:
#dubbo 协议
name: dubbo
#dubbo 协议端口( -1 表示自增端口,从 20880 开始)
port: -1
registry:
#挂载到 Spring Cloud 注册中心
address: spring-cloud://localhost
cloud:
#指定被调用的服务,多个使用逗号分隔,不建议使用*号
subscribed-services: vtom-service-sample-provider
...