dubbo之高可用

news2024/11/17 11:38:45

负载均衡

概述

负载均衡是指在集群中,将多个数据请求分散到不同的单元上执行,主要是为了提高系统的容错能力和对数据的处理能力。

Dubbo 负载均衡机制是决定一次服务调用使用哪个提供者的服务

策略

在Dubbo中提供了7中负载均衡策略,默认的负载均衡策略是Random(默认权重相同)

Weighted Random

加权随机,按权重设置随机概率。

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

RoundRobin

加权轮询,按公约后的权重设置轮询比率,循环调用节点。

存在慢的提供者累积请求的问题。

LeastActive

加权最少活跃调用优先,活跃数越低,越优先调用,相同活跃数的进行加权随机。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大;相对的,处理能力越强的节点,处理更多的请求。

ShortestResponse

加权最短响应优先,在最近一个滑动窗口中,响应时间越短,越优先调用。相同响应时间的进行加权随机。

使得响应时间越快的提供者,处理更多的请求

ConsistentHash

一致性 Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动

P2C Load Balance

1.对于每次调用,从可用的provider列表中做两次随机选择,选出两个节点providerA和providerB。

2.比较providerA和providerB两个节点,选择其“当前正在处理的连接数”较小的那个节点。

Adaptive Load Balance

自适应负载均衡,是一种能根据后端实例负载自动调整流量分布的算法实现,它总是尝试将请求转发到负载最小的节点

配置

只需要调整 loadbalance 相应取值即可

服务端服务级别

<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.部分服务暂停

2.全部服务暂停

3.随机拒绝服务

4.部分服务延迟

实现方式

内置Mock

1.return

接口级别降级:接口的所有方法调用降级,全部返回null

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one" mock="return null"/>

方法级别降级:如果只是想对部分接口降级

<!-- 对getOrderInfo方法进行降级,其它方法正常调用 -->
<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one">
    <dubbo:method name="getOrderInfo" mock="return null"/>
    <!-- 也可以使用dubbo:parameter标签进行配置 -->
    <dubbo:parameter key="getOrderInfo.mock" value="return null"/>
</dubbo:reference>

Mock是在调用发生RpcException异常之后才起作用的,如果不是Mock异常,将不会用到Mock。对于方法级别的降级,仍然需要服务注册到注册中心,否则调用时会发生服务提供者不存在的异常,此时Mock实际还未介入,最终可能导致调用或程序中断

2.empty

使用throw来返回一个Exception对象,作为远程方法调用的返回值

当调用出错时,抛出一个默认的RPCException

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one" mock="throw"/>

也可以抛出一个自定义的异常

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one"   mock="throw com.harvey.samples.core.OrderException"/>

3.force和fail

只有当远程调用发生错误时才使用Mock行为。force: 代表强制使用Mock行为,在这种情况下不会走远程调用。force: 和 fail: 都支持与throw或者return组合使用

强制接口所有方法返回指定值

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one"    mock="force:return stringresult"/>

强制抛出自定义的异常

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one"
                     mock="force:throw com.harvey.samples.core.OrderException"/>

自定义Mock类

在消费服务端本地创建一个实现了服务接口的Mock类,当远程服务不可用时或临时需要停用时,Dubbo框架将会调用mock属性指定的Mock类对应的方法并返回预设值给到用户。

1.设置为自定义的Mock类完整名(或将mock属性设置为true)

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one"
                     mock="com.harvey.samples.core.OrderServiceMock"/>

或:

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService" protocol="dubbo" group="one"
                     mock="true"/>

如果属性mock设置为true的方式,则需要将Mock实现类放在和接口相同的包下

2.定义Mock类,实现需要降级的方法,返回预设的值

Mock类的命名规则遵循为服务接口名+Mock后缀,实现服务接口,并有一个无参构造函数。

public class OrderServiceMock implements OrderService {

    //必须有一个无参构造函数
    public OrderServiceMock(){

    }

    @Override
    public Order getOrderInfo(long orderId) throws InterruptedException {
        Order order = new Order();
        order.setOrderId(-1L);
        order.setOrderName("调用失败");
        return order;
    }

