Spring Cloud完整组件搭建之路 第三篇 -OpenFeign、Hystrix整合

书接上回【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】,OpenFeignn和Ribbon的整合我们已经配置完了,这次来整合OpenFeignn和Hystrix。

SpringCloud配置系列目录:

【Spring Cloud完整组件搭建之路 第一篇-Eureka】
【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】
【Spring Cloud完整组件搭建之路 第三篇 -OpenFeign、Hystrix整合】
【Spring Cloud完整组件搭建之路 第四篇 -Zuul】
【Spring Cloud完整组件搭建之路 第五篇 -Spring Cloud Config】
【Spring Cloud完整组件搭建之路 总结篇】

前置知识

Hystrix作为SpringCloud的一个容错组件,用于隔离远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。主要有以下功能:

  1. 为系统提供保护机制。在依赖的服务出现高延迟或失败时,为系统提供保护和控制。
  2. 防止雪崩。
  3. 包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中运行。
  4. 跳闸机制:当某服务失败率达到一定的阈值时,Hystrix可以自动跳闸,停止请求该服务一段时间。
  5. 资源隔离:Hystrix为每个请求都的依赖都维护了一个线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。防止级联失败。线程池隔离的方式能防止因一个请求出现问题而影响其他请求。
  6. 快速失败:同时能快速恢复。不会真正的请求服务,发生异常再返回,而是不请求服务,直接失败。
  7. 监控:Hystrix可以实时监控运行指标和配置的变化,提供近实时的监控、报警、运维控制。
  8. 回退机制:fallback,当请求失败、超时、被拒绝,或当断路器被打开时,执行回退逻辑。回退逻辑我们自定义,提供服务降级。
  9. 自我修复:断路器打开一段时间后,会自动进入“半开”状态,可以进行打开,关闭,半开状态的转换。

引入依赖

在上一篇博客【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】中,我们在Eureka的消费者客户端使用了OpenFeign,所以这次添加Hystrx依赖也要在Eureka的消费者客户端添加。

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

配置文件修改

在Eureka的消费者客户端配置文件中添加如下配置:

feign:
  circuitbreaker:
    enabled: true

启动类添加注解

在Eureka的消费者客户端启动类添加注解

@EnableHystrix

OpenFeign和Hystrix整合有两种方式:

  1. 使用@FeignClient的fallback属性,使用统一的降级逻辑。
  2. 使用@FeignClient的fallbackFactory属性,根据不同的错误信息使用不同的降级逻辑。

使用fallback进行降级

修改测试方法

消费者客户端
修改测试接口类

在上一篇博客【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】中,我们创建了ConsumerInterface测试接口类,我们将其进行修改,修改后代码如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * 第一行的@FeignClient注解是写死url进行远程服务调用
 * 第二行的@FeignClient注解是通过eureka的app名称进行远程服务调用
 * 根据第一行注解,得知Feign可以脱离Eureka独立实现远程访问
 */
//@FeignClient(name="user-service", url = "http://localhost:7300")
@FeignClient(name="USER-PROVIDER" , fallback = UserProviderBack.class)
public interface ConsumerInterface{
    // 访问远端的/aliveGet地址
    @RequestMapping(value = "/aliveGet",method = RequestMethod.GET)
    public String aliveGet(@RequestParam("id") Integer id);
    @RequestMapping(value = "/noParamGet",method = RequestMethod.GET)
    public String noParamGet();
    // 访问远端的/alivePost地址
    @PostMapping("/alivePost")
    public String alivePost(@RequestBody Map<String, Object> map);
    // 访问远端的/alivePost地址
    @PostMapping("/alivePostParam")
    public String alivePostParam(@RequestParam Map<String, Object> map);
}

代码修改点:第二行的@FeignClient注解修改为:
@FeignClient(name="USER-PROVIDER" , fallback = UserProviderBack.class)
加了一个回退信息接收属性,所以我们新增一个回退信息接收类UserProviderBack

添加UserProviderBack回退信息接收类

此类需要添加@Component加载到IOC容器中。

import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class UserProviderBack implements ConsumerInterface {
    @Override
    public String aliveGet(Integer id) {
        return "访问失败,访问降级!!!";
    }

    @Override
    public String noParamGet() {
        return null;
    }

    @Override
    public String alivePost(Map<String, Object> map) {
        return null;
    }

    @Override
    public String alivePostParam(Map<String, Object> map) {
        return null;
    }
}

从代码中看出,如果OpenFeign调用aliveGet方法出现异常,那就进入UserProviderBack类的aliveGet方法,执行相应逻辑。

