dubbo:从零理解及搭建dubbo微服务框架(一)
创始人
2024-02-01 18:25:45
0

0.引言

dubbo作为阿里巴巴开源的微服务框架,提供了高性能的RPC调用。同时因为有阿里的背书,在国内市场得到了广泛应用,dubbo的开源工作在2018年2月阿里将项目捐献给apache基金会后,得到了更加广大的发展。

之前我们讲解了springcloud微服务体系的入门学习,今天同样带大家来快速入门掌握dubbo微服务框架的应用,让大家逐步了解springcloud alibaba体系

1. 概念

1.1 什么是dubbo?

首先大家要了解到底什么是dubbo,他是一个组件,还是一门语言?实际上dubbo一个服务框架,一开始是用java编写,后续产生了go语言版本。因为dubbo本身自带了RPC调用功能,也就是组间调用。所以也称dubbo为RPC服务框架

我们来看官方对于dubbo的定义:

dubbo官方文档

Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。

Dubbo3 定义为面向云原生的下一代 RPC 服务框架。3.0 基于 Dubbo 2.x 演进而来,在保持原有核心功能特性的同时, Dubbo3 在易用性、超大规模微服务实践、云原生基础设施适配、安全性等几大方向上进行了全面升级。

对于初学者,看起来是不是觉得晦涩难懂,但实际上大家要抓住核心词:服务治理服务通信。这是dubbo框架所提供的核心功能。实际上也是微服务框架所要提供的核心功能。

以前我们讲解过什么是微服务。那么实际上微服务要解决的两个核心问题就是服务治理与通信。

1.1.1 服务治理

服务治理是什么,就是服务的发现与分发,也就是管理有哪些种类的服务、每个种类的服务有多少个实例(可以简单理解为服务实际部署了多少台服务器),再次简化,就是如下的这张表格:

服务名ip
user-server 用户服务192.168.101.1
user-server 用户服务192.168.101.2
user-server 用户服务192.168.101.3
order-server 订单服务192.168.101.4
order-server 订单服务192.168.101.5
order-server 订单服务192.168.101.6

我们有处理用户信息的用户服务,部署了3台服务器,还有处理订单信息的订单服务,同样部署了3台。那么当用户在我们的网站上发起请求时,比如做了一个下单操作。

那么我的流程是要先获取这个用户的用户信息,也就要调用到用户服务,然后再创建订单,也就需要订单服务。那么用户肯定不会知道我们有多个用户服务和订单服务的,也不会知道我们部署这个服务的Ip地址。所以就需要一个东西管理这些服务,将用户的请求自动转发到对应的服务所对应的服务器上。

这样一个操作就是服务治理

在这里插入图片描述

好了,再回到一开始的概念,我们前面说dubbo是服务框架,记住它不是组件,框架是结合具体的项目一起使用的,组件是可以单独部署的。

一般dubbo常常和zookeeper结合来实现服务治理,也就是用zk来做注册中心。如果不了解注册中心概念的,请先阅读上面列举的《什么是微服务》。

我们再说的直白一点,dubbo具体到java项目中,就是我们引入的一个jar包,我们只需要简单的引用,以及配置文件的配置,dubbo就可以帮助我们将我们的服务注册到zookeeper中,zk充当的就是上述那张表格的实时记录

而这些注册、调用的操作,都不需要我们手动时间,而是通过我们引入的dubbo包来自动实现的,这就是框架。

1.1.2 服务通信

还有一个概念是“服务通信”,也称组间调用,也就是解决服务与服务之间的内部调用。

我们看上述的调用图,订单服务为了获取用户信息,需要调用用户服务,这里做习惯了单机架构的同学可能会疑问,你要获取用户信息,你写一个UserService不就完了嘛,你搞什么幺蛾子还单独开个用户服务,这就要理解微服务的核心概念——专业的事专业的服务去干,用户的信息请让用户服务去管,如果一个服务管的东西太多,不就又回到了单机架构了嘛。

当然如果你服务请求的本身的量就不大,项目的规模也没有那么广,那么自然不需要如此细粒度的服务拆分。

我们知道接口调用,可以通过HttpClient来实现,那么服务间调用的时候为什么不直接用httpclient呢,因为没有部署服务前我们根本都不知道服务的ip或域名,这是注册到注册中心后,注册中心告诉我们的。

