Hystrix负载均衡--SpringCloud学习笔记

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,能保证在一个依赖出问题的情况下不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

  • 服务降级fallback
    服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示
    • 程序运行异常
    • 超时
    • 服务熔断触发服务降级
    • 线程池、信号量打满也会导致服务降级
  • 服务熔断break
    达到最大服务访问后,直接拒绝访问,然后调用服务降级的方法并返回友好提示
  • 服务限流flowlimit
    秒杀高并发等操作,严禁一窝蜂的过来拥挤

服务降级

一般是放在客户端,这里先说服务端8001端口

首先是添加pom依赖,引入hystrix

<!--hystrix-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

主启动类加上注解

@EnableHystrix

或者

@EnableCircuitBreaker

对于要降级的service实现加上注解

@HystrixCommand(fallbackMethod = "paymentInfoTimeoutHandler",commandProperties = {
    
    
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })

其中paymentInfoTimeoutHandler是服务降级后调用的方法名,方法需要自己写(注意,这个方法的返回类型、参数类型都要和要保护的方法保持一致),一般就是返回一个错误页面,value是最大的等待时间,由name知单位是ms,例子中是超过3s即跳转paymentInfoTimeoutHandler方法。

下面说80端口的使用。

首先添加yml配置

#开启Hystrix支持
feign:
  hystrix:
    enabled: true

主启动类加注解

@EnableHystrix

然后可以直接在controller层的方法中加类似注解

@HystrixCommand(fallbackMethod = "paymentInfoTimeoutHandler",commandProperties = {
    
    
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })

即可实现客户访问端自身的保护。

或者直接加一个全局异常方法,写在controller中,然后controller添加全局注解,

@DefaultProperties(defaultFallback = "paymentGlobalFallback")

其中paymentGlobalFallback为自定义的方法。需要时,在方法头添加注解@HystrixCommand,即可实现保护。

再或者,在客户端的service上使用注解

@FeignClient(value = "cloud-payment-hystrix-service",fallback = PaymentFallback.class)

然后定义PaymentFallback类,在类中重写,当service中的方法出现超时、程序异常、宕机则会服务降级实现PaymentFallback里面重写的方法。

注意,这里一定要在yml中配置好

#开启Hystrix支持
feign:
  hystrix:
    enabled: true

服务熔断

大量访问后会直接挂,然后尝试启动,如果访问量变小就会恢复服务。

在服务端8001端口service层添加

@HystrixCommand(fallbackMethod = "paymentCircuitBreakFallback",commandProperties = {
    
    
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),//失败率达到多少后跳闸
    })
    @Override
    public String paymentCircuitBreaker(Integer id) {
    
    
        if (id<0){
    
    
            throw new RuntimeException("****id不能为负");
        }
        String simpleUUID = IdUtil.simpleUUID();
        return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+simpleUUID;
    }

    @Override
    public String paymentCircuitBreakFallback(Integer id) {
    
    
        return "id不能为负,请重试--------id="+id;
    }

@HystrixCommand注解中的"paymentCircuitBreakFallback"是自己写的方法,它返回错误页面的信息。@HystrixProperty注解中涉及到断路器的几个重要参数是否开启断路器、快照时间窗、请求总数阈值、错误百分比阈值。

  • 是否开启断路器:true即为开启
  • 快照时间窗:默认是10秒,是断路器统计的时间范围
  • 请求总数阈值:默认是20,在快照时间窗给定的时间内必须满足请求总数阈值才有资格熔断,否则断路器不会打开
  • 错误百分比阈值:当请求总数超过请求总数阈值,且发生超时异常的百分比超过了错误百分比阈值,那么这时断路器就会打开。

上述示例中,参数id>0会输出流水号之类;参数id<0会报异常。

然后8001端口的Controller层天添加服务熔断的GetMapping

//----服务熔断
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
    
    
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("****result:"+result);
        return result;
    }

多次输入错误的信息(例如id多次输入负值)会导致服务熔断,熔断后即使输入正确的信息也会报错,但是一段时间后输入正确的信息又会可用,这就是服务熔断的作用。

HystrixDash的使用

pom

<?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>cloud2020</artifactId>
        <groupId>com.meng</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-hystrix-dashboard9001</artifactId>

    <dependencies>
        <!--hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--devtool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

yml

server:
  port: 9001

主启动类

package com.meng;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

/**
 * @author Administrator
 */
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(HystrixDashboardMain9001.class,args);
    }
    
    @Bean
    public ServletRegistrationBean getServlet(){
    
    
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
}

然后浏览器访问http://localhost:9001/hystrix即可,访问需要监控的8001端口http://localhost:8001/hystrix.stream

注意:这里被监控的8001端口一定要加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

猜你喜欢

转载自blog.csdn.net/liuliusix/article/details/108974860