我是靠谱客的博主 怡然大象,最近开发中收集的这篇文章主要介绍SpingCloud 2020微服务教程【27】Hystrix微服务搭建及服务降级,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

视频链接:2020最新版SpringCloud框架开发教程-周阳
文章源码:https://github.com/geyiwei-suzhou/cloud2020/

cloud-eureka-server7001模块

将Eureka服务改为单机版,修改yml配置文件

defaultZone: http://eureka7001.com:7001/eureka/

cloud-provider-hystrix-payment8001模块

1. 建module

New --> Module --> Maven[Module SDK:1.8.0_191] --> name[cloud-provider-hystrix-payment8001] --> Finish

2. 改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.antherd.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>

  <artifactId>cloud-provider-hystrix-payment8001</artifactId>

  <dependencies>
    <!-- hystrix -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hystrix</artifactId>
      <version>1.4.7.RELEASE</version>
    </dependency>
    <!--eureka client-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--引入公共api包-->
    <dependency>
      <groupId>com.antherd.springcloud</groupId>
      <artifactId>cloud-api-commons</artifactId>
      <version>${project.version}</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>
</project>

3. 写yml

server:
  port: 8001

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

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

4. 主启动
新建类:com.antherd.springcloud.PaymentHystrixMain8001

package com.antherd.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PaymentHystrixMain8001 {

  public static void main(String[] args) {

    SpringApplication.run(PaymentHystrixMain8001.class, args);
  }
}

新建类:com.antherd.srpingcloud.service.PaymentService

package com.antherd.springcloud.service;

import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Service;

@Service
public class PaymentService {

  public String paymentInfoOk(Integer id) {
    return "线程池:" + Thread.currentThread().getName() + " paymentInfoOk," + id + " O(∩_∩)O哈哈~";
  }

  public String paymentInfoTimeout(Integer id) {
    int timeNumber = 3;
    try {
      TimeUnit.SECONDS.sleep(timeNumber);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return "线程池:" + Thread.currentThread().getName() + " paymentInfoTimeout," + id + " ┭┮﹏┭┮" + " 耗时" + timeNumber + "秒钟";
  }
}

新建类:com.antherd.srpingcloud.contorller.PaymentController

package com.antherd.springcloud.controller;

import com.antherd.springcloud.service.PaymentService;
import javax.annotation.Resource;
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;

@RestController
@Slf4j
public class PaymentController {

  @Resource
  private PaymentService paymentService;

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

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

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

5. 启动测试

启动:cloud-eureka-server7001,cloud-provider-hystrix-payment8001两个模块

访问:http://localhost:8001/payment/hystrix/ok/1、http://localhost:8001/payment/hystrix/timeout/1 发现都可以正常访问

如果此时用jmeter对http://localhost:8001/payment/hystrix/timeout/1 进行100线程20次压测,会发现http://localhost:8001/payment/hystrix/ok/1的响应也会变慢。

ps:Tomecat默认线程量为10。

cloud-consumer-feign-hystrix-order80模块

1. 建module

New --> Module --> Maven[Module SDK:1.8.0_191] --> name[cloud-consumer-feign-hystrix-order80] --> Finish

2. 改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.antherd.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>

  <artifactId>cloud-consumer-feign-hystrix-order80</artifactId>

  <dependencies>
    <!-- openfeign -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
      <version>2.2.1.RELEASE</version>
    </dependency>
    <!--eureka client-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--引入公共api包-->
    <dependency>
      <groupId>com.antherd.springcloud</groupId>
      <artifactId>cloud-api-commons</artifactId>
      <version>${project.version}</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>
</project>

3. 写yml

server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

4. 主启动
新建类:com.antherd.springcloud.OrderHystrixMain80

package com.antherd.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class OrderHystrixMain80 {

  public static void main(String[] args) {

    SpringApplication.run(OrderHystrixMain80.class, args);
  }
}

新建类:com.antherd.srpingcloud.service.PaymentHystrixService

package com.antherd.springcloud.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@Component
@FeignClient("CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {

  @GetMapping("/payment/hystrix/ok/{id}")
  public String paymentInfoOk(@PathVariable("id") Integer id);

  @GetMapping("/payment/hystrix/timeout/{id}")
  public String paymentInfoTimeout(@PathVariable("id") Integer id);

}

新建类:com.antherd.srpingcloud.contorller.OrderHystrixController

package com.antherd.springcloud.controller;

import com.antherd.springcloud.service.PaymentHystrixService;
import javax.annotation.Resource;
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;

@RestController
@Slf4j
public class OrderHystrixController {

  @Resource
  private PaymentHystrixService paymentHystrixService;

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