    @Override
    public List<Order> listAll() {
        // 返回一个空的列表
        return new ArrayList<>();
    }
}

注意:       

        Dubbo的服务降级采用的是mock机制,可以直接使用其内置的mock实现,也可以自定义本地的Mock类来实现。Dubbo的服务降级的介入节点主要在服务消费者端,对应配置属性为mock,支持接口级别和方法级别两种粒度的服务降级配置

服务熔断

缺陷分析

由于 dubbo 不带熔断机制,所以尽管每次因为 RPC 异常而导致调用失败,也不会进行熔断处理;即不管调用失败多少次,消费者还是会继续进行调用。其实这样会导致服务的资源浪费:

        1.只要服务提供者出现异常达到一定的次数,其实可以理解为服务提供者短时间内已经不能正常提供服务了,后续再调用也是浪费资源

        2.如果是上述的超时问题,消费者还会进行 1+retires 次的 RPC 调用,这样就更加浪费资源了

熔断机制

        当调用失败达到指定的次数,则将熔断器打开一段时间,即将请求链路断开;在指定时间内,都不再让消费者向提供者发送请求;当熔断时间到了,就将熔断器设置为半打开的状态,此时消费者可以往提供者发送请求,并统计成功次数,如果达到指定的成功次数,熔断器则变为关闭状态,即将请求链路打开,否则熔断器又变回打开状态。

        不管是业务错误还是请求超时,只要时间内达到了一定的次数就做上述的熔断处理,这样就可以防止没有必要的调用,防止浪费资源。

dubbo结合hystrix实现服务的熔断降级

1.添加依赖

<dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>         version>2.0.1.RELEASE</version>

</dependency>

2.启动类添加注解

@EnableHystrix

3.在 Service 中增加注解

@HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    })
    @Override
    public String sayHi() {
        throw new RuntimeException("Exception to show hystrix enabled.");
    }
@HystrixCommand(fallbackMethod = "hiError")
    @RequestMapping(value = "hi")
    public String sayHi() {
        return userService.sayHi();
    }

    public String hiError() {
        return "Hystrix fallback";
    }

服务隔离

服务隔离指的是将不同的服务放在不同的进程或者容器中运行,防止某个服务出现故障影响到其他服务的正常运行。Dubbo支持将不同的服务放在不同的进程或者容器中运行,实现服务的隔离

重试机制

Dubbo 服务在尝试调用一次之后,如出现非业务异常(服务突然不可用、超时等),Dubbo 默认会进行额外的最多2次重试。Dubbo可以配置重试次数、重试间隔时间等参数,实现重试机制。

Dubbo默认提供了重试机制,可以通过在配置文件中设置retries参数来启用。如果服务调用失败,则Dubbo会自动重新尝试调用服务,直到达到最大重试次数或服务调用成功。重试过程中,Dubbo会等待一定的时间间隔,以避免对服务的过度压力

重试次数配置

1.通过注解/xml进行固定配置

<dubbo:consumer retries="2"></dubbo:consumer>

2.通过RpcContext进行运行时动态配置

// dubbo服务调用前,通过RpcContext动态设置本次调用的重试次数
RpcContext rpcContext = RpcContext.getContext();
rpcContext.setAttachment("retries", 5);

代码示例

provider

1.xml

<!--为服务的所有方法设置超时时间-->
<dubbo:service interface="com.harvey.samples.client.OrderService" ref="orderServiceImpl"
                   protocol="dubbo" group="one" timeout="5000"/>

<!--具体为某个方法设置超时时间-->
<dubbo:service interface="com.harvey.samples.client.OrderService" ref="orderServiceImpl"
               protocol="dubbo" group="one">
    <dubbo:method name="getOrderInfo" timeout="5000"/>
</dubbo:service>

2.方法

private AtomicLong atomicLong = new AtomicLong();
@Override
public Order getOrderInfo(long orderId) throws InterruptedException {
    System.out.println("调用第" + atomicLong.incrementAndGet() + "次");
    RpcContext rpcContext = RpcContext.getContext();
    System.out.println("当前调用的服务端口:" + rpcContext.getLocalPort() + ", 获取订单:" + orderId);
    //休眠,主要是让服务提供者的超时时间生效,超时触发了消费者的重试机制
    TimeUnit.SECONDS.sleep(6);
    return orderMap.get(orderId);
}

