dubbo之高可用

负载均衡

概述

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

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));
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

冒泡排序 简单选择排序 插入排序 快速排序

bubblesort 两个for循环&#xff0c;从最右端开始一个一个逐渐有序 #include <stdio.h> #include <string.h> #include <stdlib.h>void bubble(int *arr, int len); int main(int argc, char *argv[]) {int arr[] {1, 2, 3, 4, 5, 6, 7};int len sizeof(…

想要延长Macbook寿命?这六个保养技巧你必须get!

Mac作为我们工作生活的伙伴&#xff0c;重要性不需要多说。但在使用的过程中&#xff0c;我们总会因不当操作导致Mac出现各种问题。 要想它长久的陪伴&#xff0c;平时的维护与保养自然不能少&#xff0c;Mac的保养很重要的两点就是硬件保养和电脑系统保养&#xff0c;硬件保养…

【一】初步认识数据库

数据库概览数据库 缘起表(Table)的理解用表来定义数据库数据库系统的理解概念层次的理解实例层次的理解 数据库管理系统的理解从用户角度看从系统实现角度看典型的数据库管理系统 数据库语言数据库定义、操纵、控制语言数据库语言 VS 高级语言 内容回顾练习 数据库概览 走马观…

gitblit-使用

1.登入GitBlit服务器 默认用户和密码: admin/admin 2.创建一个新的版本库 点击图中的“版本库”&#xff0c;然后点击图中“创建版本库” 填写名称和描述&#xff0c;注意名称最后一定要加 .git选择限制查看、克隆和推送勾选“加入README”和“加入.gitignore文件”在图中的1处…

2023一带一路东盟工商领袖峰会在曼谷成功举行,发明家周初材被授予中泰友好交流大使

今年是共建“一带一路”倡议提出十周年。十年来&#xff0c;共建“一带一路”倡议从理念到行动&#xff0c;从愿景到现实&#xff0c;开展更大范围、更高水平、更深层次的区域合作&#xff0c;致力于维护全球自由贸易体系和开放型世界经济&#xff0c;推动文明交流互鉴&#xf…

openeuler服务器 ls 和ll 命令报错 command not found...

在openeuler服务器执行 ls 和ll 命令报错 command not found... 大概是系统环境变量导致的问题。 我在安装redis是否没有安装成功后就出现了这样的情况。编辑profile文件没有写正确&#xff0c;导致在命令行下ls 和 ll 等命令不能够识别。 重新设置一下环境变量。 export PAT…

【项目学习1】如何将java对象转化为XML字符串

如何将java对象转化为XML字符串 将java对象转化为XML字符串&#xff0c;可以使用Java的XML操作库JAXB&#xff0c;具体操作步骤如下&#xff1a; 主要分为以下几步&#xff1a; 1、创建JAXBContext对象&#xff0c;用于映射Java类和XML。 JAXBContext jaxbContext JAXBConte…

Oracle 开发篇+Java通过共享模式访问Oracle数据库

标签&#xff1a;共享服务器进程、shared server process释义&#xff1a;shared server process是Oracle的一种数据库连接技术&#xff0c;类似的还有专用模式和DRCP ★ 数据库配置 alter system set shared_server_sessions1 scopespfile; alter system set max_shared_serv…

最大限度增加销售额!亚马逊提醒卖家准备Q4季度促销库存!

亚马逊美国站发布公告称为了最大限度提高卖家销售额&#xff0c;确保您的亚马逊物流库存在第四季度的促销活动中按时到达亚马逊运营中心&#xff0c;亚马逊建议卖家检查补货库存并及时将库存送到运营中心&#xff0c;以下是公告内容&#xff1a; 为了最大限度地提高您的假期销…

Practices9(双指针)|283. 移动零、11. 盛最多水的容器、15. 三数之和

283. 移动零 1.题目&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,…

全网最细,Fiddler修改接口返回数据详细步骤实战,辅助接口测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在测试的过程中&a…

React入门学习笔记3

事件处理 通过onXxx属性指定事件处理函数(注意大小写) React使用的是自定义(合成)事件, 而不是使用的原生DOM事件——为了更好的兼容性 eg&#xff1a;οnclick》onClickReact中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了更高效通过event.target得到发生…

新版Android Studio模拟器浮动

&#xff08;水一篇&#xff0c;但其实很多入门同学不知道&#xff09; 安装新版Andorid Studio后会发现模拟器是内嵌在AS中的&#xff0c;如何让她浮动

day5 STM32中断系统

中断的基本概念 在处理器中&#xff0c;中断是一个过程&#xff0c;即CPU正常执行程序的过程中&#xff0c;遇到外部或者内部的紧急时间需要处理&#xff0c;暂时终止当前程序的执行&#xff0c;转而去为处理紧急的时间&#xff0c;待处理完毕后再返回被打断的程序出继续往下执…

ffmpeg命令行是如何打开vf_scale滤镜的

前言 在ffmpeg命令行中&#xff0c;ffmpeg -i test -pix_fmt rgb24 test.rgb&#xff0c;会自动打开ff_vf_scale滤镜&#xff0c;本章主要追踪这个流程。 通过gdb可以发现其基本调用栈如下&#xff1a; 可以看到&#xff0c;query_formats&#xff08;&#xff09;中创建的v…

消息队列(3) -封装数据库的操作

前言 上一篇博客我们写了, 关于交换机, 队列,绑定, 写入数据库的一些建库建表的操作 这一篇博客中,我们将建库建表操作,封装一下实现层一个类来供上层服务的调用 , 并在写完该类之后, 测试代码是否完整 实现封装 在写完上述的接口类 与 xml 后, 我们想要 创建一个类 ,来调用…

保证接口数据安全的10种方式

我们日常开发中&#xff0c;如何保证接口数据的安全性呢&#xff1f;个人觉得&#xff0c;接口数据安全的保证过程&#xff0c;主要体现在这几个方面&#xff1a;一个就是数据传输过程中的安全&#xff0c;还有就是数据到达服务端&#xff0c;如何识别数据&#xff0c;最后一点…

Java基础篇--修饰符

Java语言提供了很多修饰符&#xff0c;主要分为以下两类&#xff1a; 访问控制修饰符 非访问修饰符 访问控制修饰符 private&#xff1a;私有访问权限&#xff0c;用于修饰类的属性和方法。被private修饰的成员只能在本类中进行访问。default&#xff08;默认访问权限&…

ctypes使用浅谈

什么是ctypes&#xff1a; ctypes 是 Python 的一个标准库&#xff0c;用于与 C 语言进行交互。它提供了一组工具和函数&#xff0c;可以方便地调用动态链接库&#xff08;DLL&#xff09;或共享对象&#xff08;SO&#xff09;中的 C 函数&#xff0c;并处理 C 数据类型的转换…

MySQL中基础查询语句

用户表user数据如下&#xff1a; iddevice_idgenderageuniversityprovince12138male21北京大学Beijing23214male复旦大学Shanghai36543famale20北京大学Deijing42315female 23 浙江大学ZheJiang55432male25山东大学Shandong 1&#xff0c;写出ddl语句创建如上表&#xff0c;…