由浅入深Dubbo核心源码剖析高阶配置运用

news2025/1/19 8:03:47

目录

  • 1 不同配置覆盖关系
  • 2 属性配置优先级
  • 3 重试与容错处理机制
  • 4 多版本控制
  • 5 本地存根调用
  • 6 负载均衡机制
  • 7 服务降级运用
  • 8 并发与连接控制


1 不同配置覆盖关系

在这里插入图片描述

Dubbo高阶配置运用
关于配置参看官方文档:https://dubbo.apache.org/zh/docsv2.7/user/configuration/

演示:

1、通过ProviderConfig配置全局超时(可通过yml配置覆盖)

2、在@DubboService注解上配置接口超时

3、在@DubboService注解上配置接口方法超时

4、在消费方进行配置,查看覆盖情况

  1. 覆盖规则:

在这里插入图片描述

配置规则:

  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之。
  1. 服务端超时设定

    增加配置类:

@Configuration
public class DubboCustomConfig {

    /**
     *  服务端
     * @return
     */
    @Bean
    public ProviderConfig registryConfig() {
        ProviderConfig providerConfig = new ProviderConfig();
        // 设定超时时间为5S
        providerConfig.setTimeout(5000);
        return providerConfig;
    }
}

修改服务接口实现:

设定模拟睡眠时间

    /**
     * 获取订单详情
     * @param orderId
     * @return
     */
    public String getOrder(Long orderId) {
        try {
            // 休眠1.5秒
            Thread.sleep(1500L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Get Order Detail, Id: " + orderId + ", serverPort: " + serverPort;
    }
  1. 客户端调用验证

    http://127.0.0.1:18084/order/getOrder?orderId=123

    • 服务端全局超时设为2秒(不触发超时), 消费端设定超时时间为1秒(触发超时)。

      修改调用代码:

    /**
     * 订单服务接口
  */
    @DubboReference(version = "${dubbo.spring.provider.version}", timeout = 1000)
 private OrderService orderService;
 调用结果, 触发超时:

在这里插入图片描述

 表明消费端配置优先。
  • 服务端全局超时设定为1秒(触发超时), 消费端去掉超时时间配置。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NtRBunAs-1684741065506)(D:\18、狂野架构师\狂野架构师资料\狂野架构 - 课件资料\01-02阶段课程资料\dubbo源码剖析\讲义\images\image-20210119111947521.png)]

    触发超时, 表明服务提供方优先级次之。

2 属性配置优先级

在这里插入图片描述

优先级从高到低:

  • JVM -D 参数;
     -Ddubbo.protocol.port=20881
  • XML(application.yml/application.properties)配置会重写 dubbo.properties 中的,一般配置项目特有的
dubbo:
  protocol:
    name: dubbo # 通讯协议
    #port: 20880   # dubbo服务提供方的端口,该值是默认值
    port: 20882
  • Properties默认配置(dubbo.properties),仅仅作用于以上两者没有配置时,一般配置全局公共配置
     dubbo.protocol.port=20883
  1. JVM参数优先级验证

    • application.properties里面配置了dubbo.protocol.port端口10888

    • JVM运行参数端口设定为-Ddubbo.protocol.port=10889

在这里插入图片描述

  • 启动服务

在这里插入图片描述

 服务启动完成, 可以看到端口优先以JVM参数为准。
  1. Properties配置文件验证

    • 注释掉application.properties里面配置的dubbo.protocol.name和dubbo.protocol.port配置

    • dubbo.properties里面配置dubbo.protocol.name和dubbo.protocol.port

    • 在启动参数里, 添加-Ddubbo.properties.file=dubbo.properties

在这里插入图片描述

  • 启动服务

    查看dubbo.properties配置的端口, 可以看到正常生效:

C:\Users\hxx68>netstat -ano |findstr 30889
  TCP    0.0.0.0:30889          0.0.0.0:0              LISTENING       49816
  TCP    [::]:30889             [::]:0                 LISTENING       49816

3 重试与容错处理机制

  1. 容错机制:

    • Failfast Cluster

      快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

    • Failsafe Cluster

      失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

    • Failback Cluster

      失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

    • Forking Cluster

      并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=“2” 来设置最大并行数。

    • Broadcast Cluster

      广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

    后面章节还会对其原理做详细讲解。

  2. 调整客户端重试次数

    /**
     * 订单服务接口
     */
    @DubboReference(version = "${dubbo.spring.provider.version}",retries = 3)
    private OrderService orderService;

