dubbo:dubbo服务负载均衡、集群容错、服务降级、服务直连配置详解(五)

news2024/9/19 13:03:44

文章目录

  • 0. 引言
  • 1. dubbo负载均衡
    • 1.1 负载均衡算法
    • 1.2. dubbo负载均衡使用
    • 1.3 自定义负载均衡策略
  • 2. dubbo服务容错
    • 2.1 8种服务容错策略
    • 2.2 自定义容错策略
  • 3. dubbo服务降级(mock)
  • 4. dubbo服务直连
  • 5. 总结

0. 引言

之前我们讲解了dubbo的基本使用,但在dubbo服务调用过程中,为了保证高可用dubbo提供者一般不是一个节点,当多个节点部署时,节点间的负载均衡问题随之而来,今天我们针对dubbo提供者服务的各类相关配置进行讲解

1. dubbo负载均衡

1.1 负载均衡算法

官方文档:https://cn.dubbo.apache.org/zh-cn/docsv2.7/dev/source/loadbalance/

在dubbo的源码中我们可以看到,dubbo支持5种负载均衡算法:
在这里插入图片描述

  • ConsistentHashLoadBalance:Hash一致性算法

将请求的参数如方法名、参数类型和参数值等作为键值对进行哈希计算,然后将固定范围内的hash值转发到对应的节点

  • RandomLoadBalance:权重随机算法,默认算法

为每一台服务器设置一个权值,当有请求到来时,按照大体的权重比例为该请求分配服务器,比如默认的1:1, 就会大体上按照1:1的比例进行随机转发

  • LeastActiveLoadBalance:最少活跃调用数算法

为每个服务提供者记录一个Active数,表示当前活跃的调用数。当有请求到来时,将该请求分配给当前活跃数最少的服务提供者,当活跃数相同时,就会按照权重大小分配转发

  • RoundRobinLoadBalance:轮询算法

按照顺序依次将请求分配给每一台服务器

  • ShortestResponseLoadBalance:最短响应时间算法

从多个提供者节点中选出成功调用且响应时间最短的节点进行转发,如果节点有多个,则再按照随机算法进行分配

1.2. dubbo负载均衡使用

在消费者端,引入提供者服务时,通过loadbalance参数指定,如下指定了Hash一致性算法

   @DubboReference(loadbalance = ConsistentHashLoadBalance.NAME)
   private UserService userService;

调用发现因为参数没变化,就会一直转发到同一个提供者节点上
在这里插入图片描述

1.3 自定义负载均衡策略

官方介绍:https://cn.dubbo.apache.org/zh-cn/docsv2.7/dev/impls/load-balance/

1、创建负载均衡实现类,声明LoadBalance接口,实现select方法,该方法即为具体的负载均衡实现算法,如下书写了一个简单的策略,固定取第一个实例

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.LoadBalance;

import java.util.List;

public class WuLoadBalance implements LoadBalance {

    public final static String NAME = "wu";

    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
        System.out.println("执行负载均衡");
        return invokers.get(0);
    }
}

2、在resources目录下创建META-INF/dubbo文件夹,再创建org.apache.dubbo.rpc.cluster.LoadBalance文件,文件内容如下,这里的名称即为给WuLoadBalance定义的别名,然后通过等号指定我们刚刚创建的实现类

wu=wu.example.orderserver.lb.WuLoadBalance

3、使用时指定该别名即可

 @DubboReference(loadbalance = WuLoadBalance.NAME)
 private UserService userService;

如果本地运行没有执行到,这是因为打包的resouces目录没有更新,将target目录删除后重新运行即可

2. dubbo服务容错

2.1 8种服务容错策略

所谓服务容错,就是当服务调用失败后的处理策略。dubbo支持8种服务容错策略,也叫集群容错策略:
在这里插入图片描述

  • AvailableCluster 可用实例策略

调用目前可用的实例,但只调用其中一个,如果当前没有可用的实例,则抛出异常

@DubboReference(cluster = AvailableCluster.NAME)
private UserService userService;
  • BroadcastCluster 广播策略

广播调用所有实例,逐个调用,任意一台报错则报错,与ForkingCluster策略形成对比

@DubboReference(cluster = BroadcastCluster.NAME)
private UserService userService;
  • FailbackCluster 失败重试策略

调用实例发生异常后,一段时间后重新再调用,直到调用成功,retries用于控制重试次数,timeout为调用超时时间