  @GetMapping("/consumer/payment/hystrix/ok/{id}")
  public String paymentInfoOk(@PathVariable("id") Integer id) {
    String result = paymentHystrixService.paymentInfoOk(id);
    log.info("*****result***** : " + result);
    return result;
  }

  @GetMapping("/consumer//payment/hystrix/timeout/{id}")
  public String paymentInfoTimeout(@PathVariable("id") Integer id) {
    String result = paymentHystrixService.paymentInfoTimeout(id);
    log.info("*****result***** : " + result);
    return result;
  }
}

5. 启动测试

启动:cloud-eureka-server7001,cloud-provider-hystrix-payment8001,cloud-consumer-feign-hystrix-order80三个模块

访问:http://localhost/consumer/payment/hystrix/ok/1 发现可以正常访问、http://localhost/consumer/payment/hystrix/timeout/1 发现访问超时直接显示了报错页面

解决

对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)down机了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级

cloud-provider-hystrix-payment8001模块

设置自身调用超时时间的峰值(3s),峰值内可以正常运行,超过了需要兜底的方法处理,作服务降级fallback

修改com.antherd.springcloud.service.PaymentService.paymentInfoTimeout方法,处理时间改为5秒,同时添加fallback注解

@HystrixCommand(fallbackMethod = "paymentInfoTimeoutHandle", commandProperties = {
      @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
  })
public String paymentInfoTimeout(Integer id) {
  int timeNumber = 5;
  try {
    TimeUnit.SECONDS.sleep(timeNumber);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "线程池:" + Thread.currentThread().getName() + " id:" + id + " O(∩_∩)O哈哈~" + " 耗时" + timeNumber + "秒钟";
}

并且编写对应的fallback方法paymentInfoTimeoutHandle

public String paymentInfoTimeoutHandle(Integer id) {
    return "线程池:" + Thread.currentThread().getName() + " id:" + id + " 8001系统繁忙或运行报错,请稍后再试" + " ┭┮﹏┭┮";
}

在主启动类上添加注解激活服务降级

@EnableEurekaClient
@EnableCircuitBreaker

启动:cloud-eureka-server7001,cloud-provider-hystrix-payment8001两个模块

访问:http://localhost:8001/payment/hystrix/timeout/1 发现访问没有报错,等待3秒后执行paymentInfoTimeoutHandle方法并且返回结果

现在,我们在paymentInfoTimeout方法开始位置添加异常代码

int age = 10/0;

访问:http://localhost:8001/payment/hystrix/timeout/1 发现立刻执行paymentInfoTimeoutHandle方法并且返回结果,不会等待3秒超时

cloud-consumer-feign-hystrix-order80模块

pom文件中添加Hystrix依赖

<!-- hystrix -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-hystrix</artifactId>
  <version>1.4.7.RELEASE</version>
</dependency>

修改application.yml配置,添加

ribbon:
  ConnectTimeout: 5000
  ReadTimeout: 5000

添加@EnableHystrix注解及对@HystrixCommand内属性的修改建议重启微服务,否则可能不生效

在启动类com.antherd.springcloud.OrderHystrixMain80上加上注解

@EnableHystrix

修改类:com.antherd.springcloud.controller.OrderHystrixController

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentInfoTimeoutHandle", commandProperties = {
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
public String paymentInfoTimeout(@PathVariable("id") Integer id) {
  return paymentHystrixService.paymentInfoTimeout(id);
}

public String paymentInfoTimeoutHandle(@PathVariable("id") Integer id) {
  return "我是消费者80,对方支付系统繁忙请10秒后再试或者自己运行出错请检查自己,┭┮﹏┭┮";
}

同时把8001模块com.antherd.springcloud.service.PaymentService.paymentInfoTimeout方法改为如下

@HystrixCommand(fallbackMethod = "paymentInfoTimeoutHandle", commandProperties = {
      @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
})
public String paymentInfoTimeout(Integer id) {
  // int age = 10/0;
  int timeNumber = 3;
  try {
    TimeUnit.SECONDS.sleep(timeNumber);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "线程池:" + Thread.currentThread().getName() + " id:" + id + " O(∩_∩)O哈哈~" + " 耗时" + timeNumber + "秒钟";
}

访问:http://localhost/consumer/payment/hystrix/timeout/1,发现消费侧启动了服务降级。然后把com.antherd.springcloud.controller.OrderHystrixController.paymentInfoTimeout 的服务降级时间改为4秒,发现可以正常访问接口。

最后

以上就是怡然大象为你收集整理的SpingCloud 2020微服务教程【27】Hystrix微服务搭建及服务降级的全部内容,希望文章能够帮你解决SpingCloud 2020微服务教程【27】Hystrix微服务搭建及服务降级所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部