1、Dubbo介绍

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

Dubbo官网:https://cn.dubbo.apache.org/zh-cn/

Dubbo文档:https://cn.dubbo.apache.org/zh-cn/overview/quickstart/

Dubbo GitHub地址:https://github.com/apache/dubbo

Dubbo 使用版本对应关系:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明#2021x-分支 选择和项目相互对应的版本进行使用。这里我使用的是Dubbo 2.7.8

2、Dubbo连接注册中心

Dubbo推荐使用Zookeeper作为注册中心,Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境。除此之外Dubbo还可以使用阿里巴巴的nacos做注册中心。Nacos作为注册中心Dubbo使用与ZooKeeper基本相同,在使用上,不同的地方只有以下两点:

  • 1、导入的依赖,配置不同;
  • 2、注解不同,ZooKeeper使用@Service、@Reference注解,Nacos使用@DubboService、@DubboReference注解;

3、Dubbo负载均衡

  • RandomLoadBalance:加权随机,默认算法,默认权重相同;
  • RoundRobinLoadBalance:加权轮询,默认权重相同;
  • LeastActiveLoadBalance:最少活跃优先+加权随机,能者多劳;
  • ConsistentHashLoadBalance:一致性Hash,确定入参,确定提供者,适用于有状态的请求;

4、Dubbo Admin下载与使用

官网地址:https://github.com/apache/dubbo-admin

Dubbo和Dubbo Admin版本说明:https://cn.dubbo.apache.org/zh-cn/blog/2019/01/07/新版-dubbo-admin-介绍/

4.1、修改配置文件

进入dubbo-admin-server的resources目录,修改application.properties文件修改配置中心。默认为zookeeper:

admin.registry.address注册中心
admin.config-center 配置中心
admin.metadata-report.address元数据中心

由于我使用nacos,修改注册中心为nacos。 nacos注册中心有 GROUP 和 namespace:

admin.registry.address=nacos://127.0.0.1:8848?group=DEFAULT_GROUP&namespace=public&username=nacos&password=nacos
admin.config-center=nacos://127.0.0.1:8848?group=dubbo&username=nacos&password=nacos
admin.metadata-report.address=nacos://127.0.0.1:8848?group=dubbo&username=nacos&password=nacos
//改为自己的注册中心:
admin.registry.address=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
admin.config-center=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
admin.metadata-report.address=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
4.2、Dubbo Admin项目打包

在项目根目录进行打包,跳过测试:

mvn clean package -Dmaven.test.skip=true

进入dubbo-admin-0.6.0/dubbo-admin-distribution/target 进行启动后端:

java -jar dubbo-admin-0.6.0.jar

dubbo-admin-ui 目录下执行命令启动前端:

npm run dev

这是官方项目开发环境说明,打开项目就能看到:

4.3 访问dubbo admin

浏览器输入地址进行访问,之前的dubbo-admin老版本用的是Tomcat启动的,后端端口是8080(可能会冲突),前端端口是8081

http://localhost:8081

新版的dubbo-admin用的是Netty,默认配置端口是38080,前端端口38082

http://localhost:38082 或 http://localhost:38080

用户名密码都是root

登录成功:

5、SpringCloud集成Dubbo

在SpringBoot模块中引入maven依赖:

<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

这里使用用户模块和订单模块模拟微服务使用Dubbo RPC的调用。在提供者模块中加入Dubbo依赖,在配置文件中设置dubbo连接注册中心和配置中心:

dubbo:
application:
name: user-service-model-provider
protocol:
name: dubbo
port: -1
provider:
group: DEFAULT_GROUP
version: 2.0
#port: 20881
registry:
address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
#配置nacos自定义命名空间
parameters:
namespace: 23857f22-27ac-4947-988a-1b88d4eeb807
group: DEFAULT_GROUP
# registry:
# address: zookeeper://${zookeeper.address:127.0.0.1}:2181
metadata-report:
address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
#配置nacos自定义命名空间
parameters:
namespace: 23857f22-27ac-4947-988a-1b88d4eeb807

配置添加成功后,在业务模块service层,新建一个对外提供的dubbo实现类UserExternalServiceImpl,需要使用@DubboService注解,@Service注解尽量不要使用,可以使用@Componet代替。代码如下:

//@Service
@Component
@DubboService(timeout = 1000 * 10,group = "userGroup",version = "2.0")
public class UserExternalServiceImpl implements IUserExternalService { @Autowired
private IUserService userService; @Override
public Response selectUserAll() {
// try {
// TimeUnit.MILLISECONDS.sleep(1000*5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return Response.success(userService.selectUserAll());
} @Override
public Response insert(UserExternal userExternal) {
// boolean flag = true;
// if (flag == true){
// throw new ParamException(500,"用户模块出现错误,需要回滚");
// }
// try {
// TimeUnit.MILLISECONDS.sleep(20000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
User user=new User();
BeanUtils.copyProperties(userExternal,user);
boolean save = userService.save(user);
if (save){
return Response.success();
}else {
return Response.fail();
}
}
}

然后还需要在新建一个专门存dubbo的对外接口服务模块用interface-module名称,在该模块中新建一个IUserExternalService接口,该接口实现在用户模块中的UserExternalServiceImpl实现类:

public interface IUserExternalService {

    Response<List<UserExternal>> selectUserAll();

    Response insert(UserExternal user);
}

现在我们的接口提供方已经编写完成了,接下来开始编写接口使用方也就是消费者。在订单模块中引入dubbo依赖,在配置文件中将dubbo连接注册中心和配置中心:

dubbo:
application:
name: order-service-model-consumer
consumer:
group: DEFAULT_GROUP
version: 2.0
protocol:
name: dubbo
port: -1
registry:
address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
#配置nacos自定义命名空间
parameters:
namespace: 23857f22-27ac-4947-988a-1b88d4eeb807
# registry:
# address: zookeeper://${zookeeper.address:127.0.0.1}:2181
cloud:
subscribed-services: user-service-model-provider
metadata-report:
address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
#配置nacos自定义命名空间
parameters:
namespace: 23857f22-27ac-4947-988a-1b88d4eeb807

下面我们需要引入刚刚新建存dubbo接口模块的依赖包,然后就可以使用该接口了。首先建一个IDubboUserService的接口实现DubboUserServiceImpl类,意思是这个类是专门存放通过dubbo接口调用用户模块的业务类,后续在订单模块中处理用户模块信息都可以在该业务类中进行处理。

IDubboUserService类代码:

public interface IDubboUserService {

    List<UserExternal> selectUserAll();

}

DubboUserServiceImpl业务类代码,需要在该类中使用@DubboReference(group = "userGroup",version = "2.0")注解注入IUserExternalService接口信息,通过Dubbo RPC实现远程调用,注意group 和version 需要和提供方相互对应,不然会注入失败:

@Service
@Slf4j
public class DubboUserServiceImpl implements IDubboUserService { @DubboReference(group = "userGroup",version = "2.0")
private IUserExternalService userExternalService; @Override
public List<UserExternal> selectUserAll() {
//添加blog
Blog blog = new Blog();
blog.setUid(UUID.randomUUID().toString());
blog.setTitle("dubbo测试Test");
blog.setContent("啊");
blog.setSummary("12");
blog.setTagUid("3c16b9093e9b1bfddbdfcb599b23d835");
blogService.insert(blog);
//处理相关逻辑
Response<List<UserExternal>> response = userExternalService.selectUserAll();
UserExternal user = new UserExternal();
user.setUserName("dubbo测试Test");
user.setAccount("system");
user.setEmail("dubbo@gemail.com");
Response insert = userExternalService.insert(user);
System.out.println(insert);
return response.getModel();
}
}

通过上面的代码,就可以实现服务模块与模块之间的远程调用了。使用Dubbo在订单模块调用用户模块就和调用其他业务类代码一样通过依赖注入就可以了,是不是非常方便。

5、dubbo使用Sentinel进行限流和异常兜底

需要引入Maven依赖:

        <!-- 在dubbo中使用 Sentinel 需要添加下面依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>

由于限流和兜底是消费方要处理的事情,所以我们只需要在订单模块中引入上面依赖即可。在DubboUserServiceImpl中,通过@SentinelResource注解处理,代码如下:

@Service
@Slf4j
public class DubboUserServiceImpl implements IDubboUserService { @DubboReference(group = "userGroup",version = "2.0")
private IUserExternalService userExternalService; @Autowired
private IBlogService blogService; // @PostConstruct
// private void initFlowRules(){
// System.out.println("Sentinel initFlowRules start===");
// List<FlowRule> rules = new ArrayList<>();
// FlowRule rule = new FlowRule();
// rule.setResource(IDubboUserService.class.getName());
// rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// // Set limit QPS to 20.
// rule.setCount(20);
// rules.add(rule);
// FlowRuleManager.loadRules(rules);
// System.out.println("Sentinel initFlowRules end====");
// } @Override
@SentinelResource(value = "com.itmy.user.service.IUserExternalService:selectUserAll()", //当前方法的路径
blockHandler = "selectUserAll",
blockHandlerClass = CustomerBlockHandler.class, //触发限流 走该类的blockHandler = "selectUserAll"方法
fallback = "selectUserAllFallback",
fallbackClass = UserFallback.class, //dubbo调用接口异常,走该类的 fallback = "selectUserAllFallback"方法
exceptionsToIgnore = {IllegalArgumentException.class})
//fallback 负责业务异常 blockHandler限流方法 exceptionsToIgnore 报该异常fallback不处理
@GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 30000,name = "order_tx_group") //seata事务注解,目前没有使用后面会在seata博客中介绍。
public List<UserExternal> selectUserAll() {
//添加blog
Blog blog = new Blog();
blog.setUid(UUID.randomUUID().toString());
blog.setTitle("dubbo事务测试Test");
blog.setContent("dubbo事务测试Test啊的服务器打");
blog.setSummary("12");
blog.setTagUid("3c16b9093e9b1bfddbdfcb599b23d835");
blogService.insert(blog);
//处理相关逻辑
Response<List<UserExternal>> response = userExternalService.selectUserAll();
// boolean flag = true;
// if (flag == true){
// throw new ParamException(500,"用户模块出现错误,需要回滚");
// }
UserExternal user = new UserExternal();
user.setUserName("dubbo事务");
user.setAccount("system");
user.setEmail("dubbo@gemail.com");
Response insert = userExternalService.insert(user);
System.out.println(insert);
return response.getModel();
}
}

CustomerBlockHandler处理限流的相关代码:

@Slf4j
public class CustomerBlockHandler { /**
* 查询用户热点限流测试
* @param name
* @param email
* @param exception
* @return
*/
public static Response selectUserBlockException(@RequestParam(value = "name",required = false) String name,
@RequestParam(value = "email",required = false) String email,
BlockException exception){
log.error("CustomerBlockHandler|selectUserBlockException is fail");
return Response.fail(FallbackErrorEnum.USER_MODULE_FALL);
} /**
* 查询限流
* @return
*/
public static Response redisFindBlockException(BlockException exception){
log.error("添加订单 redis|添加用户 redis信息,调用接口被限流。。。。。");
return Response.fail(FallbackErrorEnum.REDIS_FIND_FALL);
} public List<UserExternal> selectUserAll(BlockException exception){
log.error("添加订单|添加用户信息,触发限流控制。。。。。");
throw new ParamException(600,"添加用户信息异常:"+exception.getMessage());
} }

UserFallback异常处理:

@Slf4j
public class UserFallback { public static List<UserExternal> selectUserAllFallback(Throwable throwable) {
log.error("添加订单|添加用户信息异常,触发熔断兜底操作。");
throw new ParamException(600,"添加用户信息异常,触发兜底操作");
}
}

6、总结

SpringCloud集成Dubbo到目前为止就介绍完毕了,希望本博客对你有所帮助。目前只介绍了如何使用dubbo,dubbo还有需多需要去学习的地方,让我们持续学习新的知识,来应对工作中的各种问题。