consumer

1.xml

<dubbo:reference id="orderService" interface="com.harvey.samples.client.OrderService"
                 protocol="dubbo" group="one" retries="2"/>

2.方法

public class ConsumerStarter {

    public static void main(String[] args) throws IOException, InterruptedException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/dubbo-consumer.xml"});
        context.start();
        System.out.println("consumer start.....");
        //dubbo
        OrderService orderService1 = context.getBean("orderService", OrderService.class);
        System.out.println("接口:getOrderInfo");
        System.out.println("SUCCESS: got getOrderInfo " + orderService1.getOrderInfo(10L));
    }
}

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

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

相关文章

1.0 Python 标准输入与输出

python 是一种高级、面向对象、通用的编程语言&#xff0c;由Guido van Rossum发明&#xff0c;于1991年首次发布。python 的设计哲学强调代码的可读性和简洁性&#xff0c;同时也非常适合于大型项目的开发。python 语言被广泛用于Web开发、科学计算、人工智能、自动化测试、游…

C#实现三菱FX-3U SerialOverTcp

设备信息 测试结果 D值测试 Y值写入后读取测试 协议解析 三菱FX 3U系列PLC的通信协议 1. 每次给PLC发送指令后&#xff0c;必须等待PLC的应答完成才能发送下一条指令; 2. 报文都是十六进制ASCII码的形式 3. 相关指令 指令 命令码&#xff08;ASCII码&#xff09; 操作原件 …

七牛云获取qn(url、bucket、access-key、secret-key)

1.注册账号 2.access-key和secret-key&#xff1a; 点击“密钥管理” 复制AK和SK即可 域名&#xff1a; bucket&#xff1a; 这个就是对象存储空间名字 先新建一个空间&#xff08;没买需要先购买&#xff09;&#xff0c;步骤如下&#xff1a; 填写存储空间名字&#xff0…

“OSError: [WinError 1455]页面文件太小,无法完成操作。”解决方案

按照下面步骤, 会发现电脑默认情况下是没有给D盘分配虚拟内存的, 所以将Python装在D盘的朋友, 在跑程序时, 没有分配虚拟内存, 自然就遇到了上面的问题, 所以根本操作只要给D盘分配虚拟内存即可 第一步&#xff1a;鼠标右击我的电脑 (此电脑)&#xff0c;点击属性进入以下界面 …

PostMessage/SendMessage在不同线程的调用探究

PostMessage和SendMessage是我们比较常用的windows API&#xff0c;最近也探究这两个api在调用之后&#xff0c;执行的线程问题&#xff0c;发现如下结论&#xff1a; 仅仅是RegisterClass注册类之后&#xff0c;调用createwindow第一个参数通过&#xff1a;(const TCHAR*)base…

three.js 地球与卫星绕地飞行【真实三维数据】

&#xff08;真实经纬度运行轨迹&#xff09; 完整代码 <template><div class"home3dMap" id"home3dMap" v-loading"loading"></div> </template><script> import * as THREE from three import { OrbitControl…

【K8S 的二进制搭建】

目录 一、二进制搭建 Kubernetes v1.201、准备环境 二、操作系统初始化配置三、部署 etcd 集群1、准备签发证书环境2、在 master01 节点上操作1、生成Etcd证书 3、在 node01 节点上操作4、在 node02 节点上操作 四、部署 Master 组件五、部署 docker引擎六、部署 Worker Node 组…

【算法|数组】手撕经典二分法

算法|数组——二分查找 文章目录 算法|数组——二分查找引言二分查找左闭右闭写法左闭右开写法 总结 引言 首先学习这个算法之前需要了解数组知识&#xff1a;数组。 大概介绍以下&#xff1a; 数组是存储在连续内存空间上的相同类型数据的集合。数组下标都是从0开始。数组在…

【SpringCloud】Gateway服务网关

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 1.为什么需要网关…

“实现数字化转型:探索会议OA项目的高级技术与创新应用“

