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

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

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
    通过控制后台日志输出, 可以看到每个服务节点呈现不规则的调用。

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 优先。

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
4月前
|
缓存 Dubbo Java
趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
|
4月前
|
Dubbo Java 应用服务中间件
从源码全面解析 dubbo 服务端服务调用的来龙去脉
从源码全面解析 dubbo 服务端服务调用的来龙去脉
|
3月前
|
缓存 Dubbo Java
Dubbo 第三节_ Dubbo的可扩展机制SPI源码解析
Dubbo会对DubboProtocol对象进⾏依赖注⼊(也就是⾃动给属性赋值,属性的类型为⼀个接⼝,记为A接⼝),这个时候,对于Dubbo来说它并不知道该给这个属性赋什么值,换句话说,Dubbo并不知道在进⾏依赖注⼊时该找⼀个什么的的扩展点对象给这个属性,这时就会预先赋值⼀个A接⼝的⾃适应扩展点实例,也就是A接⼝的⼀个代理对象。在调⽤getExtension去获取⼀个扩展点实例后,会对实例进⾏缓存,下次再获取同样名字的扩展点实例时就会从缓存中拿了。Protocol是⼀个接。但是,不是只要在⽅法上加了。
|
2月前
|
XML 负载均衡 Dubbo
了解Dubbo配置:优先级、重试和容错机制的秘密【五】
了解Dubbo配置:优先级、重试和容错机制的秘密【五】
37 0
|
2月前
|
Docker 容器
在docker中安装dubbo-admin,并且阿里云服务器配置
在docker中安装dubbo-admin,并且阿里云服务器配置
135 1
|
3月前
|
Dubbo Java 应用服务中间件
微服务框架(十七)Dubbo协议及编码过程源码解析
  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。   本文为Dubbo协议、线程模型、和其基于Netty的NIO异步通讯机制及源码
|
4月前
|
缓存 负载均衡 Dubbo
从源码全面解析 dubbo 消费端服务调用的来龙去脉
从源码全面解析 dubbo 消费端服务调用的来龙去脉
|
4月前
|
存储 Dubbo Java
从源码全面解析 dubbo 服务订阅的来龙去脉
从源码全面解析 dubbo 服务订阅的来龙去脉
|
4月前
|
Dubbo 数据可视化 Java
从源码全面解析 dubbo 服务暴露的来龙去脉
从源码全面解析 dubbo 服务暴露的来龙去脉
|
4月前
|
Dubbo Java 应用服务中间件
从源码全面解析 dubbo 注解配置的来龙去脉
从源码全面解析 dubbo 注解配置的来龙去脉