SpringCloud微服务集成Dubbo的更多相关文章

  1. 微服务框架Dubbo与Springcloud的区别

    微服务框架Dubbo与Springcloud的区别 微服务主要的优势如下: 1.降低复杂度 将原来偶合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累.每一个微服务专注于单一功能,并通过定 ...

  2. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上)

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上) Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 1) 开发 ...

  3. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成--部署方案优化 之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个 ...

  4. 08 . Jenkins之SpringCloud微服务+Vue+Docker持续集成

    简介 大致流程 /* 1.开发人员每天把代码提交到Gitlab代码仓库 2.jenkins从gitlab中拉取项目源码,编译并打包成war包,然后构建Docker镜像,将镜像上传到Harbor私有仓库 ...

  5. SpringCloud微服务学习笔记

    SpringCloud微服务学习笔记 项目地址: https://github.com/taoweidong/Micro-service-learning 单体架构(Monolithic架构) Mon ...

  6. Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

    Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...

  7. SpringCloud微服务基础学习

    看了蚂蚁课堂的微服务学习,确实学习了不少关于微服务的知识,现在总结学习如下 : SpringCloud微服务基础单点系统架构传统项目架构传统项目分为三层架构,将业务逻辑层.数据库访问层.控制层放入在一 ...

  8. SpringCloud微服务治理技术入门(SCN)

    1.集群.分布式.微服务 首先先理解三个感念 什么是集群?: 同一个业务,部署在多个服务器上,目的是实现高可用,保证节点可用! 什么是分布式?: 一个业务分拆成多个子业务,部署在不同的服务器上,每个子 ...

  9. SpringCloud微服务框架复习笔记

    SpringCloud微服务框架复习笔记 什么是微服务架构? 微服务是一种软件开发技术,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进 ...

  10. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...

随机推荐

  1. Java压缩和解压缩zip文件

    介绍 Java提供的java.util.zip包只支持zip和gzip.至于更多格式的压缩可以选择apache的Commons Compress. 参考:https://o7planning.org/ ...

  2. git tag 常用操作-创建、查看、推送、删除等

    创建tag 1.创建tag: git tag -a v0.0.1 或者 对某一提交的信息打tag标签,末尾是一个commit id git tag -a v0.0.1 cc16905 2.创建tag带 ...

  3. 【Android逆向】制作Fart脱壳机,完成对NCSearch的脱壳操作

    1. 我的手机是Pixel 1 ,下载fart对应的镜像 镜像位置具体参考大佬博客 https://www.anquanke.com/post/id/201896 2 执行 adb reboot bo ...

  4. 从零开始写 Docker(二)---优化:使用匿名管道传递参数

    本文为从零开始写 Docker 系列第二篇,主要在 mydocker run 命令基础上优化参数传递方式,改为使用 runC 同款的匿名管道传递参数. 如果你对云原生技术充满好奇,想要深入了解更多相关 ...

  5. 工作中django的应用路径配置

    1.通常工作中都会把所有的应用放在一个主目录中 比如:主项目文件夹为luffyapi 在luffyapi下创建一个apps文件夹,用来存放所有的app应用 2.创建应用 先创建一个应用,需要cd到ap ...

  6. 高效的PDF文字提取技术

    无论是行政法规.学术论文还是企业合同,PDF文档为我们提供了一种便捷.稳定的信息传递方式.然而,从PDF文件中提取文本信息对于数据分析.内容编辑等后续处理来说至关重要. PDF文本提取技术是一种可以从 ...

  7. 三分钟数据持久化:Spring Boot, JPA 与 SQLite 的完美融合

    三分钟,迎接一个更加高效和简便的开发体验. 在快节奏的软件开发领域,每一个简化工作流程的机会都不容错过.想要一个无需繁琐配置.能够迅速启动的数据持久化方案吗?这篇文章将是你的首选攻略.在这里,我们将向 ...

  8. canal实现mysql跨机房备份

    背景介绍 跨机房数据库数据备份 数据库增量异构系统分发(cache,mq等) 数据内容聚合分析组件 摘录作者的描述 原理图 canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL ...

  9. Nebula Graph 1.0 Release Note

    Nebula Graph 1.0 发布了.作为一款开源分布式图数据库,Nebula Graph 1.0 版本旨在提供一个安全.高可用.高性能.具有强表达能力的查询语言的图数据库. 基本功能 DDL & ...

  10. C++ //统计元素个数 //统计内置数据类型 //统计自定义数据类型

    1 //统计元素个数 2 3 #include<iostream> 4 #include<string> 5 #include<vector> 6 #include ...