这里的重试次数设定为3次。

  1. 修改服务端超时时间

    模拟超时, 让客户端触发重试。

    /**
     *  服务端全局配置
     * @return
     */
    @Bean
    public ProviderConfig registryConfig() {
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setTimeout(1000);
        return providerConfig;
    }

将超时时间设小一些为1秒。

  1. 客户端调用(单个服务)

    http://127.0.0.1:18084/order/getOrder?orderId=123

    查看服务端控制台,可以看到触发重试机制:

在这里插入图片描述

加上第一次的调用和3次重试, 共4次。

  1. 客户端调用(多个,涉及到负载均衡机制,后面再测试)

    允许多个实例运行, 开启多个服务

    访问接口, http://127.0.0.1:18084/order/getOrder?orderId=123

在这里插入图片描述

第一个服务实例,访问两次, 其他每个服务访问一次。

4 多版本控制

  1. 启动三个服务端

    第一个服务端版本为1.0.0, 第二、三个服务端版本分别为:2.0.0 和 3.0.0

    主要是修改application.properties配置:

#服务版本号
dubbo.spring.provider.version = 2.0.0
  1. 启动三个服务提供者,通过-Ddubbo.spring.provider.version = 2.0.0 -Dserver.port=18082来启动三个

    相关的端口不能重复

  2. 消费端指定版本号

    同样修改application.properties配置:

#服务版本号
dubbo.spring.provider.version = 2.0.0

仍然通过-Ddubbo.spring.provider.version = 2.0.0来调用不同版本的服务

测试时,注释掉超时的代码

  1. 仍是采用超时配置, 通过重试测试验证

    测试验证结果:

    请求只会访问至版本号为2.0.0的服务节点上面。

5 本地存根调用

  1. 实现流程

在这里插入图片描述

把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。

  1. 客户端存根实现:

    增加service接口

public class OrderServiceStub implements OrderService {

    private final OrderService orderService;

    // 构造函数传入真正的远程代理对象
    public OrderServiceStub(OrderService orderService){
        this.orderService = orderService;
    }

    /**
     * 获取订单详情
     * @param orderId
     * @return
     */
    public String getOrder(Long orderId){
        // 在客户端执行, 预先验证参数是否合法,等等
        try {
            if(null != orderId) {
                return orderService.getOrder(orderId);
            }
            return "参数校验错误!";
        } catch (Exception e) {
            //容错处理
            return "出现错误:" + e.getMessage();
        }
    }
}
  1. 修改客户端调用配置
    /**
     * 订单服务接口
     */
    @DubboReference(version = "${dubbo.spring.provider.version}",retries = 3, stub = "com.itheima.dubbo.spring.consumer.service.OrderServiceStub")
    private OrderService orderService;

stub要配置存根接口的完整路径。

  1. 测试调用

    访问不带参数的地址: http://127.0.0.1:18084/order/getOrder

在这里插入图片描述

会进入存根接口的处理逻辑, 提示校验异常。

6 负载均衡机制

  1. 默认负载策略

    Dubbo默认采用的是随机负载策略。

    开启三个服务节点,通过消费端访问验证: http://127.0.0.1:18084/order/getOrder?orderId=123

    通过控制后台日志输出, 可以看到每个服务节点呈现不规则的调用。

  2. Dubbo 支持的负载均衡策略,可用参看源码:AbstractLoadBalance

    • Random LoadBalance:默认

      随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

    • RoundRobin LoadBalance

      加权轮询负载均衡,按公约后的权重设置轮询比率。 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

    • LeastActive LoadBalance

      最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 活跃数其实就是在当前这个服务调用者中当前这个时刻 某个invoker(某个服务提供者的某个接口)某个方法的调用并发数,在调用之前+1 调用之后-1的一个计数器,如果出现多个活跃数相等invoker的时候使用随机算法来选取一个

    • ConsistentHash LoadBalance

      一致性 Hash,相同参数的请求总是发到同一提供者。 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

一致性Hash负载均衡涉及到两个主要的配置参数为hash.argumentshash.nodes

hash.arguments : 当进行调用时候根据调用方法的哪几个参数生成key,并根据key来通过一致性hash算法来选择调用结点

hash.nodes: 为结点的副本数

  • ShortestResponseLoadBalance

    2.7.7 +新增

    最短响应时间负载均衡

    从多个服务提供者中选择出调用成功的且响应时间最短的服务提供者,由于满足这样条件的服务提供者有可能有多个。所以当选择出多个服务提供者后要根据他们的权重做分析,如果权重一样,则随机

    源码实现: org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance

    Dubbo提供了四种实现:

在这里插入图片描述

  1. 四种配置方式:

    优先级从下至上:

    • 服务端的服务级别:
     <dubbo:service interface="..." loadbalance="roundrobin" />
  • 客户端的服务级别:
     <dubbo:reference interface="..." loadbalance="roundrobin" />
 注意:服务提供者配置后最终也只是同步到消费者端。故一般在消费端配置
  • 服务端方法级别:
 <dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
  • 客户端方法级别:
<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>
 当然这里还有全局配置(略),
  1. 调用验证

    修改客户端的负载策略, 改为轮询策略:

    注意很多配置都有三个级别,针对方法的,针对接口的,全局的。

@DubboReference(version = "${dubbo.spring.provider.version}",retries = 3,
            loadbalance = "roundrobin",
            stub = "com.itheima.dubbo.spring.consumer.service.OrderServiceStub")

开启三个服务节点, 进行访问验证: http://127.0.0.1:18084/order/getOrder?orderId=123

会依次轮询进行调用。

​ 注意:测试时将服务提供者的版本号都调成一致(1.0.0),超时配置注释掉!

  1. 动态权重调整验证

    管理后台地址: http://127.0.0.1:8080/#

    通过管理后台修改服务的权重配置:

在这里插入图片描述

将两台节点的权重降低至20:

在这里插入图片描述

调整后可以看到权重配置已经生效:

在这里插入图片描述

通过消费者接口访问, 会发现第一台权重较大的节点, 访问次数会明显增多。

7 服务降级运用

  1. 服务动态禁用

    启动单个服务节点,进入Dubbo Admin, 创建动态配置规则:

configVersion: v2.7
enabled: true
configs:
  - side: provider
    addresses:
      - '0.0.0.0:20880'
    parameters:
      timeout: 3000
      disabled: true

将disabled属性设为true, 服务禁用, 可以错误提示:

在这里插入图片描述

将disabled属性改为false,

configVersion: v2.7
enabled: true
configs:
  - side: provider
    addresses:
      - '0.0.0.0:20880'
    parameters:
      timeout: 3000
      disabled: false
恢复正常访问:

在这里插入图片描述

  1. 服务降级

    • 配置规则
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
 > - `mock=force:return+null` 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
 > - 还可以改为 `mock=fail:return+null`表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
  • 降级测试(force方式)

    进入Dubbo Admin进行配置:

configVersion: v2.7
enabled: true
configs:
  - side: consumer
    addresses:
      - 0.0.0.0
    parameters:
      timeout: 3000
      mock: 'force:return null'
 客户端调用, 会直接屏蔽, 并且服务端控制台不会有任何调用记录:

 ![image-20210121165217882](D:\18、狂野架构师\狂野架构师资料\狂野架构 - 课件资料\01-02阶段课程资料\dubbo源码剖析\讲义\images\image-20210121165217882.png)
  • 降级测试(fail方式)

    进入Dubbo Admin配置:

configVersion: v2.7
enabled: true
configs:
  - side: consumer
    addresses:
      - 0.0.0.0
    parameters:
      timeout: 1000
      mock: 'fail:return null'
 这里为了触发调用异常, 超时时间缩短为1秒。

 注意这里的超时时间可能不会起作用,最终的超时时间还是得看项目中配置,故在服务提供方将线程休眠时间延长,造成调用超时。

 客户端调用, 会出现降级显示为空: 

 ![image-20210121165544731](D:\18、狂野架构师\狂野架构师资料\狂野架构 - 课件资料\01-02阶段课程资料\dubbo源码剖析\讲义\images\image-20210121165544731.png)

 同时服务端会有调用记录显示(请求会进入服务端,但由于超时, 调用是失败):

 ![image-20210121165617267](D:\18、狂野架构师\狂野架构师资料\狂野架构 - 课件资料\01-02阶段课程资料\dubbo源码剖析\讲义\images\image-20210121165617267.png)

8 并发与连接控制

实际运用, 会碰到高并发与峰值场景, Dubbo是可以做到并发与连接数控制。

可使用jmeter进行测试!

并发数控制

  1. 服务端控制

    • 服务级别
     <dubbo:service interface="com.foo.BarService" executes="10" />
 服务器端并发执行(或占用线程池线程数)不能超过 10 个。
  • 方法级别
 <dubbo:service interface="com.foo.BarService">
    <dubbo:method name="sayHello" executes="3" />
