SpringCloud —— Hystrix 简介

前文

SpringCloud 简介

SpringCloud 版本选型

SpringCloud 工程构建

SpringCloud —— Eureka 注册中心

SpringCloud —— Eureka 集群

SpringCloud —— 服务注册进 Eureka 集群

SpringCloud —— Eureka 自我保护

SpringCloud —— SpringCloud Consul 实现服务注册中心

SpringCloud —— 三个注册中心的异同点

SpringCloud —— Ribbon

SpringCloud —— Ribbon 负载均衡算法

SpringCloud —— OpenFeign

分布式系统面临的问题

复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败

服务雪崩

    多个微服务之间调用的时候,假设微服务 A 调用微服务 B 和 微服务 C,微服务 B 和微服务 C 又调用其它的微服务,这就是所谓的 “扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务 A 的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的 “雪崩效应”

    对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其它系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统

    所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其它的模块,这样就会发生级联故障,或者叫雪崩

Hystrix 是什么?(概念)

    Hystrix 是一个用于处理分布式系统的 延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix 能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性

    “断路器” 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用放返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法处理的异常,这样就保证了服务调用方法的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩

Hystrix 能干什么?

服务降级

当服务器忙,请稍后再试,不让客户端等待并立即返回一个友好的 fallback

哪些情况会触发降级?

  • 程序运行异常
  • 超时
  • 服务熔断触发服务降级
  • 线程池 / 信号量打满也会导致服务降级

服务熔断

类似保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好的提示

服务降级 ——> 进而熔断 ——> 恢复调用链路

服务限流

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟 N 个,有序地进行

Hystrix 实战

构建项目 8001(提供者)

新建 Module 8001

添加依赖

<dependencies>
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--eureka client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <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>

编写 application.yml 文件

server:
  port: 8001

spring:
  application:
    name: demo-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

编写 Service

package com.java.springcloud.service;

import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author Woo_home
 * @create 2020/3/28 12:33
 */

@Service
public class PaymentService {

    /**
     * 正常访问
     * @param id
     * @return
     */
    public String paymentInfo_OK(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentInfo_OK,id :" + id;
    }

    public String paymentInfo_Timeout(Integer id) {
        int timeNumber = 3;
        try {
            TimeUnit.SECONDS.sleep(timeNumber);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentInfo_OK,id :" + id + "\t" + "耗时 " + timeNumber + " s";
    }

}

编写 Controller

package com.java.springcloud.Controller;

import com.java.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Woo_home
 * @create 2020/3/28 12:39
 */

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfo_OK(id);
        log.info("****** result ****** " + result);
        return result;
    }

    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfo_Timeout(id);
        log.info("****** result ****** " + result);
        return result;
    }
}

编写启动类

package com.java.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author Woo_home
 * @create 2020/3/28 12:52
 */

@SpringBootApplication
@EnableEurekaClient
public class HystrixPaymentMain8001 {
    public static void main(String[] args){
        SpringApplication.run(HystrixPaymentMain8001.class,args);
    }
}

测试

启动服务端 7001,启动客户端 8001,访问 http://eureka7001.com:7001/

成功注册到 Eureka
在这里插入图片描述
在这里插入图片描述
也能正常访问 http://localhost:8001/payment/hystrix/ok/1 和 http://localhost:8001/payment/hystrix/timeout/1
在这里插入图片描述
在这里插入图片描述
控制台输出:
在这里插入图片描述


完整代码已上传至码云,感兴趣的朋友可以下载测试下 代码地址

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值