【SpringCloud】12 服务降级 Hystrix 断路器 Part1 概述和案例搭建

分布式应用系统面临的问题?

服务调用即接口调用,有一级链路调用,就会产生N级链路调用

例如:

A1服务接口是最初提供的服务接口,被A2接口调用

A2接口被A3调用,A3接口被A4调用,A4接口被A5调用,如此往下继续。。。。

An -> A5 -> A4 -> A3 -> A2 -> A1

 

每一个接口就都有可能会出现错误或者等等不可抗力的原因,无法向下调用

那么整个链路的调用就无效了

An -> A5 × A4 -> A3 -> A2 -> A1

当然,除了单链路服务接口调用,还有多链路调用的可能(扇出)

An -> A5 -> A4 -> A3 -> A2 -> A1
 |
Bn -> B2 -> B1
           |
          Cn -> C3 -> C2 -> C1

. . . . . .

多链路也有这种情况:

An -> A5 -> A4 × A3 -> A2 -> A1
 |
Bn -> B2 -> B1
           |
          Cn -> C3 × C2 -> C1

. . . . . .

如果响应时间过长或者服务本身不可用,就会造成服务崩溃

系统资源占用过多,俗称雪崩效应

Hystrix解决的就是保证一个整体的服务维持正常,提高分布式系统的弹性

断路器就是一个跳闸,该服务不可用时,Hystrix马上换到备用服务顶替上去

总之就是为了避免系统全体瘫痪

 

服务降级、服务熔断、服务限流

演示案例构建:

在之前的案例中有配置IP地址,由于自己重装了系统的原因,重新配置一下:

Hosts文件位置:

C:\Windows\System32\drivers\etc\hosts

然后在尾部追加你自己配置的Eureka服务地址:

127.0.0.1 eureka7001.cn
127.0.0.1 eureka7002.cn

回到Cloud工程中的7001服务中的Yaml配置:

server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      # defaultZone: http://eureka7002.cn:7002/eureka/
    defaultZone: http://eureka7001.cn:7001/eureka/
  server:
    enable-self-preservation: false # 关闭自我保护 不可用的服务立即移除
    eviction-interval-timer-in-ms:  2000 # 默认一个30秒,一个90秒

然后创建Hystrix的提供者8001服务模块

Cloud-Provider-Hystrix-Payment-8001

所需要的依赖坐标:

<dependencies>

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

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
        <groupId>cn.dzz.springcloud</groupId>
        <artifactId>API-Commons</artifactId>
        <version>${project.version}</version> <!--<version>1.0-SNAPSHOT</version>-->
    </dependency>

    <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>
        <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>

yaml配置:

server:
  port: 8001

eureka:
  instance:
    hostname: eureka7001
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.cn:7001/eureka/

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

编写业务层接口和实现类:这里就不搞麻烦直接写类了

package cn.dzz.service;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @file IntelliJ IDEA SpringCloud-ATGG-2020
 * @create 2020 10 04 21:49
 */
@Service
public class PaymentService {

    // 正常访问
    public String paymentInfoOk(Integer id) {
        return "线程池: " + Thread.currentThread().getName() + " payment-info:ok, id =  " + id + " 支付成功!";
    }

    // 访问超时
    public String paymentInfoTimeout(Integer id) {
        try {
            int sleepTime = 3;
            TimeUnit.SECONDS.sleep(sleepTime);
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();

        }
        return "线程池: " + Thread.currentThread().getName() + " payment-info:timeout, id =  " + id + " 请求超时!";
    }
}

控制器的接口编写:

package cn.dzz.springcloud.controller;

import cn.dzz.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Administrator
 * @file IntelliJ IDEA SpringCloud-ATGG-2020
 * @create 2020 10 04 21:58
 */

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

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

    @RequestMapping("payment/hystrix/info/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        String paymentInfoOk = paymentService.paymentInfoOk(id);
        log.info(paymentInfoOk);
        return paymentInfoOk;
    }

    @RequestMapping("payment/hystrix/info/timeout/{id}")
    public String paymentInfoTimeout(@PathVariable("id") Integer id) {
        String paymentInfoTimeout = paymentService.paymentInfoTimeout(id);
        log.info(paymentInfoTimeout);
        return paymentInfoTimeout;
    }
}

编写启动类:

package cn.dzz.springcloud;

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

/**
 * @author Administrator
 * @file IntelliJ IDEA SpringCloud-ATGG-2020
 * @create 2020 10 04 21:48
 */
@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrix8001Application {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrix8001Application.class, args);
    }
}

启动服务:

 

 访问接口:

http://localhost:8001/payment/hystrix/info/ok/1

访问超时接口:

http://localhost:8001/payment/hystrix/info/timeout/1

Eureka7001注册中心:

http://eureka7001.cn:7001/

出现红字警告:

RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.

发现没有服务实例注册到Eureka中...

原因是因为8001没有更改为True

server:
  port: 8001

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

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

这样Hystrix工程搭建完成了

 

posted @ 2020-10-05 09:31  emdzz  阅读(133)  评论(0)    收藏  举报