生产者客户端
修改测试类方法逻辑

在上一篇博客【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】创建的UserProviderController测试类中,加入异常代码,测试Hystrix,修改后代码如下:

import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

@RestController
public class UserProviderController {
    @Value("${server.port}")
    private String port;

    /**
     * 用于为consumer提供feign带参的get访问
     * @param id
     * @return
     */
    @RequestMapping(value = "/aliveGet",method = RequestMethod.GET)
    public String aliveGet(@RequestParam("id") Integer id){
    	int i = 1/0;
        return id + "---"+ port + "aliveGet";
    }

    /**
     * 用于为consumer提供feign带参的get访问
     * @return
     */
    @RequestMapping(value = "/noParamGet",method = RequestMethod.GET)
    public String noParamGet(){
        return port + "aliveGet";
    }

    /**
     * 用于为consumer提供feign带参的post访问
     * @param map
     * @return
     */
    @RequestMapping(value = "/alivePost",method = RequestMethod.POST)
    public String alivePost(@RequestBody Map<String,Object> map){
        return ToStringBuilder.reflectionToString(map) + "---"+ port + "alivePost";
    }

    /**
     * 用于为consumer提供feign带参的post访问
     * @param map
     * @return
     */
    @RequestMapping(value = "/alivePostParam",method = RequestMethod.POST)
    public String alivePostParam(@RequestParam Map<String,Object> map){
        return ToStringBuilder.reflectionToString(map) + "---"+ port + "alivePostParam";
    }
}

在aliveGet方法中加入算法异常代码。

OpenFeign/Hystrix整合测试

在这里插入图片描述
我只在其中一个生产者客户端添加了异常,他还是会有Ribbon负载均衡逻辑,访问其他有效生产者客户端。

使用fallbackFactory进行降级

修改测试方法

消费者客户端
修改测试接口类

对刚才fallback降级的ConsumerInterface测试接口类进行修改,修改后代码如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * 第一行的@FeignClient注解是写死url进行远程服务调用
 * 第二行的@FeignClient注解是通过eureka的app名称进行远程服务调用
 * 根据第一行注解,得知Feign可以脱离Eureka独立实现远程访问
 */
//@FeignClient(name="user-service", url = "http://localhost:7300")
@FeignClient(name="USER-PROVIDER" , 
	fallbackFactory = UserProviderFallBackFactory.class)
public interface ConsumerInterface{
    // 访问远端的/aliveGet地址
    @RequestMapping(value = "/aliveGet",method = RequestMethod.GET)
    public String aliveGet(@RequestParam("id") Integer id);
    @RequestMapping(value = "/noParamGet",method = RequestMethod.GET)
    public String noParamGet();
    // 访问远端的/alivePost地址
    @PostMapping("/alivePost")
    public String alivePost(@RequestBody Map<String, Object> map);
    // 访问远端的/alivePost地址
    @PostMapping("/alivePostParam")
    public String alivePostParam(@RequestParam Map<String, Object> map);
}

代码修改点:第二行的@FeignClient注解修改为:
@FeignClient(name="USER-PROVIDER" , fallbackFactory = UserProviderFallBackFactory.class)
加了一个回退信息接收工厂属性,所以我们新增一个回退信息接收工厂类UserProviderFallBackFactory

添加UserProviderFallBackFactory回退信息接收工厂类

此类需要添加@Component加载到IOC容器中。


import feign.FeignException;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class UserProviderFallBackFactory 
	implements FallbackFactory<ConsumerInterface> {
    @Override
    public ConsumerInterface create(Throwable cause) {
        return new ConsumerInterface() {
            @Override
            public String aliveGet(Integer id) {
                if(cause instanceof FeignException.InternalServerError){
                    return "invoke error promote 500!!!" 
                    + cause.getLocalizedMessage() + "        " 
                    + cause.getStackTrace() + "        " 
                    + ToStringBuilder.reflectionToString(cause);
                }
                return "invoke localhost error!!!" + cause.getLocalizedMessage();
            }

            @Override
            public String noParamGet() {
                return null;
            }

            @Override
            public String alivePost(Map<String, Object> map) {
                return null;
            }

            @Override
            public String alivePostParam(Map<String, Object> map) {
                return null;
            }
        };
    }
}

从代码中看出,如果OpenFeign调用aliveGet方法出现异常,那就进入UserProviderFallBackFactory类的create方法,传入异常对象,执行相应逻辑。

OpenFeign/Hystrix整合测试2

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值