Spring Cloud 之 Feign,Hystrix 和 Gateway

2022-07-07 09:09:11

Feign声明式服务调用

Feign概述

• Feign 是一个声明式的 REST 客户端,它用了基于接口的注解方式,很方便实现客户端配置。
• Feign 最初由 Netflix 公司提供,但不支持SpringMVC注解,后由SpringCloud 对其封装,支持了SpringMVC注 解,让使用者更易于接受。

  • Feign自动集成Ribbon,且默认开启相关功能
  • Feign自动集成Hystrix,但默认关闭,需要手动开启

Feign 快速入门

  1. 在消费端引入 open-feign 依赖
  2. 编写Feign调用接口
  3. 在启动类 添加 @EnableFeignClients 注解,开启Feign功能
  4. 测试调用

Feign依赖:

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

Feign调用接口:

package com.itheima.consumer.feign;import com.itheima.consumer.FeignLogConfig;import com.itheima.consumer.domain.Goods;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;/**
 * feign声明式接口,发起远程调用
 * String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
 * Goods goods = restTemplate.getForObject(url, Goods.class);
 *
 * 1.定义接口
 * 2.接口上添加注解,@FeignClient,设置属性为 服务提供者的 应用名称,日志级别配置类
 * 3.编写调用接口,接口的声明规则和提供方接口保持一致
 * 4.注入该接口,调用接口方法完成远程调用
 */@FeignClient(value="FEIGN-PROVIDER",configuration= FeignLogConfig.class)publicinterfaceGoodsFeignClient{@GetMapping("/goods/findOne/{id}")public GoodsfindGoodsById(@PathVariable("id")int id);}
package com.itheima.consumer.controller;import com.itheima.consumer.domain.Goods;import com.itheima.consumer.feign.GoodsFeignClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@RequestMapping("/order")publicclassOrderController{@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate GoodsFeignClient goodsFeignClient;@GetMapping("/goods/{id}")public GoodsfindGoodsById(@PathVariable("id")int id){
        
        Goods goods= goodsFeignClient.findGoodsById(id);return goods;}}

启动类 开启Feign功能

package com.itheima.consumer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;@EnableDiscoveryClient// 激活DiscoveryClient@EnableEurekaClient@SpringBootApplication@EnableFeignClients//开启Feign功能publicclassConsumerApp{publicstaticvoidmain(String[] args){
        SpringApplication.run(ConsumerApp.class,args);}}

Feign - 超时设置

服务调用方配置
• Feign 底层依赖于 Ribbon 实现负载均衡和远程调用。
• Ribbon默认1秒超时。
• 超时配置:
在这里插入图片描述

Feign - 日志记录

开启SpringBoot框架的debug日志

  • 开启全部
# 设置当前的日志级别 debug,feign只支持记录debug级别的日志logging:level:root: debug
  • 开启部分
logging:level:com.itheima: debug

服务调用方配置
• Feign 只能记录 debug 级别的日志信息。
在这里插入图片描述

• 定义Feign日志级别Bean

服务调用方根包下定义日志级别

package com.itheima.consumer;import feign.Logger;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@ConfigurationpublicclassFeignLogConfig{/**
     * NONE:不记录
     * BASIC:记录基本的请求行,响应状态码数据
     * HEADERS:记录基本的请求行,响应状态码,记录响应头信息
     * FULL:记录完整的请求 响应数据
     * @return
     */@Beanpublic Logger.Leveldebug(){return Logger.Level.FULL;}}

• 启用该Bean:
@FeignClient(configuration = XxxConfig.class)

package com.itheima.consumer.feign;import com.itheima.consumer.FeignLogConfig;import com.itheima.consumer.domain.Goods;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;/**
 * feign声明式接口,发起远程调用
 * String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
 * Goods goods = restTemplate.getForObject(url, Goods.class);
 *
 * 1.定义接口
 * 2.接口上添加注解,@FeignClient,设置属性为 服务提供者的 应用名称,日志级别配置类
 * 3.编写调用接口,接口的声明规则和提供方接口保持一致
 * 4.注入该接口,调用接口方法完成远程调用
 */@FeignClient(value="FEIGN-PROVIDER",configuration= FeignLogConfig.class)publicinterfaceGoodsFeignClient{@GetMapping("/goods/findOne/{id}")public GoodsfindGoodsById(@PathVariable("id")int id);}

Hystrix 熔断器

Hystrix 概述

• Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。

Hystix 主要功能

  • 隔离:用于隔离不同调用链之间相互不受影响
    1.线程池隔离
    2.信号量隔离
  • 降级:封装友好的错误提示并返回
    1.异常
    2.超时
  • 熔断:当请求错误率较高时,自动降级熔断
  • 限流:合理分配每个调用的并发请求数量

在这里插入图片描述

Hystrix 降级

• Hystix 降级:当服务发生异常或调用超时,返回默认数据
在这里插入图片描述

Hystrix 降级 - 服务提供方

  1. 在服务提供方,引入 hystrix 依赖
  2. 定义降级方法
  3. 使用 @HystrixCommand 注解配置降级方法
  4. 在启动类上开启Hystrix功能:@EnableCircuitBreaker
