欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot+nacos+openfeign日志记录+openfeign降级+服务端降级(Hystrix降级)

程序员文章站 2024-03-20 23:28:04
...

前言:

上一篇文章 openfeign 远程调用+openfeign超时设置+负载均衡

openfeign日志记录

openfeign 只能记录 debug 级别的日志信息
所以先设置项目的日志记录,关于项目的日志记录,这里自行百度。

关于一些细节问题,查看我以前写的文章
https://blog.csdn.net/weixin_44865916/article/details/115465002
https://blog.csdn.net/weixin_44865916/article/details/115477784

我使用的springboot框架自带的默认配置:
application.yml:

# 设置当前的日志级别 debug,feign只支持记录debug级别的日志
logging:
  level:
  	# 添加自己的包名路径
    com.cyj.nacosconsumer: debug
@Configuration
public class FeignLogConfig {
    /**
     * NONE,不记录
     * ASIC,记录基本的请求行,响应状态码数据
     * HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
     * FULL;记录完成的请求 响应数据
     * @return
     */
    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}
/**
 * @description: feign声明式接口, 发起远程调用的
 * 接口上添加注解 @FeignClient
 * 设置value属性为 服务提供者的 应用名称
 * 设置configuration属性为  feign的  配置 比如日志记录
 * 编写调用接口,接口的声明规则 和 提供方接口保持一致
 * @Author C_Y_J
 * @create 2021-03-29 10:34
 **/
@FeignClient(
        value = "nacos-provider",//服务名
        configuration = FeignLogConfig.class//配置类
)
@Component
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne3")
    Goods findGoodsById3();

}

日志输出:

2021-04-07 11:02:36.161 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] ---> GET http://nacos-provider/goods/findOne3 HTTP/1.1
2021-04-07 11:02:36.161 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] ---> END HTTP (0-byte body)
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] <--- HTTP/1.1 200 (2018ms)
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] connection: keep-alive
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] content-type: application/json;charset=UTF-8
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] date: Wed, 07 Apr 2021 03:02:38 GMT
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] keep-alive: timeout=60
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] transfer-encoding: chunked
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] 
2021-04-07 11:02:38.179 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] {"id":1,"title":"标题:8010","price":123.123,"count":1200}
2021-04-07 11:02:38.180 DEBUG 19632 --- [nio-9000-exec-2] c.c.n.feign.GoodsFeignClient             : [GoodsFeignClient#findGoodsById3] <--- END HTTP (59-byte body)

openfeign降级

关于一些细节问题,查看我以前写的文章
https://blog.csdn.net/weixin_44865916/article/details/115465002
https://blog.csdn.net/weixin_44865916/article/details/115477784

  1. openfeign 组件已经集成了 hystrix 组件。
  2. 定义feign 调用接口实现类,复写方法,即 降级方法。
/**
 * @description: feign声明式接口, 发起远程调用的
 * 接口上添加注解 @FeignClient
 * 设置value属性为 服务提供者的 应用名称
 * 设置configuration属性为  feign的  配置 比如日志记录
 * 设置fallback属性为  feign的  Hystix降级方案   *** 配置开启 feign.hystrix.enabled = true ***
 * 编写调用接口,接口的声明规则 和 提供方接口保持一致
 * @Author C_Y_J
 * @create 2021-03-29 10:34
 **/
@FeignClient(
        value = "nacos-provider",//服务名
        configuration = FeignLogConfig.class,//配置类
        fallback = GoodsFeignClientFallback.class //消费端 降级方案
)
@Component
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne3")
    Goods findGoodsById3();

    @GetMapping("/goods/findOne4")
    Goods findGoodsById4();

}
/**
 * @description:
 * @Author C_Y_J
 * @create 2021-03-29 10:34
 **/
@Component
public class GoodsFeignClientFallback implements GoodsFeignClient {

    @Override
    public Goods findGoodsById3() {
        return new Goods().setTitle("因为服务端延迟,消费端自动降级");
    }

    @Override
    public Goods findGoodsById4() {
        return new Goods().setTitle("因为服务端异常,消费端自动降级");
    }
}

配置开启 feign.hystrix.enabled = true:

feign:
  #开启feign对hystrix的支持 默认是关闭
  hystrix:
    enabled: true

服务端(Provider)模块:

关于一些细节问题,查看我以前写的文章
https://blog.csdn.net/weixin_44865916/article/details/115465002
https://blog.csdn.net/weixin_44865916/article/details/115477784

/**
 * @description:
 * @Author C_Y_J
 * @create 2021-03-29 11:04
 **/
@RestController
@RequestMapping("/goods")
public class GoodsController {

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

    /**
     * ======================================================================================================
     * 下面的不在服务提供方进行降级,在消费方进行降级。
     */

    @GetMapping("/findOne3")
    public Goods findGoodsById3() {
        //当前线程睡2秒
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("标题");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }

    @GetMapping("/findOne4")
    public Goods findGoodsById4() {
        int i = 1 / 0;
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("标题");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }
}

