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 如何计算两个汉字的相似度?如何获得一个汉字的相似汉字?

    计算汉字相似度 情景 有时候我们希望计算两个汉字的相似度,比如文本的 OCR 等场景.用于识别纠正. 实现 引入 maven <dependency> <groupId>com ...

  2. 使用@ControllerAdvice统一处理自定义异常

    最近工作中涉及到捕捉AOP方法中抛出的异常. 想针对某一种异常做一个统一的处理器并封装好异常信息以JSON格式交给前端进行提示. 主要实现的话有以下几步: 1.编写自定义异常类 package com ...

  3. Mac技巧之苹果电脑上将一个软件进程的 CPU 占用率限制在指定范围内:cputhrottle

    苹果电脑 Mac OS X 系统上,我们可以用 cputhrottle 这个免费工具,配合活动监视器和终端,把一个软件进程的 CPU 占用率限制在指定值(比如 20%)以内,以防止应为它 " ...

  4. Selenium入门介绍

    目录 Selenium概述 浏览器支持 工具库 开发实践 等待 操作浏览器 定位元素 定位单个元素 定位多个元素 获取HTML元素内容的方式 Selenium概述 https://github.com ...

  5. Unity学习笔记--数据持久化Json

    JSON相关 json是国际通用语言,可以跨平台(游戏,软件,网页,不同OS)使用, json语法较为简单,使用更广泛.json使用键值对来存储. 认识json文件 //注意字典类型存储时,键是以st ...

  6. React 组件通信方式

    人生的游戏不在于拿了一副好牌,而在于怎样去打好坏牌,世上没有常胜将军,勇于超越自我者才能得到最后的奖杯. 1. 父子组件通信方式 1.1 父组件传递到子组件 直接通过属性进行传递,数据的传递可以提高组 ...

  7. Java面向对象之接口和抽象类的区别一目了然

    介绍 相信对于Java面向对象部分,很多人很长一段时间对于接口和抽象类的区别,使用场景都不是很熟悉,同是作为抽象层重要的对象,工作中到底什么情况下使用抽象类,不是很清楚.本文就一次性把这些概念一次性说 ...

  8. 【Azure Key Vault】在Alteryx中使用Azure Key Vault存储账号和密码并实现无交互登录

    问题描述: 需要在Alteryx中使用Azure Key Vault, Alteryx 能将数据发布到 Tableau,需要输入账号和密码,使用Azure Key Vault来替换这个输入账号和密码的 ...

  9. 【Azure Service Bus】使用Spring Cloud integration示例代码,为多个 Service Bus的连接使用 ConnectionString 方式

    问题描述 查看Service Bus的Java示例代码,发现使用Spring Cloud Integration,配置 Application.yaml 可以连接到两个Service Bus. 但代码 ...

  10. 【Azure 云服务】云服务(经典) 迁移至云服务(外延支持) 的相关疑问

    问题描述 根据微软官方文档说明,云服务(经典)已弃用.所以关于它有以下的一些疑问: 一:迁移时候的停机时间问题? 二:云服务(经典) 与 云服务(外延支持) 的区别是什么? 三:注意事项有那些呢?如 ...