开发者学堂课程【(知识精讲+项目实战)第五阶段:SpringCloud Alibaba Dubbo 使用】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/687/detail/11932
SpringCloud Alibaba Dubbo 使用
内容介绍
一、总述
二、发展历史
三、服务调用
四、基本介绍
五、实现
六、测试
一、总述
主要研究一下 SpringCloud 阿里巴巴技术栈中另外一个用于远程服
务调用的组件,称作 Dubbo。
二、发展历史
首先来看一下官方对于 Dubbo 是如何解释的,在 SpringCloud 阿里
巴巴技术栈的主页中就有一个组件,组建中就有对 Dubbo 的一个解
释。
对于 ApacheDubbo 可能会有一些疑问,为何 Alibaba 会变为
Apache。这里涉及到一个发展历史。Dubbo 这个组件首先是由阿里开
发并且开源出的,后来阿里一度宣布对 Dubbo 放弃维护。
放弃维护一直持续了两到三年之久,就在前年阿里重新宣布对 Dubbo
的维护,并且把它捐献给了 Apache 的基金会,所以Dubbo现在是
属于 Apache 的一个子项目。
三、服务调用
1、基本介绍
ApacheDubbo 是一款高性能JavaRPC框架。RPC就是远程过程调
用,其实在讲解 SpringCloudAlibaba 这门技术的开始就提到过这
个词。在第一章的时候有一个常见概念,其中有一个服务调用。在微
服务架构中,通常存在多个服务之间远程调用的需求。比如订单和商
品,在下订单的时候需要远程调用商品微服务查询商品信息,这就是
一个远程调用的需求。
2、远程调用技术
目前主流的远程调用技术有两个。
(1)基于 http 的 RESTful 的接口
这种形式其实是比较熟悉的。因为在讲解这门课程的时候一直使用的
就是这项技术。此前所用的是 RepresentationalState,后来才改
成了RESTful。不管使用的是哪种底层,均是基于TCP的。
(2)基于 TCP 的 RPC 协议
这是在一开始就进行讲解的,后来又讲解了何为 RESTful,何为 RPC,
最后又把两者的区别和联系进行对比。
区别与联系:
①通讯协议
RESTful:HTTP
RPC:TCP
②性能
RESTful 的性能较低,RPC 的性能较高。
③灵活度
RESTful的灵活度较高,RPC 的灵活度较低。
④应用
微服务架构一般采用的是 RESTful,而对于 SOA 架构一般使用的是
RPC。
3、特殊情况
注意在这里所说的是在一般情况下,如果有的公司需求比较特别,它
使用的就是微服务架构,还想使远程调用的性能更加高一些,就像使
用 RPC。对此接下里讲解的 Dubbo 技术就是一个很好的解决方案了。
四、基本介绍
1、注意事项
注意 Dubbo 这门技术本身就是一个成型的方案,如果在这里单独讲
解 Dubbo 的话,是需要花费很长时间的。
但是这里毕竟是 SpringCloudAlibaba 技术站的讲解课程,并不是
Dubbo 的。所以如果对于 Dubbo 不太了解的,可以去观看与之相关
的视频。
首先把 Dubbo 的内容了解了再学习接下来的内容就非常简单了,这
是一个前提条件。
2、功能介绍
Dubbo 是阿里巴巴开源的基于 java 的高性能 RPC 分布式服务框
架,致力于提供高性能和透明化的RPC远程服务调用方案,以及 SOA
服务治理方案。
Spring-cloud-alibaba-dubbo 是基于 SpringCloudAlibaba 技术栈
对 dubbo 技术的一种封装,目的在于实现基于RPC的服务调用。接
下来研究的重点就是 SpringCloudAlibaba 对于 Dubbo 封装之后的
要怎样使用。
3、图文分析
首先左边为服务的消费者,右边为服务的提供者,就相当于订单和商
品微服务。接下来的服务调用有两条路径,上方的路径是基于nacos
为服务注册中心,借用 rest 和 http 来作为远程调用,经过 http
的协议最终得到服务提供者。前面的课程讲解所用的均是这样的路
径。
此外还有一条以nacos为服务注册中心,以 Dubbo 作为远程过程调
用,借助 Dubbo 协议直接得到服务提供者。接下来所要研究的就是
下方这条路径。
或许会对此有所疑问,Dubbo 推荐的注册中心为 Zookeeper,却变成
了 nacos。因为现在使用的是SpringCloudAlibaba技术栈,
Zookeeper 是不属于这个技术栈的。
既然拥有 nacos 可以作为服务注册中心,直接使用 Dubbo+nacos 就
可以了。
五、实现
1、总括
实现的案例非常简单,仍然是要做下单这样一个案例。当前的工程是
在做了版本回退之后得到的,现在来看一下其中有何内容。首先为
shop-common,它已经是退回到了最基本的内容。
接下来是 shop-order 订单,其中也是留下了最基本的内容。Dao 中
没有任何内容,在service中最简单实现了一个订单的保存。在
Controller中发现其中的大部分内容均已经注销了,因为现在还未
加入 Dubbo,无法远程调用 product-service。
接下来再看另外一个商品,dao中是空白的,service 提供了最简单
的查询功能,controller 同样是提供了最简单的查询功能。这就是
环境基础,接下来就是在这样的基础上加入 Dubbo 完成一个基于
RPC的远程服务调用。
2、三个步骤
实现的过程主要是分成三个步骤的,如果对 Dubbo 非常熟悉的话很
容易就理解这三个步骤。
(1)提供统一的任务接口
这是 Dubbo 所要求做的。下面的服务提供者和服务消费者均需要使
用这个接口uct均是依赖于 common。这个在企业开发中一般是把它
作为单独的模块进行开发的,在这里为了简单就把它直接放在
common 这个模块中,因为order和product接口其实就是依赖于
common 的。这个接口其实就是提供了 productService 中的
findByPid 方法,也就是远程过程需要调用的方法。对于这个方法,
消费者需要调用它,提供者要实现它。
现在这个方法在 product 中,把 productService 删除掉,现在把
它添加到 common中。在企业开发中经常是单独开设一个模块的。找
到 itheima,新建一个接口为 service.ProductService。也就是对
接口进行一个提取,从product中提取到 common 中。后面还需要
把所有的实体类加上一个序列化的接口。这也是 Dubbo 在远程调用
中必须要实现的。
代码如下:
publicinterfaceProductService{
ProductfindByPid(Integerpid);
(2)提供服务提供者
①添加依赖
代码如下:
<!--dubbo-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactid></depend
ency>
②添加 Dubbo 配置
第二步首先要修改服务的生产者,需要实现这样一个方法并且把它暴
露出来。查询商品的方法已经有了,如果要使其暴露出来就要修改一
个注解。在此需要吧 service 的注解修改成 Dubbo 暴露服务的注
解。
如果要使用 Dubbo 的内容就必须引入 Dubbo 的依赖包,暴露出来以
后就相当于 order 能够远程调用它了。但是如果要远程调用底层是
需要经过Dubbo协议的,而这些 Dubbo 协议需要进行注册。对此需
要修改一下配置文件,在其中加入一些配置。首先第一项为包扫描,
扫描的是 service 的实现类。它的作用是让其中的注解生效。后面
配置的项是 Dubbo 的协议和端口。
协议使用的就是 Dubbo 协议,端口-1是无限制的意思。注册地址的
写法指的是用 SpringCloudAlibaba 技术栈中的地址,就是使用的
nacos。
代码如下:
dubbo:
scan:
base-packages:com.itheima.service.imp1#开启包扫描
protocols:
dubbo:
name:dubbo#服务协议
port:-1#服务端口
registry:
address:spring-cloud://1ocalhost#注册中心
③编写并暴露服务
暴露服务只要提供一个 Dubbo 的注解,不再使用Spring的注解就
可以了。
代码如下:
//暴露服务:注意这里使用的是dubbo提供的注解@Service,而不是
Spring的@Service
publicclassProductServiceImp1implementsProductService
@Autowired
privateProductDaoproductDao;
@Override
publicProductfindByPid(Integerpid){
returnproductDao.findyId(pid).get();
(3)提供服务的消费者
①添加依赖
接下来修改服务的调用方,第一步要加入 Dubbo 的依赖,
②添加 Dubbo 配置
第二个要加入与 Dubbo 相关的一些配置。第一个为注册中心,因为
只有在注册中心进行注册,注册中心才能管理到两个服务。其实和原
来的调用是很相似的,order 需要注册中心得到 product 的一个地
址,只不过这个地址不再是http的,而是dubbo协议的。
subscribed-services 翻译后是订阅的服务,后面写的是当前的服务
提供者在 nacos 中的一个服务名称。
代码如下:
Dubbo:
registry:
address:spring-cloud://localhost#注册中心
cloud:
subscribed-services:service-product#订阅的提供者名称
③引用服务
第三步为服务的调用。找到 orderController,这个时候发现已经引
用到service了,但这是一个接口,需要注入它的实现类也就是实
现对象。注意不再采用 Autowired,而采用的是 dubbo 提供的
Reference。这个注解的意思是服务的引用,也就是从原来的用 http
调用变成 dubbo 调用了。
代码如下:
@RestController
@s1f4j
publicclassOrderController{
@Autowired
privateOrderServiceorderService;
//引用服务
@Reference
privateProductServiceproductService;
@RequestMapping("/order/prod/{pid}")
publicOrderorder(@PathVariableIntegerpid){
log.info("接收到{}号商品的下单请求,接下来调用商品微服务查询
此商品信息",pid);
//调用商品微服务,查询商品信息
Productproduct=productServicefindByPid(pid);
log.info("查询到{}号商品的信息,内容是:{}",pid,
JSON.toJSONString(product));
//下单(创建订单)
Orderorder=newOrder();
order.setuid(1):
order.setUsername("测试用户");
order.setPid(pid):
order.setPname(product.getPname());
order.setPprice(productgetPprice));
ordersetNumber(1)
orderService.createOrder(order);
log.info("创建订单成功,订单信息为{}"
,JSON.toJSONString(order));
returnorder;
六、测试
最后进行一个测试,把两个服务都启动看是否成功。注意这个时候启
动是有顺序的,必须先启动服务的生产者。直接启动 product,当然
这个地方可以通过配置进行调整,这个配置也是 dubbo 的一些配置。
只要按照顺序先启动生产者,再启动调用者就可以了。
在这里已经打出很多 dubbo 相关的日志了,比如 dubbo 注册的地
址。
接下来启动 orderApplication,order 必定会向注册中心注册个人
信息,并且从注册中心调用服务提供者的服务地址。
在 nacos 中找到服务的列表,现在 service-order 和
service-product 都存在了。
点击一下详情,会发现在元数据里面就有许多和 dubbo 的内容了。
在这里甚至可以控制调用哪个版本。服务调用对于客户端来讲没有任
何的区别,依旧是可以传承服务调用的。但是对于底层的服务调用已
经由原来的http服务变成了 dubbo,现在就是通过 dubbo 来调用
的。