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

2024-08-27 21:04

本文主要是介绍dubbo:dubbo服务负载均衡、集群容错、服务降级、服务直连配置详解(五),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 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";@Overridepublic <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);}@Overrideprotected 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";@Overrideprotected <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 {@Overridepublic String getUserById(Integer id) {return "服务繁忙,请耐心等候";}@Overridepublic 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-serverprotocol: # 指定通信规则name: dubbo # 通信协议port: 20892 # dubbo协议端口,以供消费者访问,-1即为随机端口registry: # 注册中心id: zk-registryaddress: 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/

这篇关于dubbo:dubbo服务负载均衡、集群容错、服务降级、服务直连配置详解(五)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112775

相关文章

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

详解Java中的敏感信息处理

《详解Java中的敏感信息处理》平时开发中常常会遇到像用户的手机号、姓名、身份证等敏感信息需要处理,这篇文章主要为大家整理了一些常用的方法,希望对大家有所帮助... 目录前后端传输AES 对称加密RSA 非对称加密混合加密数据库加密MD5 + Salt/SHA + SaltAES 加密平时开发中遇到像用户的

如何在一台服务器上使用docker运行kafka集群

《如何在一台服务器上使用docker运行kafka集群》文章详细介绍了如何在一台服务器上使用Docker运行Kafka集群,包括拉取镜像、创建网络、启动Kafka容器、检查运行状态、编写启动和关闭脚本... 目录1.拉取镜像2.创建集群之间通信的网络3.将zookeeper加入到网络中4.启动kafka集群

Springboot使用RabbitMQ实现关闭超时订单(示例详解)

《Springboot使用RabbitMQ实现关闭超时订单(示例详解)》介绍了如何在SpringBoot项目中使用RabbitMQ实现订单的延时处理和超时关闭,通过配置RabbitMQ的交换机、队列和... 目录1.maven中引入rabbitmq的依赖:2.application.yml中进行rabbit

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.