当然你说我已经规定好了这个服务就要部署到固定的服务器上,那我可以直接用httpclient调用吗?当然可以了,万变不离其中,这本质上就是一个局域网内的接口调用。但是你想想,这足够灵活吗?

所以dubbo做了一个事情,也就是rpc的含义,让服务间调用,像本地调用一样简单!

什么意思?

就是我们调用用户服务时,只需要引一个UserService,然后按照类的形式来使用即可,但这个Serivice是的实现是定义在用户服务中的,这两个都不在一个项目里面,是怎么做到的呢,我们下面来实际搭建一个dubbo微服务,让大家深入感受一下

1.2 项目简介

开始搭建之前,我们先说明本次演示项目的情况,我们将搭建一个订单服务,在订单服务中调用用户信息,以此来创建订单。

因为要用到注册中心,本次演示我们选用zookeeper,当然dubbo支持的注册中心不止zk,还有nacos与consul。

1.3 消费者与生产者

这里额外补充一点,因为dubbo官方讲解中常提到生产者与消费者的概念,对于初学者来讲会有些陌生。

但实际上这个概念非常好理解,比如我上述订单服务要获取用户信息就需要调用用户服务,那么用户服务就是生产者,因为用户服务要提供用户信息。订单服务要调用用户信息,即消费用户信息,所以订单服务是消费者,当然如果订单服务也需要对别的服务提供信息时,也需要将它注册成消费者。

具体我们进入到项目中来看。

如果你是刚学习微服务的同学,更加建议大家在搭建完dubbo后,系统学习下我之前书写的微服务入门专栏:

从零开始学习微服务

在这里插入图片描述

2. 项目搭建

2.1 下载安装

1、首先需要安装zookeeper,为了演示完整,我这里还额外安装了dubbo-admin,一个官方提供的可以可视化管理dubbo服务的web应用。不知道怎么安装的同学可以参考这篇文章:

docker安装dubbo-admin、zookeeper

2.2 搭建父项目

1、我们需要创建一个maven空项目,作为父项目

在这里插入图片描述

注意这里我将版本号和包名做了调整

在这里插入图片描述

2、该项目下不需要任何目录,删除原有的src目录

在这里插入图片描述

3、修改父项目的pom.xml,统一jar包版本管理,注意这里我已经提前将需要用到的jar包的版本号做了声明,同时将子项目的服务名在modules标签中提前说明了。如果后续有新子项目引入,需要在此标签中添加。还要将父项目的打包方式改为pom


4.0.0wu.exampledubbo_wu_demo${project.version}pom1.0.0-SNAPSHOT1.83.8.1UTF-8UTF-82.3.7.RELEASE3.1.2user-serverorder-serverorg.springframework.bootspring-boot-dependencies${spring-boot.version}pomimportorg.apache.dubbodubbo-spring-boot-starter${dubbo.version}org.apache.dubbodubbo-dependencies-zookeeper${dubbo.version}pomsrc/main/java**/*.properties**/*.xmlfalseorg.apache.maven.pluginsmaven-compiler-plugin${maven.version}${java.version}${java.version}UTF-8org.springframework.bootspring-boot-maven-plugin${spring-boot.version}repackage

2.3 创建用户服务user-server

1、在该项目下右键新建一个子项目

在这里插入图片描述

2、创建用户服务,选择springboot框架,注意将包名调整为与父项目一致

在这里插入图片描述

3、为了演示方便,我们引入spring-web依赖

在这里插入图片描述

4、修改user-server项目的pom,引入dubbo-spring-boot-starter,dubbo-dependencies-zookeeper依赖,因为在父项目中已经声明过版本了,所以子项目中就不用在书写版本号了


dubbo_wu_demowu.example1.0.0-SNAPSHOT4.0.0user-server${parent.version}user-serverorg.apache.dubbodubbo-spring-boot-starterorg.apache.dubbodubbo-dependencies-zookeeperpomorg.slf4jslf4j-log4j12org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestorg.junit.vintagejunit-vintage-engine

5、同时为了项目的简洁清爽,以及版本的统一管理,我们做一些调整:
(1)删除多余不需要的文件,将.gitignore,README.md挪到父项目下
(2)配置文件格式改为yml(个人更喜欢yml格式,可以根据你的习惯)
在这里插入图片描述