测试:

你会发现访问:localhost:9000/order/goods3,会出现"因为服务端延迟,消费端自动降级"
你会觉得疑惑:已经配置openfeign中ribbon的超时时间,怎么还会降级呢?

原因是没有设置:Hystrix超时时长
这也算我给你们挖的坑。

解决方案:

# 开启Feign的Hystrix开关
feign:
  #开启feign对hystrix的支持 默认是关闭
  hystrix:
    enabled: true
# 设置Hystrix超时时长
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000
            
# 配置openfeign中ribbon的连接时长和服务响应时长
ribbon:
  #请求连接的超时时间,默认一秒,默认毫秒值
  ConnectTimeout: 3000
  #请求处理的超时时间,默认一秒,默认毫秒值
  ReadTimeout: 3000

服务端降级(Hystrix降级)

关于一些细节问题,查看我以前写的文章
https://blog.csdn.net/weixin_44865916/article/details/115465002
https://blog.csdn.net/weixin_44865916/article/details/115477784

 <!-- 服务端 hystrix 熔断 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
@RestController
@RequestMapping("/goods")
public class GoodsController {

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

    /**
     * fallbackMethod:指定降级后调用的方法名称
     * commandProperties 设置Hystrix的超时时间,默认1s
     * 在启动类上开启Hystrix功能:@EnableCircuitBreaker
     *
     * @return
     */
    @GetMapping("/findOne")
    @HystrixCommand(fallbackMethod = "findGoodsById_fallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
    })
    public Goods findGoodsById() {
        //当前线程睡2秒
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            System.out.println("当前线程睡2秒");
        }
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("标题");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }

    public Goods findGoodsById_fallback() {
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("因为服务端延迟,服务端自动降级");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }

    @GetMapping("/findOne2")
    @HystrixCommand(fallbackMethod = "findGoodsById2_fallback")
    public Goods findGoodsById2() {
        int i = 1 / 0;
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("标题");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }

    public Goods findGoodsById2_fallback() {
        Goods goods = new Goods().setId(1).setPrice(123.123).setCount(1200).setTitle("因为服务端异常,服务端自动降级");
        return goods.setTitle(goods.getTitle() + ":" + port);
    }

}

消费端(Consumer)模块:

/**
 * @description: feign声明式接口, 发起远程调用的
 * 接口上添加注解 @FeignClient
 * 设置value属性为 服务提供者的 应用名称
 * 设置configuration属性为  feign的  配置 比如日志记录
 * 设置fallback属性为  feign的  Hystix降级方案   *** 配置开启 feign.hystrix.enabled = true ***
 * 编写调用接口,接口的声明规则 和 提供方接口保持一致
 * @Author C_Y_J
 * @create 2021-03-29 10:34
 **/
@FeignClient(
        value = "nacos-provider",//服务名
        configuration = FeignLogConfig.class,//配置类
        fallback = GoodsFeignClientFallback.class //消费端 降级方案
)
@Component
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne")
    Goods findGoodsById();

    @GetMapping("/goods/findOne2")
    Goods findGoodsById2();

}
/**
 * @description:
 * @Author C_Y_J
 * @create 2021-03-29 10:34
 **/
@Component
public class GoodsFeignClientFallback implements GoodsFeignClient {

    @Override
    public Goods findGoodsById() {
        return new Goods().setTitle("虽然因为服务端延迟,并且服务端配置降级方案,优先以使用服务端的降级方案," +
                "如果消费端的的ribbon和hystrix的超时时长短于服务端的处理时长,那么优先使用消费端降级方法");
    }

    @Override
    public Goods findGoodsById2() {
        return new Goods().setTitle("虽然因为服务端异常,并且服务端配置降级方案,但是不会优先以使用消费端的降级方案");
    }

}

总结:

openfeign降级

1. openfeign 组件已经集成了 hystrix 组件。

2. 定义feign 调用接口实现类,复写方法,即 降级方法。

3. 设置fallback属性为  feign的 Hystix降级方案 。

4. 配置开启 feign.hystrix.enabled = true 

5. 同时在消费端这边配置ribbon的超时时长和Hystrix超时时长

6. 如果消费端的的ribbon和hystrix的超时时长短于服务端的处理时长,那么优先使用消费端降级方法

服务端降级

7. 导入依赖:spring-cloud-starter-netflix-hystrix

8. 定义降级方法: 方法的返回值需要和原方法一样,方法的参数需要和原方法一样

9. 使用 @HystrixCommand 注解配置降级方法

10. @HystrixCommand(fallbackMethod = "findOne_fallback")  
   fallbackMethod:指定降级后调用的方法名称

11. commandProperties 设置Hystrix的超时时间,默认1s

12. 在启动类上开启Hystrix功能:@EnableCircuitBreaker

13. 如果消费端的的ribbon和hystrix的超时时长短于服务端的处理时长,那么优先使用消费端降级方法