</dubbo:service>
 限制具体的方法,服务器端并发执行(或占用线程池线程数)不能超过3 个。
  1. 客户端控制

    • 调用的服务控制
     <dubbo:reference interface="com.foo.BarService" actives="10" />
 每客户端并发执行(或占用连接的请求数)不能超过 10 个。
  • 调用的服务方法控制
<dubbo:reference interface="com.foo.BarService">
    <dubbo:method name="sayHello" actives="10" />
</dubbo:service>
 [dubbo:reference](dubbo:reference)比[dubbo:service](dubbo:service)优先。
  1. 客户端负载配置
   <dubbo:reference interface="com.foo.BarService"loadbalance="leastactive" />

负载策略为最小连接数时, Loadbalance 会调用并发数最小的 Provider。

连接数控制

  1. 服务端连接控制
   <dubbo:provider protocol="dubbo" accepts="10" />

限制服务器端接受的连接不能超过 10 个

  1. 客户端连接控制
   <dubbo:reference interface="com.foo.BarService" connections="10" />

限制客户端服务使用连接不能超过 10 个

如果 dubbo:service 和 dubbo:reference 都配了 connections,dubbo:reference 优先。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/556430.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-python_bobo

Python Bobo&#xff1a;轻量级Web框架 Python是一个强大的编程语言&#xff0c;被广泛用于web应用程序和数据科学。用Python构建web应用程序的其中一条途径是使用框架。它们提供了一些实用的功能&#xff0c;如路由、模板、数据库集成等等。 Python中许多框架都很强大&#x…

Keil Debug 串口调试技巧

Keil Debug 串口调试技巧 效果 debug窗口效果 虚拟串口效果 debug窗口实现方法 第一步&#xff1a;配置参数 更改对应的bebug窗口参数 两边的 Dialog DLL 更改为&#xff1a;DARMSTM.DLL两边的 Parameter &#xff08;这里的根据单片机型号更改&#xff09;更改为&#xff…

chatgpt赋能Python-python_char

Python Char&#xff1a;了解 Python 字符的基础知识 Python是一种广泛使用的编程语言&#xff0c;因其易于学习、语法简单且适用于不同的应用场景而备受欢迎。在Python中&#xff0c;字符是一种重要的数据类型&#xff0c;也是值得深入学习的主题之一。本文将介绍Python字符的…

基于 Docker 搭建 ownCloud 个人云盘

本文源码&#xff1a;https://github.com/chen2438/chenhaotian.top/tree/main/source/_posts/linux-app/owncloud.md 在我的博客上查看&#xff1a;https://chenhaotian.top/2022/09/07/linux-app/owncloud/ 基于 Docker 搭建 ownCloud 个人云盘 官方文档 机翻气息贯穿全文…

【JUC基础】09. LockSupport

1、什么是LockSupport LockSupport是一个线程阻塞工具&#xff0c;可以在线程任意位置让线程阻塞。线程操作阻塞的方式其实还有Thread.suspend()和Object.wait()。而LockSupport与suspend()相比&#xff0c;弥补了由于resume()方法而导致线程被挂起&#xff08;类似死锁&#x…

chatgpt赋能Python-python_bin目录

了解Python中的Bin目录 如果你是Python编程的初学者&#xff0c;可能会对Python中的Bin目录感到困惑。本文将为你介绍Bin目录的作用&#xff0c;以及为什么它对于Python编程人员来说是如此重要。 什么是Bin目录&#xff1f; Bin目录是Python安装时创建的一个目录&#xff0c…

Linux Yum指令

目录 一.yum 二.使用yum下载软件指令 1.安装指令&#xff1a; 2.查找在yum中所下载软件的指令&#xff1a; 3.卸载指令&#xff1a; 一.yum yum是Linux的一个指令&#xff0c;其实它的作用相当于一个商店&#xff0c;我们可以在商店里面买我们需要的东西。 我们将yum称为包…

40亿个QQ号,限制1G内存,如何去重?

40亿个QQ号&#xff0c;限制1G内存&#xff0c;如何去重&#xff1f; 40亿个unsigned int&#xff0c;如果直接用内存存储的话&#xff0c;需要&#xff1a; 4*4000000000 /1024/1024/1024 14.9G &#xff0c;考虑到其中有一些重复的话&#xff0c;那1G的空间也基本上是不够…

chatgpt赋能Python-python_calchist