6、创建一个UserServiceImpl类,用来模拟根据用户ID提供用户信息,因为我们需要给订单服务调用,需要被注册为dubbo服务,所以需要使用@DubboService注解


import org.apache.dubbo.config.annotation.DubboService;/*** @author benjamin_5* @Description* @date 2022/11/19*/
@DubboService
public class UserServiceImpl {public String getUserById(Integer id){return "用户" + id;}}

7、修改配置文件properties.yml

更多的dubbo配置项可参考官方配置项介绍

# 应用名称
dubbo:application:name: user-serverprotocol: # 指定通信规则name: dubbo # 通信协议port: -1 # dubbo协议端口,以供消费者访问,-1即为随机端口registry: # 注册中心id: zk-registryaddress: zookeeper://127.0.0.1:2181# 应用服务 WEB 访问端口
server:port: 8081

8、作为生产者,也就是服务的提供者,我们还需要将其启动类上添加@EnableDubbo注解

2.4 创建订单服务order-server

1、创建springboot项目order-server,与user-server引用同样的依赖,pom.xml如下所示


dubbo_wu_demowu.example1.0.0-SNAPSHOT4.0.0order-server${parent.version}order-serverorg.apache.dubbodubbo-spring-boot-starterorg.apache.dubbodubbo-dependencies-zookeeperpomorg.slf4jslf4j-log4j12org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestorg.junit.vintagejunit-vintage-engine

2、修改配置文件

# 应用名称
dubbo:application:name: user-serverprotocol: # 指定通信规则name: dubbo # 通信协议port: -1 # dubbo协议端口,以供消费者访问,-1即为随机端口registry: # 注册中心id: zk-registryaddress: zookeeper://127.0.0.1:2181# 应用服务 WEB 访问端口
server:port: 8082

3、创建一个接口,用来模拟订单创建,需要在这个接口内调用用户服务的UserServiceImpl,dubbo中引用service需要使用@DubboReference

但问题出现了,我们直接引用是会报错的,那这要怎么操作呢?不是说的像本地调用这么简单吗

在这里插入图片描述

4、毕竟还是在两个服务中,要想纯粹的直接调用肯定出问题,那可以想一想,先不考虑调用的问题,想让一个类能够在另一个服务中调用的方法是什么?

没错,就是引用,当然我们不能直接在order-server中引用user-server,不然要是用户服务也需要调订单服务的话,不就造成循环依赖了吗

5、我们创建一个server-api服务,专门用于存放service接口类

在这里插入图片描述

6、该服务不需要启动类,仅需要创建一个UserService接口,声明接口方法

在这里插入图片描述

项目依赖如下,因为没有启动类,所以要单独调整其打包方式:


dubbo_wu_demowu.example1.0.0-SNAPSHOT4.0.0service-api${parent.version}user-serverorg.springframework.bootspring-boot-maven-plugintrue${project.name}

同时父项目pom中要把该项目的module加上

在这里插入图片描述

7、创建完成后项目整体mvn install一下,让server-api包存放到本地仓库,方便其他服务引用

在这里插入图片描述

在这里插入图片描述

8、在user-server,order-server中都引入server-api

wu.exampleservice-api${parent.version}

9、修改user-server中的UserServiceImpl,让申明UserService接口

@DubboService
public class UserServiceImpl implements UserService {@Overridepublic String getUserById(Integer id){return "用户" + id;}}

10、同时order-server中则不再引用UserServiceImpl了,而是引用其接口类

@RestController
public class OrderController {@DubboReferenceprivate UserService userService;@GetMapping("createOrder")public String createOrder(Integer id){String userName = userService.getUserById(id);return userName + " createOrder success";}
}

所以到这里,大家明白dubbo组间调用的使用方法了吗?

2.5 测试

1、我们将订单服务和用户服务启动起来,注意先启动生产者user-server,再启动生产者order-server

我们使用zk可视化工具prettyZoo,可以看到服务已经注册上去了

在这里插入图片描述

同时也可以用dubbo-admin查看

在这里插入图片描述

这里我们可以看到,只有生产者会注册上去,而消费者只是从注册中心拉取服务

2、调用创建用户的接口

在这里插入图片描述

调用成功!

总结

如上,我们针对dubbo框架的简单搭建就完成了, 实际还可以接入gateway来实现网关,或者也可以使用Nginx来做一层代理。后续我们一一演示

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...