@DubboReference(cluster = FailbackCluster.NAME, retries = 3, timeout = 10000)
private UserService userService;
  • FailfastCluster 快速失败策略

只发起一次调用,失败立即报错,一般用于非幂等性操作场景,也就是操作不允许重复的,比如用户付款

  • FailoverCluster 自动切换策略,默认策略

当出现失败,重试其它服务

  • FailsafeCluster 安全失败策略

出现异常时,直接忽略,与FailfastCluster的区别就是:FailsafeCluster并不抛出异常,而FailfastCluster会抛出异常

  • ForkingCluster 并行策略

并行调用多个实例,有一个成功则返回。通常用于实时性要求较高的读操作,缺点是会浪费更多的资源

  • MergeableCluster 分组策略

某些场景下同一个接口,但是我们会有不同的实现,我们就可以针对这些不同的实现做不同的分组,然后调用时声明分组来调用不同的实现,一般和group参数一起使用,该策略和tag属性都可以用来调用不同的实现,可以针对灰度发布、分组实现、新老版本替换的场景
比如:

// 调用分组为xxx或者yyy的其中一个接口
 @Reference(cluster = MergeableCluster.NAME, group = "xxx,yyy")
 private IUserService userService;

// 同时在提供者中也声明group
@DubboService(group = "xxx")
public class UserServiceImpl implements UserService {
  ...
}

2.2 自定义容错策略

1、自定义ClusterInvoker
创建继承 AbstractClusterInvoker 的子类,并重写 doInvoke 方法


import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;

import java.util.List;

/**
 * @author benjamin_5
 * @Description
 * @date 2024/8/23
 */
public class MyClusterInvoker<T> extends AbstractClusterInvoker<T> {

    public MyClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        // 使用loadbalance对象选择具体的实例
        Invoker<T> invoker = select(loadbalance, invocation, invokers, null);
        try {
            // 执行rpc调用
            return invokeWithContext(invoker, invocation);
        } catch (Throwable e) {
            if (e instanceof RpcException && ((RpcException) e).isBiz()) {
                throw (RpcException) e;
            }

            throw new RpcException(e.getMessage(), e);
        }
    }
}

2、自定义Cluster类
创建继承 AbstractCluster 的子类,并重写 doJoin 方法。举例如下。

import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;

/**
 * @author benjamin_5
 * @Description
 * @date 2024/8/23
 */
public class MyDubboCluster extends AbstractCluster {

	public static final String NAME = "my";

    @Override
    protected <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
        // 创建具体的集群策略
        return new MyClusterInvoker<>(directory);
    }
}

3、在resources资源目录下,创建META-INF文件夹,再创建dubbo文件夹,创建org.apache.dubbo.rpc.cluster.Cluster文件,然后内容声明自定义策略的名称

比如我这里自定义MyDubboCluster策略的名称为“my”,则再说明其对应的策略类包名即可,这样目的是为了让服务能够找到自定义的策略类

my=wu.example.orderserver.invoker.MyDubboCluster

4、在服务引用中声明策略

 @DubboReference(cluster = MyDubboCluster.NAME)
 private UserService userService;

5、为了测试验证,我们还可以在MyClusterInvoker加一句打印测试语句,然后启动项目,调用接口查看转发效果

如下执行结果表示自定义的策略调用成功
在这里插入图片描述

3. dubbo服务降级(mock)

所谓服务降级就是在所调用服务因各类异常而调用不通或者报错时而进行的一个兜底措施。比如当并发高导致下游服务处理不及时,这是降级返回一个“服务繁忙,请稍后重试”之类的兜底措施,或者访问远程中央数据库不通时,兜底访问本地库,从而保证基本服务正常运行,或者

1、创建降级服务类(Mock类),声明要降级的接口类UserService

public class UserServiceMock implements UserService {

    @Override
    public String getUserById(Integer id) {
        return "服务繁忙,请耐心等候";
    }

    @Override
    public String getInfo() {
        return "服务繁忙,请耐心等候";
    }
}

2、使用时通过mock参数来指定降级类

@DubboReference(mock = "wu.example.orderserver.service.UserServiceMock")
private UserService userService;

3、我们将userService的实例停掉,模拟访问不通,然后访问调用接口,发现返回的是降级信息,则说明降级成功。
在这里插入图片描述

4. dubbo服务直连

某些场景下,我们业务不适合或者不能使用注册中心,这时就只能通过直连的方式来进行访问,而dubbo中设置服务直连也很简单,通过url参数即可