package com.itheima.provider.controller;import com.itheima.provider.domain.Goods;import com.itheima.provider.service.GoodsService;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;import org.springframework.beans.factory.annotation.Autowired;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.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Date;/**
 * Goods Controller 服务提供方
 */@RestController@RequestMapping("/goods")publicclassGoodsController{@Autowiredprivate GoodsService goodsService;@Value("${server.port}")privateint port;/**
     * 降级
     * 1.出现异常
     * 2.服务器调用超时
     * @param id
     * @return
     */@GetMapping("/findOne/{id}")//指定降级后调用的方法名称@HystrixCommand(fallbackMethod="findOne_fallback",commandProperties={//设置hystrix的超时时间,默认1秒@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")})public GoodsfindOne(@PathVariable("id")int id){int i=1/0;try{
            Thread.sleep(2000);}catch(InterruptedException e){
            e.printStackTrace();}
        Goods goods= goodsService.findOne(id);

        goods.setTitle(goods.getTitle()+":"+ port);//将端口号,设置到了 商品标题上return goods;}/**
     * 定义降级方法:
     * 返回值,参数和原方法一致
     */public GoodsfindOne_fallback(int id){
        Goods goods=newGoods();
        goods.setTitle("降级了.....");return goods;}}

Hystrix 降级 - 服务消费方

  1. feign 组件已经集成了hystrix 组件。
  2. 定义feign 调用接口实现类,复写方法,即 降级方法
  3. 在 @FeignClient 注解中使用 fallback 属性设置降级处理类。
  4. 配置开启 feign.hystrix.enabled = true

在这里插入图片描述

package com.itheima.consumer.feign;import com.itheima.consumer.domain.Goods;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;@FeignClient(value="HYSTRIX-PROVIDER",fallback= GoodsFeignClientFallback.class)publicinterfaceGoodsFeignClient{@GetMapping("/goods/findOne/{id}")public GoodsfindGoodsById(@PathVariable("id")int id);}
package com.itheima.consumer.feign;import com.itheima.consumer.domain.Goods;import org.springframework.stereotype.Component;/**
 * feign的客户端降级处理类
 * 1.定义类:实现feign客户端接口
 * 2.使用@Component注解将该类的Bean加入到Spring中
 */@ComponentpublicclassGoodsFeignClientFallbackimplementsGoodsFeignClient{@Overridepublic GoodsfindGoodsById(int id){
        Goods goods=newGoods();
        goods.setTitle("又降级了...");return goods;}}
# 开启feign对hystrix的支持feign:hystrix:enabled:true

Hystrix 熔断

• Hystrix 熔断机制,用于监控微服务调用情况,当失 败的情况达到预定的阈值(5秒失败20次),会打开 断路器,拒绝所有请求,直到服务恢复正常为止。
• circuitBreaker.sleepWindowInMilliseconds:监控时间
• circuitBreaker.requestVolumeThreshold:失败次数
• circuitBreaker.errorThresholdPercentage:失败率
在这里插入图片描述
在这里插入图片描述

Gateway 网关

网关概述

在这里插入图片描述

Gateway 网关快速入门

  1. 搭建网关模块
  2. 引入依赖:starter-gateway
  3. 编写启动类
  4. 编写配置文件
  5. 启动测试

依赖:

<!--引入gateway网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>

配置文件:

server:port:80spring:application:name: api-gateway-servercloud:# 网关配置gateway:# 路由配置:转发规则routes:#集合#id:唯一标识,默认是一个uuid#uri:转发路径#predicates:条件,用于请求网关路径的匹配规则-id: gateway-provider# uri: http://localhost:8001/uri: lb://GATEWAY-PROVIDERpredicates:- Path=/goods/**filters:- AddRequestParameter=username,zhangsan-id: gateway-consumer# uri: http://localhost:9000/uri: lb://GATEWAY-CONSUMERpredicates:- Path=/order/**discovery:locator:enabled:true# 设置为true,请求路径前可以加微服务名称lower-case-service-id:true# 允许小写eureka:client:service-url:defealtZone: http://localhost:8761/eureka

Gateway 网关路由配置

uri:
静态路由:http://locathost:8080/
动态路由:lb://服务名称

Gataway 过滤器

在这里插入图片描述

Gateway 过滤器 – 局部过滤器

在这里插入图片描述

Gateway 过滤器 – 全局过滤器

在这里插入图片描述
自定义全局过滤器

package com.itheima.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;@ComponentpublicclassMyFilterimplementsGlobalFilter, Ordered{@Overridepublic Mono<Void>filter(ServerWebExchange exchange, GatewayFilterChain chain){

        System.out.println("自定义全局过滤器执行了...");return chain.filter(exchange);//放行}/**
     * 过滤器排序
     * @return 数值越小,越先执行
     */@OverridepublicintgetOrder(){return0;}}
  • 作者:熊熊fire
  • 原文链接:https://blog.csdn.net/xglfire/article/details/108303795
    更新时间:2022-07-07 09:09:11