springcloud(七) feign + Hystrix 整合 、

之前几章演示的熔断,降级 都是 RestTemplate + Ribbon 和 RestTemplate + Hystrix  ,但是在实际开发并不是这样,实际开发中都是 Feign 远程接口调用。

Feign + Hystrix 演示:

  eruka(略)

order 服务工程:

 

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">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tuling.cloud</groupId>
  <artifactId>microservice-consumer-order-feign-hystrix-fallback</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>07-ms-consumer-order-feign-hystrix-fallback</name>

  <!-- 引入spring boot的依赖 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>

    <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.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- feign 已经依赖hystrix core 包,并不像之前的restTemplate + hystrix 需要引入全部的jar <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

  </dependencies>

  <!-- 引入spring cloud的依赖 -->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

  

ConsumerOrderApplication_07 启动类

package com.jiagoushi.cloud.study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients    // feign-hystrix  支持, 不用在写@EnableCircuitBreaker
public class ConsumerOrderApplication_07 {

  public static void main(String[] args) {
    SpringApplication.run(ConsumerOrderApplication_07.class, args);
  }
}

 UserFeignClient接口:

package com.jiagoushi.cloud.study.user.feign;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.jiagoushi.cloud.study.user.entity.User;

/**
 * Feign的fallback测试
 * 使用@FeignClient的fallback属性指定回退类
 */
@FeignClient(name = "microservice-provider-user", fallback = FeignClientFallback.class /*, configuration = FeignDisableHystrixConfiguration.class 指定该类来设置禁用该接口的Hystrix*/)
public interface UserFeignClient {
  @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  public User findById(@PathVariable("id") Long id);
}

/**
 * 降级方法 FeignClientFallback 需实现Feign Client接口
 * FeignClientFallback也可以是class,没有区别
 * 不是每个接口都必须要有降级的。重要的方法才会有
 */
@Component
class FeignClientFallback implements UserFeignClient {
  @Override
  public User findById(Long id) {
    User user = new User();
    user.setId(-1L);
    user.setUsername("降级用户");
    return user;
  }
}
  • feign注解 configuration = FeignDisableHystrixConfiguration.class  标识该feign接口禁用Hystrix

FeignDisableHystrixConfiguration类:

package com.jiagoushi.cloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;  

import feign.Feign;  

/**   注意:该类不能被启动扫描到。不然就是全局设置。
 * 为Feign禁用Hystrix功能的配置类,可单独用在具体的Feign接口上
 *  为什么要禁用? 因为Hystrix在接口上做了很多封装,限制接口线程池10个,有熔断,降级等功能,
 *  有的接口不需要这么多功能所以要禁用
 */
@Configuration
public class FeignDisableHystrixConfiguration {

    FeignDisableHystrixConfiguration(){

    }
    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder() {
        return Feign.builder();
    }
}

  applcation.yml:

server:
  port: 9010
spring:
  application:
    name: microservice-consumer-order
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

# 开启feign支持hystrix,
# https://blog.csdn.net/mxmxz/article/details/84633098 这个链接关于feign+hystrix超时时间设置
# http://blog.java1234.com/blog/articles/440.html   这个链接关于feign+hystrix超时时间设置
feign:
  hystrix:
    enabled: true

#配置这个是无效的,因为feign 也有一个超时时间的设置,
#当然feign底层是 ribbon的封装,所以 直接配置ribbon,ribbon默认超时也是1秒。
#所以这里都是强制要求,ribbon的超时时间要大于hystrix的超时时间,
#否则 hystrix自定义的超时时间毫无意义。所以还得加个 ribbon超时时间设置
#hystrix:
#  command:
#    default:
#      execution:
#        isolation:
#          thread:
#            timeoutInMilliseconds: 3000
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000

# 解释一下:这种配置会出现这样的现象:
# order服务Feign调用user服务时,因为user睡眠4S,所以浏览器会一直转4s等待,这种情况只会等待三次,之后仍然继续
# 调用user服务时,Feign 直接降级,浏览器转的时间很短。说明被降级了服务器响应快。

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000  #feign整合hystrix 光设置Hystrix 超时没用的要配合ribbon超时
      circuitBreaker:
        requestVolumeThreshold: 3 #默认20 ,熔断的阈值,如何user服务报错满足3次,熔断器就会打开,就算order之后请求正确的数据也不行。
        sleepWindowInMilliseconds: 8000 #默认5S , 等5S之后熔断器会处于半开状态,然后下一次请求的正确和错误讲决定熔断器是否真的关闭和是否继续打开

# 说明:请务必注意,从Spring Cloud Dalston开始,Feign默认是不开启Hystrix的。
# 因此,如使用Dalston请务必额外设置属性:feign.hystrix.enabled=true,否则断路器不会生效。
# 而,Spring Cloud Angel/Brixton/Camden中,Feign默认都是开启Hystrix的。无需设置该属性。

  user服务工程:

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">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tuling.cloud</groupId>
  <artifactId>microservice-provider-user</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>07-provider-user</name>
  <!-- 引入spring boot的依赖 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

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

  </dependencies>

  <!-- 引入spring cloud的依赖 -->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

  application.yml:

server:
  port: 8010