1、因为dubbo服务直连需要通过dubbo端口来进行通信,所以我们先指定服务提供者的dubbo端口

dubbo:
  application:
    name: user-server
  protocol: # 指定通信规则
    name: dubbo # 通信协议
    port: 20892 # dubbo协议端口,以供消费者访问,-1即为随机端口
  registry: # 注册中心
    id: zk-registry
    address: zookeeper://127.0.0.1:2181

2、在服务使用者里通过url声明地址

@DubboReference(url = "dubbo://localhost:20892")
private UserService userService;

如果有多个提供者的,用分号隔开

@DubboReference(url = "dubbo://localhost:20891;dubbo://localhost:20892")
private UserService userService;

3、如果需要配置负载均衡策略的使用loadbalance参数声明即可,用法与注册中心注册的服务负载均衡一致。

5. 总结

至此,我们针对dubbo各类常用配置的讲解即完成了,更多详细的配置大家可以参考官方文档,如有需要自定义配置的,可灵活利用dubbo的SPI机制(服务自定义拓展),dubbo中支持各类模块的自定义,具体也可参考官方文档说明:https://cn.dubbo.apache.org/zh-cn/docsv2.7/dev/impls/

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

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

相关文章

内部类java

内部类就是定义在一个类里面的类&#xff0c;里面的类可以理解成&#xff08;寄生&#xff09;&#xff0c;外部类可以理解成&#xff08;寄主&#xff09;。 //外部类 public class people{//内部类public class heart{} } 内部类的使用场景、作用 1.当一个事物的内部&…

STM32学习笔记3---ADC,DMA

目录 ADC模拟数字转换器 规则组的四种转换模式 AD单通道 AD多通道 常用代码函数相关 DMA直接存储器 存取&#xff08;访问&#xff09; 两个应用 DMA存储器到存储器的转运 ADCDMA ADC模拟数字转换器 stm32数字电路&#xff0c;只有高低电平&#xff0c;无几V电压的概念…

MySQL:常用函数

MySQL&#xff1a;常用函数 日期时间函数字符串函数数学函数加密函数 在MySQL中&#xff0c;存在许多现成的函数&#xff0c;可以简化部分操作&#xff0c;本博客讲解MySQL中的常用函数。 日期时间函数 current_date current_date函数用于输出当前的日期&#xff1a; curren…

一道关于php文件包含的CTF题

一、源码 这是index.php的页面。 点击login后会发现url里多了action的参数&#xff0c;那么我们就可以通过它来获取源码。 ?actionphp://filter/readconvert.base64-encode/resourcelogin.php 再通过base64的解码可以查看源码。 index.php源码&#xff1a; <?php erro…

【编码解码】CyberChef v10.18.9

下载地址 【编码解码神器】CyberChef v10.18.9 在线地址 CyberChef (gchq.github.io) 简介 CyberChef 是一个简单易用的网页应用&#xff0c;&#xff0c;包含了四百多种在线编解码工具。它在浏览器中执行各种“网络安全”操作。这些操作包括简单的 XOR 和 Base64 编码、复…

基于单片机的无线空气质量检测系统设计

本设计以STC89C52单片机为核心&#xff0c;其中包含了温湿度检测模块、光照检测模块、PM2.5检测模块、报警电路、LCD显示屏显示电路、按键输入模块和无线传输模块来完成工作。首先&#xff0c;系统可以通过按键输入模块设置当前的时间和报警值&#xff1b;使用检测模块检测当前…

spring boot(学习笔记第十九课)

spring boot(学习笔记第十九课) Spring boot的batch框架&#xff0c;以及Swagger3(OpenAPI)整合 学习内容&#xff1a; Spring boot的batch框架Spring boot的Swagger3&#xff08;OpenAPI&#xff09;整合 1. Spring boot batch框架 Spring Batch是什么 Spring Batch 是一个…

个人网站免费上线

声明一下&#xff0c;小科用的是natapp&#xff0c;进行的 1.起步-下载安装 去浏览器搜索" natapp "&#xff0c;在官网下载&#xff0c;或者直接 点击下列网站 NATAPP-内网穿透 基于ngrok的国内高速内网映射工具https://natapp.cn/ 打开后下滑找到下载&#xff…

JMeter Plugins之内网插件问题解决

JMeter Plugins之内网插件问题解决 背景 在我司内部进行JMeter工具进行性能脚本开发时&#xff0c;为了提高测试效率&#xff0c;我们会用到部分JMeter提供的插件&#xff0c;但是在我司内网的情况下&#xff0c;我们如果直接点击JMeter界面右上角的插件按钮 弹出来的JMeter…