文章目录 引言&#xff1a;1.项目背景和需求分析&#xff1a;2.技术选型和架构设计&#xff1a;3.项目实现和功能亮点&#xff1a;3.0 layui实现登录及注册3.1 会议管理模块3.1.1 会议发布3.1.2 我的会议3.1.3 我的审批3.1.4 会议通知3.1.5 待开会议3.1.6 历史会议3.1.7 所有会…

【Leetcode】层次遍历||树深度||队列

step by step. 题目&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&am…

【LeetCode】数据结构题解(13)[设计循环链表]

设计循环链表 &#x1f609; 1.题目来源&#x1f440;2.题目描述&#x1f914;3.解题思路&#x1f973;4.代码展示 所属专栏&#xff1a;玩转数据结构题型❤️ &#x1f680; >博主首页&#xff1a;初阳785❤️ &#x1f680; >代码托管&#xff1a;chuyang785❤️ &…

WordPress使用【前端投稿】功能时为用户怎么添加插入文章标签

在使用Wordpress做前端投稿功能的时候&#xff0c;可能需要用户填写文章标签&#xff0c;在插入文章的时候很多人不知道怎么把这些标签插入进去&#xff0c;下面这篇文章来为大家带来WordPress使用前端投稿功能时插入文章标签方法。 在Wordpress里 wp_insert_post 此函数的作…

Vue3核心笔记

文章目录 1.Vue3简介2.Vue3带来了什么1.性能的提升2.源码的升级3.拥抱TypeScript4.新的特性 一、创建Vue3.0工程1.使用 vue-cli 创建2.使用 vite 创建 二、常用 Composition API1.拉开序幕的setup2.ref函数3.reactive函数4.Vue3.0中的响应式原理vue2.x的响应式Vue3.0的响应式 5…

冠达管理:夜盘是什么意思?

跟着现代社会的快节奏开展&#xff0c;股票商场的运营也因而发生了相应的改变。夜盘是指在正常的买卖时刻外特别敞开的买卖商场&#xff0c;为出资者供给更多的买卖时刻和机会。夜盘的概念在我国自2002年引入以来逐渐被越来越多的出资者所熟知。那么夜盘究竟是什么&#xff1f;…

Collection 中的简单命令

一、list 集合常用的方法 LIst&#xff1a;元素存取有序、可以保存重复元素、有下标。可以存储 null 值。 ArrayList&#xff1a;底层数组结构&#xff0c;有 index&#xff0c;查询快 LinkList&#xff1a; 底层链表结构&#xff0c;增删快 添加 //确保此集合包含指定的元素…

操作系统—进程管理

这里写目录标题 进程特点并行和并发进程的状态进程的控制结构PCB包含什么信息 进程上下文切换进程上下文切换发生的场景 进程的通信方式 线程什么是线程线程的优缺点进程线程的区别线程的上下文切换线程的实现用户线程和内核线程的对应关系 用户线程如何理解、优缺点内核线程如…

在Echarts中的tooltip上添加点击按钮

需求&#xff1a; 在Echarts的tooltips中添加点击按钮并可以鼠标悬停点击该按钮 功能实现&#xff1a; 在option中的tooltip添加enterable: true的属性&#xff0c;表示鼠标可以移入tooltip中再在formatter中添加 <button onclick"onTooltipsFun()" stylecursor:…

protobuf 2定义string常量

背景 protobuf 2中定义的enum枚举值必须为数字类型&#xff0c;故不支持string类型&#xff0c;但有些业务场景又确实需要定义string常量。 目标 在protobuf 2中定义string常量。 方案 思路&#xff1a;通optional default实现string常量。 细节&#xff1a; 1、protobu…

直击HDC展区现场,华为天气开启天气+生活新方式

备受瞩目的HDC 2023 大会正式举办&#xff0c;华为天气携气象领域最新成果展现在大会现场&#xff0c;经过在线下展区实际体验过后&#xff0c;我被天气服务卡强势“种草”了。 天气与人们生活息息相关&#xff0c;面对日益复杂的天气场景&#xff0c;简单的“打开APP看天气”…