spring:
  application:
    name: microservice-provider-user
  jpa:
    generate-ddl: false
    show-sql: true
    hibernate:
      ddl-auto: none
  datasource:                           # 指定数据源
    platform: h2                        # 指定数据源类型
    schema: classpath:schema.sql        # 指定h2数据库的建表脚本
    data: classpath:data.sql            # 指定h2数据库的数据脚本
logging:                                # 配置日志级别,让hibernate打印出执行的SQL
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

  UserComtroller:

package com.tuling.cloud.study.controller;

import java.util.Random;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.tuling.cloud.study.entity.User;
import com.tuling.cloud.study.repository.UserRepository;

@RestController
public class UserController {

  private final Logger logger = Logger.getLogger(getClass());

  @Autowired
  private UserRepository userRepository;
  @Autowired
  private Registration registration;

  @GetMapping("/{id}")
  public User findById(@PathVariable Long id) throws Exception {

          // 模拟hystrix 超时降级
          Thread.sleep(4000);

          //测试熔断,传入不存在的用户id模拟异常情况
	 /* if (id == 10) {
	    throw new NullPointerException();
	  }*/
	  logger.info("用户中心接口:查询用户"+ id +"信息");
	  User findOne = userRepository.findOne(id);
	  return findOne;
  }

  @GetMapping("/getIpAndPort")
  public String findById() {
	  return registration.getHost() + ":" + registration.getPort();
  }
}

  ProviderUserApplication类:

package com.tuling.cloud.study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class ProviderUserApplication {

  public static void main(String[] args) {
    SpringApplication.run(ProviderUserApplication.class, args);
  }
}

  当user服务sleep(4000) 效果图:

测试Hystrix 阈值设置3时把注释去掉:

原文地址:https://www.cnblogs.com/smallFishs/p/10698963.html

时间: 2024-10-03 14:41:54

springcloud(七) feign + Hystrix 整合 、的相关文章

spring Cloud中,解决Feign/Ribbon整合Hystrix第一次请求失败的问题?

Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题,要如何解决该问题呢? 造成该问题的原因 Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码.而首次请求往往会比较慢(因为Spring的懒加载机制,要实例化一些类),这个响应时间可能就大于1秒了.知道原因后,我们来总结一下解决方法.解决方案有三种,以feign为例. 方法一 1 hystrix.command.default.execution.iso

SpringCloud系列七:Hystrix 熔断机制(Hystrix基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)

1.概念:Hystrix 熔断机制 2.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的提供方出现了问题之后整个的程序将出现错误的信息显示,而这个时候如果不想出现这样的错误信息,而希望替换为一个错误时的内容. 一个服务挂了后续的服务跟着不能用了,这就是雪崩效应 对于熔断技术的实现需要考虑以下几种情况: · 出现错误之后可以 fallback 错误的处理信息: · 如果要结合 Feign

Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul)

Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul) 1.Eureka Eureka是Netflix的一个子模块,也是核心模块之一.Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移.服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了.功能类似于dubbo的注册中心,比如Zookeeper. Eureka包含两个组件:

基于springcloud搭建项目-Hystrix篇(五)

1.概述 (1).首先要知道分布式系统面临的问题复杂分布式体系结构中应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败 (2).服务雪崩 多个服务之间相互调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这既是所谓的“扇出”.如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的嗲用就会占用原来越多的系统资源,今儿引起系统崩溃,所谓的“雪崩效应”. (3).对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒

SpringCloud 进阶之Hystrix(断路器)

1. Hystrix 断路器 Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败, 比如超时,异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分 布式系统的弹性; "断路器"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方 返回一个符合预期的,可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就

SpringCloud中使用Hystrix

引言 一般而言,一个服务都是部署了多台机器的,那么在这种情况下,当其中一个服务挂了以后Hystrix是怎么处理的呢? 为了验证这个问题,我们准备两个服务:user-api 和 app-gateway,再加一个Eureka Server 服务搭建 2.1. 注册中心 关于这一部分,参见<SpringCloud学习笔记(1)--Eureka> 2.2. 服务提供方 复制代码<?xml version="1.0" encoding="UTF-8"?>

解决:SpringCloud中Feign支持GET请求POJO传参

在日常的开发中,当遇到一个请求需要传递多个参数时,我们习惯将参数封装到一个POJO对象中,已提高程序的可读性和简化编写.但是在使用SpringCloud时,Feign对SpringMVC注解支持并不完善,其中一点就是,当发送的GET请求携带多个参数时,不能使用POJO来封装参数,这个就比较蛋疼了.一种使之支持GET请求POJO传递参数的方法如下: 添加Maven依赖 <dependency> <groupId>org.springframework.cloud</groupI

springcloud(七,多个服务消费者配置,以及zuul网关案例)

spring cloud (一.服务注册demo_eureka) spring cloud (二.服务注册安全demo_eureka) spring cloud (三.服务提供者demo_provider) spring cloud (四.服务消费者demo_consumer) springcloud(五,多个服务注册中心eureka) springcloud(六,多个服务提供者) 多个服务消费者同上面的提供者和服务注册一样的哈,就是复制出来两个,把端口改一下即可 这里就不做截图了 直接开始zu

SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]

作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 前提:本篇是基于 SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习[1] 的修改与拓展 1.修改consumer的CenterFeign.java,把返回值全部设置为String /** * 是consumer调用provider(需要指定provider的名字) * 请求的清单列表:规定调用地址.参数.返回值 * 在正常走通的时候不走CenterFeignFallBack,当provider down