洛谷刷题(4)

P1089 [NOIP2004 提高组] 津津的储蓄计划 题目描述 津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300 元钱&#xff0c;津津会预算这个月的花销&#xff0c;并且总能做到实际花销和预算的相同。 为了让津津学习如何储蓄&#xff0c;妈妈提出&#xff0c;津津可以随…

零基础5分钟上手亚马逊云科技 - AI模型内容安全过滤

在上一篇文章中&#xff0c;小李哥带大家深入调研亚马逊云科技AI模型平台Amazon Bedrock热门开发功能&#xff0c;了解了模型平台的文字/图片生成、模型表现评估和模型内容安全审核的实践操作。这次我们将继续介绍如何利用API的形式&#xff0c;利用Python代码的形式对AI模型内…

OpenSearch的快照还原

本次测试选择把索引快照备份到Amazon S3&#xff0c;所以需要使用S3 repository plugin&#xff0c;这个插件添加了对使用 Amazon S3 作为快照/恢复存储库的支持。 OpenSearch集群自带了这个插件&#xff0c;所以无需额外安装。 由于需要和Amazon Web Services打交道&#xf…

工厂数字化转型中工业一体机起到什么作用?

近年来工厂数字化转型成为企业提升竞争力的关键路径。而在这场转型浪潮中&#xff0c;工业一体机扮演着至关重要的角色&#xff0c;它不仅是推动工厂数字化转型的关键工具&#xff0c;更是赋能企业实现更高效、智能、灵活生产的关键要素。 一、工业一体机&#xff1a;连接物理与…

CAN通信之波特率相关配置

由于 CAN 属于异步通讯&#xff0c;没有时钟信号线&#xff0c;连接在同一个总线网络中的各个节点会像串口异步通讯那样&#xff0c;节点间使用约定好的波特率进行通讯。 首先我们要明确几个概念&#xff1a; 波特率&#xff1a;can 1s传输的位数&#xff0c;其单位为bps。 T…

Vue3学习笔记之插槽

目录 前言 一、基础 (一) 默认插槽 (二) 具名插槽 (三) 作用域插槽 (四) 动态插槽 二、实战案例 前言 插槽&#xff08;Slots&#xff09;&#xff1f; 插槽可以实现父组件自定义内容传递给子组件展示&#xff0c;相当于一块画板&#xff0c;画板就是我们的子组件&…

速速报名|数据治理与数据建模workshop报名开启

由Datamodeling社区出品的「数据治理与数据建模workshop 」将在9月份正式启动上海站和深圳站。 本课程由社区特邀讲师王琤老师、黄峰老师授课&#xff0c;两位老师基于丰富的数据管理经验提炼出知识体系&#xff0c;以面对面带练的方式&#xff0c;帮助学习者快速掌握数据建模…

dp+差分数组

前言&#xff1a;怎么也没想到要用dp来做&#xff0c;并且这个题目中如果列为1的话还要特殊考虑 题目地址 #include<bits/stdc.h> using namespace std;//#define int long long const int N (int)5e3 10; int dp[N][N][2]; // 0 表示上端点&#xff0c;1表示下端点 in…

正确枚举 Winlogon 桌面窗口层次

目录 前言 原理解释 原理实现 Winlogon 桌面窗口层次 本文出处链接&#xff1a;https://blog.csdn.net/qq_59075481/article/details/141608316。 前言 众所周知&#xff0c;从 Windows 7 开始&#xff0c;Winlogon 桌面不再使用 SASWindow 作为背景窗口&#xff0c;而是采…

翻斗雨量监测站

翻斗雨量监测站通常用于测量和记录降雨量&#xff0c;其主要功能包括&#xff1a; 测量降雨量&#xff1a;翻斗雨量监测站使用翻斗式测量原理&#xff0c;通过记录翻斗倒转的次数或翻斗中积累的水量来测量降雨量。可以准确地记录降雨量的变化。 记录降雨时间&#xff1a;翻斗雨…

PowerDesigner生成数据字典文档

PowerDesigner生成数据字典文档 目录 1. 设置报告 2. 导出报告 3. 查看报告 设置报告 删除多余的选项&#xff0c;只保留【LIst of Table Columns -表%PARENT%的栏的清单】选项。 只显示Name、Code、Data Type、Length、Is Key等列 导出报告 查看报告