Python计算直方图&#xff1a;使用calchist进行图像分析 如果你是一位熟练掌握Python的工程师&#xff0c;同时又对图像分析领域感兴趣&#xff0c;那么你应该一定听说过Python的OpenCV库。OpenCV是一个专业的图像处理库&#xff0c;可以用来处理图像、视频和计算机视觉等相关…

2023 华为 Datacom-HCIE 题库 03--含解析

单选题 1.[试题编号&#xff1a;189810] &#xff08;单选题&#xff09;SSH算法协商阶段中&#xff0c;双方交换自身所支持的算法列表。SSH服务器的对称加密算法列表依次为:aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc。SSH客户端的对称加密算法列表依次为&#xff1a;aes1…

研发工程师玩转Kubernetes——使用Deployment进行版本升级

软件升级是一件非常常见的事&#xff0c;本节我们将尝试使用Deployment进行软件升级。 更新simple_http版本 我们还是借助《研发工程师玩转Kubernetes——构建、推送自定义镜像》中的代码库&#xff0c;只是稍微修改一下Dockerfile——将版本变成2。 From python:3.11 RUN p…

TypeScript - Interfaces(接口)

目录 1、接口介绍 1.1 接口示例 2、可选属性 3、只读属性 4、额外的属性检查 5、函数类型 6、可索引的类型 &#xff17;、类类型 &#xff17;.1 类静态部分和实例部分 &#xff18;、继承接口 &#xff19;、混合类型 1&#xff10;、接口继承类 1、接口介绍 Ty…

探索未来:物联网的无限可能

连接万物&#xff0c;创造未来。从智能家居到智慧医疗&#xff0c;从智能车联到智慧城市&#xff0c;物联网技术的影响已经悄然渗透到了我们的方方面面。欢迎大家积极讨论联网技术如何影响了我们的生活。 物联网技术概述 物联网技术&#xff08;Internet of Things&#xff0…

WebStorm 固定 调试版 Chrome

WebStorm 固定 调试版 Chrome 每次升级 WebStorm 都会打开一个新的 Chrome&#xff0c;导致调试时需要重新登录&#xff0c;重新安装插件等问题。 解决办法&#xff1a; 固定 WebStorm 中 Chrome UserData 的路径&#xff0c;这样每次打开的 Chrome 都是同一个。 文件 | 设…

HJ73 计算日期到天数转换

1.题目&#xff1a; 2.分析&#xff1a; 1. 通过枚举每个月的1号是这一年的第几天&#xff0c;从而进行累加求和即可&#xff0c;其中注意闰年的处理 3.我的代码&#xff1a; #include <iostream> using namespace std;int main() {int arr[13] { 0, 31, 28, 31, 30,…

设计模式基础-面向对象基础

✨作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 这里只是简单的将《大话设计模式【Java溢彩加强版】》的内容简单是复述一下&#xff0c;并加上自己的理解 在学习Java设计模式的时候…

Hadoop集群实现时间同步

一.为什么要对集群实现时间同步 因为我们在集群使用hive&#xff0c;mysql&#xff0c;hdfs之间等使用sqoop传输数据的时候&#xff0c;如果集群之间没有同步时间的话&#xff0c;那么就会报错&#xff0c;无法实现数据的传输。 不仅如此&#xff0c;在集群的使用当中&#xff…

logstash的快速使用

同品&#xff1a; filebeat&#xff1a;只做数据收集&#xff0c;讲数据输出到指定目的地&#xff0c;占用资源小 logstash:收集日志数据&#xff0c;还能过滤&#xff0c;转换数据&#xff0c;组需要更多资源 目录 1.logstash的安装 2.配置文件 3.创建容器 4.引入依赖 …

设计模式期末程序题(只是一个简单整理)

1.下图是某系统的数据部分的类图。因为该层次结构中的操作需要经常变化&#xff0c;所以需要用访问者模式对其进行重构&#xff0c;请按以下要求完成题目&#xff1a; &#xff08;1&#xff09;绘制重构后系统完整类图。&#xff08;4分&#xff09; &#xff08;2&#xff09…

第一章 数学基础

目录 一、线性代数二、微积分三、概率 一、线性代数 理解范数概念区分向量的内积 a ⋅ b \mathbf{a} \cdot \mathbf{b} a⋅b 与外积 a b \mathbf{a} \times \mathbf{b} ab区分矩阵的乘法 A ⊗ B \mathbf{A} \otimes \mathbf{B} A⊗B、内积 A B \mathbf{A} \mathbf{B} AB 、…