精华内容
下载资源
问答
  • 降级与限流概念 降级 当访问量剧增,服务出现问题时,需要做一些处理,比如服务降级服务降级就是将某些服务停掉或者不进行业务处理,释放资源来维持主要服务的功能。 释放掉一些资源,将一些不那么重要的服务采取...

    降级与限流概念

    降级
    当访问量剧增,服务出现问题时,需要做一些处理,比如服务降级。
    服务降级就是将某些服务停掉或者不进行业务处理,释放资源来维持主要服务的功能。
    释放掉一些资源,将一些不那么重要的服务采取降级措施,
    限流
    限流的目的是为了保护系统不被大量请求冲垮,通过限制请求的速度和次数来保护系统。

    实现方式

    1. 服务降级有很多种方式,最好的方式就是利用 Docker 来实现。当需要对某个服务进行降级时,
      直接将这个服务所有的容器停掉,需要恢复的时候重新启动就可以了。

    2. 还有就是在 API 网关层进行处理,当某个服务被降级了,前端过来的请求就直接拒绝掉,不往内部服务转发,将流量挡回去。

    3. 限流的方式也有多种,可以在 Nginx 层面限流,也可以在应用当中限流,比如在 API 网关中。

    限流的算法

    • 计数器:
      计算单元时间内访问接口的次数,如果达到次数,则限制访问

    • 令牌桶:

    令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。可以控制流量也可以控制并发量, 假如我们想要控制 API 网关的并发量最高为 1000,可以创建一个令牌桶,以固定的速度往桶里添加令牌,超出了 1000 则不添加。

    当一个请求到达之后就从桶中获取一个令牌,如果能获取到令牌就可以继续往下请求,获取不到就说明令牌不够,并发量达到了最高,请求就被拦截

    • 漏桶:
    1. 漏桶是一个固定容量的桶,按照固定的速率流出,可以以任意的速率流入到漏桶中,超出了漏桶的容量就被丢弃,总容量是不变的。但是输出的速率是固定的,无论你上面的水流入的多快,下面的出口只有这么大,就像水坝开闸放水一样

    计数器(依赖,配置)

    zuul中

    <dependency>
        <groupId>com.marcosbarbero.cloud</groupId>
        <artifactId>spring-cloud-zuul-ratelimit</artifactId>
        <version>2.0.6.RELEASE</version>
    </dependency>
    

    限流粒度
    在这里插入图片描述

    在application.yml中

    zuul:
      routes:
        jwxt-teacher:
          path: /teacher/**
          service-id: jwxt-teacher
        jwxt-learner:
          path: /student/**
          service-id: jwxt-learner
        ignored-services: '*'
      ratelimit: #3秒内访问不允许超过 2 次,并且这 2 次请求要小于 5 秒
        enabled: true  # 开启限流开关
        behind-proxy: true # 开启限流代理
        default-policy: #
          limit: 2 #单元时间内置允许访问2次
          quota: 5 #单元时间内每个请求不得超过5秒
          refresh-interval: 3 #单元时间 3秒
    
    展开全文
  • dubbo服务降级与限流

    2020-11-19 22:25:40
    作为RPC框架,dubbo在调用过程中不可避免的会出现各种异常问题,在使用springcloud进行微服务治理时,会接触到hystrix,sentinel等服务限流降级框架,同样对于dubbo来说,使用过程中也需要考虑这方面的问题 ...

    前言

    作为RPC框架,dubbo在调用过程中不可避免的会出现各种异常问题,在使用springcloud进行微服务治理时,会接触到hystrix,sentinel等服务限流降级框架,同样对于dubbo来说,使用过程中也需要考虑这方面的问题

    1、集群容错

    集群容错指的是,当消费者调用提供者集群时发生异常的处理方案,以上一篇的小demo为例,当consumer端调用hello这个服务时,如果正好调到了其中的的一台机器上的服务挂掉了怎么办?

    在实际部署中,为了保证服务的高可用通常服务会部署多份,当某台机器的服务挂掉了,为了保证服务的可用性,从消费端来说,就可以有很多策略,下面我们简单列举几种dubbo提供的解决方案

    Failover 故障转移策略
    当消费者调用提供者集群中的某个服务器失败时,其会自动尝试调用其它服务器。该策略通常用于读操作,但重试可能会带来服务延迟

    Failfast 快速失败策略
    消费者端只发起一次调用,若失败则立即报错。通常用于非幂等性的写操作,比如新增记录,很明显通过这种操作可以避免在多节点重试操作带来的数据不一致性

    Failsafe 失败安全策略
    当消费者调用提供者出现异常时,直接忽略本次操作,该策略通常在分布式 RPC 系统框架中用于执行相对不太重要的服务

    Failback 失败自动恢复策略
    消费者调用提供者失败后,Dubbo 会记录下该失败请求,然后定时自动重新发送该请求。该策略通常用于实时性要求不太高的服务,例如在消息通知类的业务中

    Forking 并行策略
    消费者对于同一服务并行调用多个提供者服务器,只要一个成功即调用结束并返回结果。通常用于实时性要求较高的读操作,但其会浪费较多服务器资源

    Broadcast 广播策略
    广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息

    容错策略可以设置在消费者端,也可以设置在提供者端。若消费者与提供者均做了设置,
    则消费者端的优先级更高

    Dubbo 默认的容错策略是故障转移策略 Failover,即允许失败后重试。可以通过如下方式来设置重试次数,注意设置的是重试次数,不含第一次正常调用

    <dubbo:reference id="helloService" check="false" protocol="dubbo" interface="com.congge.service.HelloService"
                         cluster="failover"
                         retries="2">
        </dubbo:reference>
    

    如果需要更换集群的容错策略,只需修改cluster=“failover” ,将failover换成上面的其他配置方式即可

    2、服务降级

    服务降级

    服务降级,当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务有策略的
    降低服务级别,以释放服务器资源,保证核心任务的正常运行,比如双11进行大促秒杀活动的时候,可以适当关闭短信通知服务或评论服务,确保整个下单服务的可用

    服务降级常用策略

    • 部分服务暂停
    • 全部服务暂停
    • 随机拒绝服务
    • 部分服务延迟

    我们先来回忆下在springcloud中我们是怎么做服务降级的呢?可以针对部分服务统一返回一个友好的提示供前端页面展示,或者干脆返回空数据吧

    在dubbo中,提供了类似的处理方式,Dubbo的服务降级采用的是mock机制,有两种降级处理方式:Mock Null降级处理,与 Mock Class 降级处理,即直接针对某个方法降级,或者提供一个统一的类吧,这个类专门用于处理降级的逻辑

    下面来通过具体的代码演示下吧

    dubbo服务降级之mock

    设想这么一种场景,当开发人员知道服务提供者的某些服务处于不可用状态时,为了不影响使用体验,就可以考虑使用dubbo提供的mock功能

    使用dubbo的mock功能非常简单,对于服务调用方来说,只需要做如下简单的配置,即在依赖的服务接口标签中添加moc属性,比如这里设置为 return null,表示调用这个服务时返回null

    为了演示,我们重新创建了一个消费者工程,并添加一个接口,

    public interface UserService {
    
        String getUserById(String userId);
    
        void addUser();
    }
    
    <dubbo:reference id="userService" check="false" mock="return null"
                         interface="com.congge.service.UserService" />
    

    完整的配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="consumer-mocknull"/>
    
        <!--指定服务注册中心:zk单机模式-->
        <dubbo:registry address="zookeeper://localhost:2181" />
    
        <dubbo:reference id="userService" check="false" mock="return null"
                         interface="com.congge.service.UserService" />
    
    </beans>
    

    启动类:

    public class ConsumerRun {
    
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("spring-consumer.xml");
            UserService userService = (UserService) ac.getBean("userService");
            String userById = userService.getUserById("1");
            System.out.println(userById);
        }
    
    }
    

    运行main函数,观察控制台效果,
    在这里插入图片描述
    这里我并没有启动生产者代码,直接模拟服务不可用时的效果,但是这样的话,实际效果可能并不是那么友好,能不能像sentinel那样,自定义返回结果呢?

    dubbo提供了mock-class的功能,即提供一个类专门用于处理降级的业务,即降级相关的业务逻辑可以在这个类中统一处理,修改一下配置文件即可,将mock标签替换为 mock=true

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="consumer-mocknull"/>
    
        <!--指定服务注册中心:zk单机模式-->
        <dubbo:registry address="zookeeper://localhost:2181" />
    
        <dubbo:reference id="userService" check="false" mock="true"
                         interface="com.congge.service.UserService" />
    
    </beans>
    

    在这种情况下,我们需要在service接口相同的目录下提供一个mock类,实现相同的服务接口
    在这里插入图片描述

    public class UserServiceMock implements UserService {
        @Override
        public String getUserById(String userId) {
            return "不好意思,没有该用户," +userId;
        }
    
        @Override
        public void addUser() {
            System.out.println("用户添加失败");
        }
    }
    

    再次运行main函数,观察控制它输出结果,
    在这里插入图片描述

    3、服务超时

    在RPC调用中,不管是通过http远程调用,还是使用dubbo,服务超时是经常碰到的事情,对于服务超时,常见的做法可以重试,并设定重试次数,或者超时之后,调用者所在的服务返回一个友好的提示,在dubbo中,服务超时的配置也比较简单,和mock配置一样,添加timeout属性,根据业务调用所能容忍的最大限度设置一个合理的超时时间,通常配置在consumer端

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="consumer-timeout">
            <dubbo:parameter key="qos.port" value="55555"/>
        </dubbo:application>
    
        <!--指定服务注册中心:zk单机模式-->
        <dubbo:registry address="zookeeper://localhost:2181" />
    
        <dubbo:reference id="userService" check="false" mock="true" timeout="2000"
                         interface="com.congge.service.UserService" />
    
    </beans>
    

    比如这里配置的timeout=2000,即消费端最多等待2秒的时间,超过2秒将会走降级逻辑,为了模拟效果,我们直接在provider中,将该服务的实现休眠3秒,以便观察效果

    	@Override
        public String getUserById(String userId) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "hello consumer,is :" + userId;
    
        }
    

    provider端的其他配置不用动,然后启动provider和consumer端的程序
    在这里插入图片描述

    在这种情况下,控制台的输出日志可以看出,是由于超时引起的异常,同时走了降级的处理,但是当我们把超时时间设置的大一点时,又可以正常响应结果了

    <dubbo:reference id="userService" check="false" mock="true" timeout="4000"
                         interface="com.congge.service.UserService" />
    

    在这里插入图片描述

    通常来说,这个超时的设置配置在服务调用方,根据服务的实际情况设定一个合理的值

    4、服务限流

    为了防止某个消费者的 QPS 或是所有消费者的 QPS 总和突然飙升而导致的重要服务的失效,系统可以对访问流量进行控制,这种对集群的保护措施称为服务限流,Dubbo 中能够实现服务限流的方式较多,可以划分为两类:直接限流与间接限流

    • 直接限流:通过对连接数量直接进行限制达到限流的目的
    • 间接限流:通过一些非连接数量设置达到限制流量的目的

    executes 限流 – 仅提供者端

    该属性仅能设置在提供者端。可以设置为接口级别,也可以设置为方法级别。限制的是服务(方法)并发执行数量

    假如这里我们配置在provider端,设置executes=“10” ,即最大允许并发10个线程请求

    <dubbo:service interface="com.congge.service.UserService" ref="userService" executes="10"
                       cluster="failover"
                       retries="2"
            />
    

    在消费端的配置,我们去掉服务降级的配置,

     <dubbo:reference id="userService" check="false"
                         interface="com.congge.service.UserService" />
    

    为了模拟效果,在消费端的程序中,我们使用CountDownLatch模拟一下并发调用

    public class Consumer1 {
        public static void main(String[] args) {
            final Integer concurrency = 100;
            ExecutorService pool = Executors.newCachedThreadPool();
            final AtomicInteger number = new AtomicInteger();
            final CountDownLatch command = new CountDownLatch(1);
            for (int i = 0; i < concurrency; i++) {
                Runnable task = new Runnable() {
                    public void run() {
                        try {
                            Integer order = number.getAndIncrement();
                            command.await();
                            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-consumer.xml"});
                            context.start();
                            System.out.println(((UserService) context.getBean("userService")).getUserById(String.valueOf(order)));
                            System.in.read();
                            context.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
                pool.execute(task);
            }
            try {
                System.out.println("准备执行并发量为" + number.intValue() + "的请求");
                Thread.sleep((long) Math.random() * 1000);
                command.countDown();//启动开关
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    

    启动生产者的main函数,再执行上述的并发代码,通过控制台输出的关键信息,我们可以分析出这里是抛出了限流的异常,当然我这里对于接口的并发数量设置在服务级别,也可以设置在方法级别
    在这里插入图片描述

    accepts 限流 – 仅提供者端
    该属性仅可设置在提供者端的dubbo:provider/dubbo:protocol/,用于对指定协议的连接数量进行限制,可以配置

    <!--针对dubbo类型的协议进行限流-->
        <dubbo:provider protocol="dubbo" accepts="10"/>
    

    或者

    <dubbo:protocol name="dubbo" port="20881" accepts="10"/>
    

    actives 限流 – 两端

    该限流方式与前两种不同的是,其可以设置在提供者端,也可以设置在消费者端。可以设置为接口级别,也可以设置为方法级别

    设置在提供者一端,表示最多可以处理的请求个数,设置在消费者一端,表示当前消费者所发出的长连接中最多可以提交的请求个数

     <dubbo:service interface="com.congge.service.UserService" ref="userService" actives="10"
                       cluster="failover"
                       retries="2"
            />
    
    

    在这里插入图片描述

    最终的异常效果大同小异

    connections 限流

    可以设置在提供者端,也可以设置在消费者端。限定连接的个数。对于短连接,该属性效果与 actives 相同。但对于长连接,其限制的是长连接的个数

    一般情况下,我们会使 connectons 与 actives 联用,让 connections 限制长连接个数,让actives 限制一个长连接中可以处理的请求个数。联用前提:使用默认的 Dubbo 服务露协议

    <dubbo:service interface="com.congge.service.UserService" ref="userService" connections="10"
                       cluster="failover"
                       retries="2"
            />
    

    这样配置完毕后,再次调用上面的并发测试程序,观察控制台效果
    在这里插入图片描述

    关于dubbo的服务容错,降级与限流到这里就结束了,更多的是结合实际的业务开发场景,不断的对各种配置进行调整,寻找一个适合自己业务的平衡点就好,总归一句话,在实际开发中,dubbo的调优很大程度上是对dubbo各种配置的调优和使用,本篇到此结束,最后感谢观看!

    需要源码的同学可前往下载
    https://download.csdn.net/download/zhangcongyi420/15401687

    展开全文
  • Hystrix是netflix创建的一个用于服务降级限流熔断的组件 微服务架构中一个服务调用链任何一个环节都有可能出现异常 若对异常没有合理的处理方式,则可能导致此相关的功能不可用,甚至有可能引发雪崩现象 ...

    1. 简介

    Netflix has created a library called Hystrix that implements the circuit breaker pattern. In a microservice architecture it is common to have multiple layers of service calls.
    A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service reach a certain threshold (20 failures in 5 seconds is the default in Hystrix), the circuit opens and the call is not made. In cases of error and an open circuit a fallback can be provided by the developer.
    Having an open circuit stops cascading failures and allows overwhelmed or failing services time to heal. The fallback can be another Hystrix protected call, static data or a sane empty value. Fallbacks may be chained so the first fallback makes some other business call which in turn falls back to static data.

    • Hystrix是netflix创建的一个用于服务降级、限流熔断的组件
    • 微服务架构中一个服务调用链任何一个环节都有可能出现异常
    • 若对异常没有合理的处理方式,则可能导致与此相关的功能不可用,甚至有可能引发雪崩现象
    • Hystrix可以很好的解决服务不可用问题,可采用直接返回错误状态码、静态提示数据、以及转调统一处理方法等方式对调用方及时做出相应

    2. 代码实现

    2.1涉及的模块

    • eureka-server-singleton:服务注册中心,端口8761
    • eureka-service: 服务提供者,通过profile指定不同端口模拟一组微服务,端口8762、8763
    • eureka-service-ribbon-hystrix:通过Ribbon调用服务提供者提供的服务,并提供限流熔断功能

    2.2 源代码

    2.2.1 Github地址

    https://github.com/andyChenHuaYing/spring-cloud-demo

    2.2.2 切换

    通过tag切换git tag -d v1.0,若想修改,可根据此tag创建新的分支。
    

    Spring Cloud 之服务发现与调用-Ribbon#2.3 eureka-server-singleton 没有任何区别

    2.3 eureka-service

    Spring Cloud 之服务发现与调用-Ribbon#2.4 eureka-service 没有任何区别

    2.4 eureka-service-ribbon-hystrix

    2.4.1整体实现步骤

    1. pom.xml中引入spring-cloud-starter-netflix-eureka-serverspring-cloud-starter-netflix-ribbonspring-cloud-starter-netflix-hystrix依赖
    2. application.yml中指定配置项:端口、application name、eureka-server地址
    3. SpringBoot 启动类添加注解@EnableHystrix开启使用Hystrix功能
    4. 使用@Bean @LoadBalanced向Spring容器注入org.springframework.web.client.RestTemplate 实例
    5. 在使用之处使用@Autowired public RestTemplate restTemplate; 获取实例,调用服务提供方提供的方法
    6. 在需要使用Hystrix服务降级、容错功能的方法上使用@HystrixCommand(fallbackMethod = "hiError")指定回调方法

    2.4.2 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring-cloud-finchley-demo</artifactId>
            <groupId>org.oscar.scd</groupId>
            <version>1.0.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>eureka-service-ribbon-hystrix</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
        </dependencies>
    
    </project>

    2.4.2 application.yml

    server:
      port: 8766
    
    spring:
      application:
        name: eureka-service-ribbon-hystrix
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/

    2.4.3 EurekaServiceRibbonHystrixApplication

    package org.oscar.scd.eureka.service.ribbon.hystrix;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @EnableHystrix
    @EnableEurekaClient
    @EnableDiscoveryClient
    @SpringBootApplication
    public class EurekaServiceRibbonHystrixApplication {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServiceRibbonHystrixApplication.class, args);
        }
    }
    

    2.4.4 HelloRibbonHystrixController、HelloRibbonHystrixService

    • HelloRibbonHystrixService:
    package org.oscar.scd.eureka.service.ribbon.hystrix.service;
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    @Service
    public class HelloRibbonHystrixService {
    
        @Autowired
        public RestTemplate restTemplate;
    
        @HystrixCommand(fallbackMethod = "hiError")
        public String hiService(String name) {
            return restTemplate.getForObject("http://eureka-service//print?name=" + name, String.class);
        }
    
        public String hiError(String name) {
            return "Hi " + name + ", sorry, system error.";
        }
    
    }
    
    • HelloRibbonHystrixController:
    package org.oscar.scd.eureka.service.ribbon.hystrix.controller;
    
    import org.oscar.scd.eureka.service.ribbon.hystrix.service.HelloRibbonHystrixService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/ribbon/hystrix")
    public class HelloRibbonHystrixController {
    
        @Autowired
        public HelloRibbonHystrixService service;
    
        @GetMapping("/print")
        public String print(@RequestParam String name) {
            return this.service.hiService(name);
        }
    }
    

    3. 验证

    3.1 创建SpringBoot启动类

    3.1.1 EurekaServerSingletonApplication

    最简单的方式添加一个SpringBoot启动类型的启动类就行。
    

    这里写图片描述

    3.1.2 EurekaServiceApplication-8762

    EurekaServiceApplication-8762

    3.1.3 EurekaServiceApplication-8763

    与8762相同,只是修改 Active profiles 为8763
    

    3.1.4 EurekaServiceRibbonHystrixApplication

    最简单的方式添加一个SpringBoot启动类型的启动类就行。
    

    3.2 启动

    1. EurekaServerSingletonApplication
    2. EurekaServiceApplication-8762
    3. EurekaServiceApplication-8763
    4. EurekaServiceRibbonHystrixApplication

    启动完成后Run Dashboard界面:
    这里写图片描述

    3.3 访问服务信息界面

    此时服务都是正常注册状态!
    

    这里写图片描述

    3.4 服务提供者正常

    • 第一次访问,正常返回,服务提供者端口为:8763
      这里写图片描述

    • 第二次访问,也正常返回,服务提供者端口为:8762
      这里写图片描述

    3.5 服务提供者异常

    验证Hystrix是否生效,整体步骤
    

    1. 停止端口为8762的服务提供者,观察eureka-server信息界面,服务是否下线以及再次调用服务,观察返回结果是否只有8763端口响应
    2. 停止端口为8763的服务提供者,观察eureka-server信息界面,服务是否下线以及再次调用服务,观察返回结果是否是Hystrix服务熔断回调函数返回的结果
    3. 若都是,则验证Hystrix功能生效

    3.5.1 停止端口8762服务

    1. eureka-server信息界面:停止的8762没有像我们预期的下线,并且出现了红色的提示(eureka-server进入了自我保护模式-见补充部分)
      这里写图片描述

    2. 访问服务:绝大部分时间返回的是8763,8762服务刚停时,偶尔会返回Hystrix熔断回调函数的结果
      这里写图片描述

    3.5.2 停止端口8763服务

    1. eureka-server信息界面:
      这里写图片描述
    2. 访问服务:只会返回Hystrix熔断回调函数的结果
      这里写图片描述

    到这里,基本验证了Hystrix启作用了,但是这只是入门级别的使用,还有几个疑点后续解决。

    4. 思考

    • 服务下线之后,eureka-server信息界面为什么只出现红色提示信息,并且没有将服务下线?或者说是服务已下线但是没有将服务状态标识为已下线或者不可用?
    • 这样设计的理由是什么?如何让已停止提供服务的服务信息在eureka-server中看的到呢
    • 为什么刚停止两个服务提供者之一时,访问服务信息会偶尔出现Hystrix熔断之后的回调函数处理结果?
    • Hystrix的处理方法能否指定使用单独的Thread或者ThreadPool来执行,

    5. 补充

    5.1 资料

    5.2 Eureka 自我保护

    Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。
    解决方式(或者说处理措施,在后续详细使用或者问题整理中会解)

    展开全文
  • dubbo服务降级限流

    2020-06-14 22:15:29
    服务降级 解决高并发的三把利器:降级、限流、缓存...服务降级与Mock机制 Dubbo的服务降级,采用Mock机制。其具有两种降级处理方式:Mock Null降级处理,与Mock Class降级处理 Mock Null降级处理 消费者服务降级代

    服务降级

    解决高并发的三把利器:降级、限流、缓存。

    服务降级基础

    什么是服务降级

    • 服务降级,当服务器压力剧增情况下,根据当前业务的情况及流量对一些服务有策略地降低服务级别,以释放服务器资源,保证核心人物的正常运行。

    服务降级方式

    • 部分服务暂停
    • 全部服务暂停
    • 随机拒绝服务
    • 部分服务延迟

    服务降级埋点

    在这里插入图片描述

    服务降级与Mock机制

    Dubbo的服务降级,采用Mock机制。其具有两种降级处理方式:Mock Null降级处理,与Mock Class降级处理

    Mock Null降级处理

    • 消费者服务降级代码配置
    <dubbo:reference id="demoService" mock="return null" interface="com..."/>
    

    Mock Class降级处理

    • 消费者服务降级代码配置
    <dubbo:reference id="demoService" mock="true" interface="com..."/>
    
    • 代码规范
    //1、Mock class DemoServiceMock,即接口类名称+Mock
    //2、和接口必须在同一个包里,即相同目录下
    public class DemoServiceMock implements DemoService{
    	@Override
    	public String testReturn(){
    		return "哈哈降级啦";
    	}
    	
    	@Override
    	public void testVoid(){
    		log.info("呵呵降级啦");
    	}
    }
    

    服务限流

    为了防止某个消费者的QPS,或者所有消费者的QPS总和突然飙升导致某些重要的服务失败,系统可以对访问流量进行限制,这种对集群的保护措施称为服务限流。
    Dubbo中可以实现现有的方案比较多,可以划分为两类:直接限流和间接限流
    直接限流:通过对连接数据进行限制来到底限流的目的。(官方方案)
    间限限流:通过一些非连接数量设置来到的限流的目的。

    直接限流

    executes限流

    改属性仅能设置在提供者端。可以设置为接口或方法级别。
    限制的是接口(或方法)并发执行数量。

    <!--限制接口中的每个方法的并发数量不能超过10个-->
    <dubbo:service interface="com...DemoService" ref="demoService" executes="10"/>
    

    accepts限流

    该属性仅可设置在提供者端 <dubbo:provide>与<dubbo:protocol>
    用于对指定协议的连接数量进行限制

    <!--限制当前提供者使用dubbo协议时最多接受10个消费者连接-->
    <dubbo:provide  protocol="dubbo" accepts="10"/>
    <!--限制当前提供者使用dubbo协议时最多接受10个消费者连接-->
    <dubbo:protocol  name="dubbo" port="20880" accepts="10"/>
    

    actives限流

    可以设置在提供者端或消费者端。
    可以设置成接口级别和方法级别。

    • 提供者端限流
      • 其根据消费者和提供者间建立的连接类型的不同,其意义也不同:
      • 长连接:表示当前长连接最多处理的请求的个数,与长连接的数量没有关系。
      • 断连接:表示当前可以同时处理的短链接数量。
    <dubbo:service interface="com...DemoService" ref="demoService" actives="10"/>
    
    • 消费者端
      • 其根据消费者和提供者间建立的连接类型的不同,其意义也不同:
      • 长连接:表示当前消费者所发出的长连接中最多可以提交的请求个数,与长连接的数量没有关系。
      • 断连接:表示当前消费者可以提交的短链接数量。
    <dubbo:reference id="demoService" interface="com..."  actives="10"/>
    

    connections限流

    可以设置在提供者端或消费者端,限定连接的个数。
    可以设置成接口级别和方法级别。

    • 对于短链接,其相当于actives限流
    • 对于长连接,其设置的是长连接的数量。
    • 一般情况下,使用connections和actives同时使用,让connections限制长连接的个数,让actives限制一个长连接中的请求的个数。联用前提,必须使用dubbo协议。

    间接限流

    • 延迟连接

    仅可设置下消费者端,且不能设置方法级别。仅作用于Dubbo服务暴漏协议。
    将长连接的建立推迟到消费者调用提供者时。

    <!--设置当前消费者对指定接口的每一个方法发出的连接均采用延迟连接-->
    <dubbo:reference id="demoService" interface="com..."  lazy="true"/>
    
    <!--设置当前消费者对所有接口的所有方法发出的连接均采用延迟连接-->
    <dubbo:consumer lazy="true"/>
    
    • 粘连连接

    仅可设置下消费者端,可以设置在接口和方法级别上。仅作用于Dubbo服务暴漏协议。
    其会使客户端尽量向同一个提供者发起调用,除非该提供者挂了,其后连接另一个。
    只要启用了粘连连接,其会自动启用延迟连接
    其限制的是流向,而不是流量。

    <!--设置当前消费者对指定接口的每一个方法开启粘连连接-->
    <dubbo:reference id="demoService" interface="com..."  sticky="true"/>
    
    • 负载均衡

    可以设置在提供者端或消费者端。
    可以设置成接口级别和方法级别。
    其限制的是流向,而不是流量。

    <!--通过指定负载均衡策略为leastactive来达到限流的目的-->
    <dubbo:service interface="com...DemoService" ref="demoService" loadbalance="leastactive"/>
    
    展开全文
  • 一、Sentinel 是什么 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量...控制台用于管理限流,熔断规则的发布监控。 客户端则用于接收规则,并执行相关...
  • Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 的历史 2012 年,Sentinel 诞生,...
  • 出现了Hystrix中出现的问题,降级方法业务方法耦合,一个服务需要配置一个降级方法,并且配置没有实现持久化 自定义限流处理逻辑 单独创建一个类,用于处理限流,里面定义了handlerException1和handlerException2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 558
精华内容 223
关键字:

服务降级与限流