dubbo之高可用

这篇具有很好参考价值的文章主要介绍了dubbo之高可用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

负载均衡

概述

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

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

策略

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

dubbo之高可用,Java,dubbo,java,spring

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));
    }
}文章来源地址https://www.toymoban.com/news/detail-637894.html

到了这里,关于dubbo之高可用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ常见问题之高可用

    RabbitMQ 的是基于 Erlang 语言编写,而 Erlang 又是一个面向并发的语言,天然支持集群模式。 RabbitMQ 的集群有两 种模式: 普通集群:是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。 镜像集群:是一种主从集群,普通集群的基础上,添加了主从备

    2024年01月18日
    浏览(46)
  • 14.RocketMQ之高可用性机制

    RocketMQ分布式集群是通过Master和Slave的配合达到高可用性的。 Master和Slave的区别:在Broker的配置文件中,参数 brokerId的值为0表明这个Broker是Master,大于0表明这个Broker是 Slave,同时brokerRole参数也会说明这个Broker是Master还是Slave。 Master角色的Broker支持读和写,Slave角色的Broker仅支

    2024年02月11日
    浏览(46)
  • k8s 自身原理之高可用

    说到高可用,咱们在使用主机环境的时候(非 k8s),咱做高可用有使用过这样的方式: 服务器做主备部署,当主节点和备节点同时存活的时候,只有主节点对外提供服务, 备节点就等着主节点挂了之后,立刻补位 另外为了提供服务的可用性,做了异地多活,增加服务的接入

    2024年02月12日
    浏览(34)
  • Redis 从入门到精通【进阶篇】之高可用集群(Redis Cluster)详解

    前面两个章节我们学习关于Redis 中的高可用 Redis主从复制. 以及Redis的哨兵模式(sentinel)。我们能够发现上面两种方式主要解决读写分离,备份冗余,以及故障恢复,故障转移。但是无法解决redis的性能问题,我们如果做过测试会发现 redis在单节点的情况下,只能将CPU的一个

    2024年02月16日
    浏览(41)
  • dubbo的高可用

    现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务。 原因: 在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。 (1)负载均衡策略 Random LoadBalance 随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使

    2024年02月14日
    浏览(35)
  • 深入理解java和dubbo的SPI机制

    本质:将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。 java SPI:用来设计给服务提供商做插件使用的。基于策略模式来实现动态加载的机制。我们在程序只定义一个接口,具体的实现交个不同

    2024年02月08日
    浏览(48)
  • zookeeper和dubbo面试题,,Java初级项目案例

    一致性(Consistency)是指多副本(Replications)问题中的数据一致性。可以分为强一致性、顺序一致性与弱一致性。 1.1 强一致性(Strict Consistency) 也称为:**原子一致性(Atomic Consistency)** 线性一致性(Linearizable Consistency) 强一致性有两个要求: 任何一次读都能读到某个数据

    2024年03月16日
    浏览(44)
  • Java 【dubbo rpc改feign调用】controller注解处理

    【框架改造问题点记录,dubbo改为spring cloud alibaba】 【第三篇】controller注解处理 【描述】项目之前用了jboss,引入了很多ws.rs包,controller参数注解使用QueryParam。改造时批量替换成了@RequestParam(代表必传)。但是前端并不会传全部参数,会导致400,持续更新… 不加注解,表示

    2024年02月17日
    浏览(42)
  • Java 【dubbo rpc改feign调用】feign接口异常统一处理

    【框架改造问题点记录,dubbo改为spring cloud alibaba】 【第一篇】feign接口异常统一处理 示例代码中【ApplicationException 】、【Payload 】为自定义异常类和通用结果返回实体类: 示例代码中【ApplicationException 】、【StringUtil】为自定义异常类和自定义工具,自己平替即可:

    2024年02月16日
    浏览(36)
  • Java 【dubbo rpc改feign调用】解决调用服务提供方无法传递完整参数问题

    【框架改造问题点记录,dubbo改为spring cloud alibaba】 【第二篇】feign接口异常解决 【描述】多参数情况下,调用服务提供方无法传递完整参数、改@SpringQueryMap原因是会将实体自动拆分为拼接参数。目前只遇到多参数:实体和单参数情况,持续更新… 汇总: 1.多个普通参数,

    2024年02月16日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包