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")})@Overridepublic 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.hqwc.cn/news/62963.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VS Code 使用cnpm下载包失败

一、 问题如下&#xff1a; 网上找到的解决方法是要在powershell中执行&#xff1a; Set-ExecutionPolicy RemoteSigned进行更改策略。 首先我们解释下这个Set-ExecutionPolicy RemoteSigned&#xff0c;Set-ExecutionPolicy 是一个 PowerShell 命令&#xff0c;用于控制脚本…

为什么商业基础软件需要开源

Bytebase 本身是一家商业软件公司&#xff0c;而作为最核心资产的代码从 Day 0 却是开源的。同时我们还是 star-history.com 的运营者&#xff0c;大家在各种开源渠道会看到它生成的图&#xff1a; 一直以来&#xff0c;常会被别人问起的一个问题&#xff0c;就是为什么 Byteba…

C# 使用FFmpeg.Autogen对byte[]进行编解码

C# 使用FFmpeg.Autogen对byte[]进行编解码&#xff0c;参考&#xff1a;https://github.com/vanjoge/CSharpVideoDemo 入口调用类&#xff1a; using System; using System.IO; using System.Drawing; using System.Runtime.InteropServices; using FFmpeg.AutoGen;namespace F…

最新AI创作系统ChatGPT源码V2.5.8/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt+MJ以图生图+思维导图生成!

使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到系统&#xff01; 最新版【V2.5.8】更新&#xff1a; 新增 MJ 官方图片重新生成指令功能同步官方 Vary 指令 单张图片对比加强 Vary(Strong) | Vary(Subtle)同步官方 Zoom 指令 单张图片无限缩放 Zoom out 2x | Zoom ou…

【BI系统】选型常见问题解答二

本文主要总结BI系统选型过程中遇见的常见问题&#xff0c;并针对性做出回答&#xff0c;希望能为即将选型&#xff0c;或正在选型BI系统的企业用户们提供一个快速了解通道。 有针对金蝶云星空的BI方案吗&#xff1f;能起到怎样的作用&#xff1f; 答&#xff1a;奥威BI系统拥…

CTF-Flask-Jinja2(持续更新)

放心&#xff0c;我会一直陪着你 一.知识一.在终端的一些指令1.虚拟环境2.docker容器二.SSTI相关知识介绍1.魔术方法2.python如何执行cmd命令3.SSTI常用注入模块(1)文件读取(2)内建函数eval执行命令(3)os模块执行命令(4)importlib类执行命令(5)linecache函数执行命令(6)subproc…

Android Socket使用TCP协议实现手机投屏

本节主要通过实战来了解Socket在TCP/IP协议中充当的是一个什么角色&#xff0c;有什么作用。通过Socket使用TCP协议实现局域网内手机A充当服务端&#xff0c;手机B充当客户端&#xff0c;手机B连接手机A&#xff0c;手机A获取屏幕数据转化为Bitmap&#xff0c;通过Socket传递个…

vim学习笔记(致敬vim作者)

vim cheat sheet 30. vim 删除大法 vim 删除某个字符之后改行的其他的字符&#xff1f;删除某行之后的其他行&#xff1f;删除某个字符之后的其他字符&#xff1f;【1】删除单个字符&#xff1f; 跳到要删除的字符位置 按下d键然后按下shift 4键 【2】删除某行之后的其他行…

搭建了个腾讯滑块服务,直接取ticket的,仅供测试.

最近闲着没事搭建了个TX滑块验证码服务,C#写的. 接口是rest接口 提交任务POST http://47.104.132.20:19090/task/addTask 提交数据: { "url": "https://ssl.captcha.qq.com/template/wireless_mqq_captcha.html?stylesimple&aid16&uin3557247785…

tomcat上部署jpress

一.确保有jdk&#xff0c;tomcat和mysql环境 二.新建jpress数据库&#xff0c;新建jpress用户并赋予所有权限 三.将jpress的war上传到tomcat/apache-tomcat-8.5.70/webapps&#xff0c;具体根据你的实际tomcat安装路径为准&#xff0c;上传完成后他会自己解包 四.到浏览器完…

stable-diffusion 模型效果+prompt

摘自个人印象笔记&#xff0c;图不完整可查看原笔记&#xff1a;https://app.yinxiang.com/fx/55cda0c6-2af5-4d66-bd86-85da79c5574ePrompt运用规则及技巧 &#xff1a; 1. https://publicprompts.art/&#xff08;最适用于OpenArt 线上模型 https://openart.ai/&#xff09;…