文章目录

  • 1.环境准备
  • 2.简单使用
  • 2.1用户服务修改(服务调用者)
  • 2.1.1 pom.xml
  • 2.1.2 启动类
  • 2.1.3 Fegin接口编写
  • 2.1.4 服务调用者controller
  • 2.2 启动服务并测试
  • 3.负载均衡配置
  • 4.熔断器配置
  • 4.1 服务调用者改造
  • 4.1.1 配置类开启熔断器
  • 4.1.2 服务降级
  • 4.2 重启服务测试
  • 5.压缩配置
  • 6.日志配置
  • 6.1 配置Fegin日志
  • 6.2 log日志配置
  • 6.3 重启测试


1.环境准备

这里我们继续学习SpringCloud中的Feign组件,我们这里强烈建议使用《SpringCloud之Hystrix使用高级篇》中的环境
1.首先我这里有spring-cloud-parent pom工程
2.spring-cloud-eureka-server Eureka Server 子工程 这里端口我们使用90开头
我们这里集群由两个服务实例组成,分别是9090与9091端口
3.spring-cloud-user-service-consumer 用户服务 (也就是咱们的服务消费者)这里端口我们使用80 开头 ,
我们这个用户服务现在这里有两个实例,分别是8080与8081
4.spring-cloud-order-service-provider 订单提供服务 (服务提供者) 这里端口我们使用70开头
我们订单服务提供着也由两个实例组成,分别是7070与7071
如果不想使用该环境,可以根据架构图来搭建自己的环境,这里我使用的spring-cloud版本是Greenwich.RELEASE。

2.简单使用

我们都知道,Fegin这个组件内部是 RestTemplate+Ribbon+Hystrix组成的,我们在使用Fegin的时候就可以将之前添加Hystrix依赖给去掉了,接下来我们就简单使用一下Fegin

2.1用户服务修改(服务调用者)

使用Fegin主要是需要我们的服务调用者,也就是服务消费者项目,在这里是spring-cloud-user-service-consumer项目。

2.1.1 pom.xml

首先我们需要在项目的pom.xml中引入Fegin的相关依赖

<!--添加Fegin依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

如果我们服务中引入了Hystrix的相关依赖,这个需要去掉或者注释掉,因为我们Fegin的依赖中会自动引入。

2.1.2 启动类

我们需要在服务提供者的主启动类添加@EnableFeignClients 注解,表示开启Fegin,当然,如果我们主启动类上面有有关于熔断器的注解可以注释掉。

springcloud拆分服务 springcloud使用fegin_springcloud


还有之前咱们写的RestTemplateConfiguration 配置类这个是需要留着的。

@Configuration
public class RestTemplateConfiguration {
    @Bean
    public RestTemplate getRestTemplate(){
        return  new RestTemplate();
    }
}
2.1.3 Fegin接口编写

这里我们在服务调用者新建一个service包,然后根据服务提供者的接口,写了一个FeginClient接口,这里可以直接将 服务提供者接口controller中的method 搬过来,然后去掉方法体就可以了

@FeignClient(name = "spring-cloud-order-service-provider") // 这里这个name 需要填写 请求的服务提供者的注册到Eureka Server上面的服务名
@RequestMapping("/order/data")  // 这里你服务提供者接口controller 啥样 可以照着搬过来,当然也可以写到FeignClient注解的path属性上。
public interface OrderStatisticFeginClient {
    // 请求路径,FeginClient增加了对Springmvc的支持,所以可以直接将服务提供者接口controller 方法搬过来,然后去掉方法体
    @GetMapping("/getTodayFinishOrderNum/{id}")
    public Integer getTodayFinishOrderNum(@PathVariable("id") Integer id);
    
}
2.1.4 服务调用者controller

这里我们需要对UserCenterController做改造,当然也可以新写一个。如果用之前的UserCenterController 就需要将之前的Hystrix的一些注释掉。我们的controller只需要注入咱们上面写的Fegin Client接口,然后调用就可以了,下面提供了完整的UserCenterController代码。

@RestController
@RequestMapping("/user/data")
public class UserCenterController {

	// 注入咱们的Fegin Client接口
    @Autowired
    private OrderStatisticFeginClient orderStatisticFeginClient;
    @GetMapping("/getTodayStatistic/{id}")
    public Integer getTodayStatistic(@PathVariable("id") Integer id){
    	// 直接调用
        Integer todayFinishOrderNum = orderStatisticFeginClient.getTodayFinishOrderNum(id);
        return todayFinishOrderNum;
    }

}
2.2 启动服务并测试

这里附上服务提供者也就是我们的订单服务controller代码

@RestController
@RequestMapping("/order/data")
public class OrderStatisticServiceController {
    @Value("${server.port}")
    private Integer port;
    /**
     * 根据用户id获取今日完单数
     * @param id 用户ID
     * @return  完单数
     */
    @GetMapping("/getTodayFinishOrderNum/{id}")
    public Integer getTodayFinishOrderNum(@PathVariable("id") Integer id){
        return port;
    }
}

这里我们需要把Eureka Server 提起来分别是9090 与9091端口,然后将我们的两个服务提供者实例提起来分别是7070 与7071端口,最后将服务调用者提起来,这里我们这里提一个就可以了8080端口。

springcloud拆分服务 springcloud使用fegin_服务调用_02

我们可以看到服务都起来了,然后接着浏览器输入http://127.0.0.1:8080/user/data/getTodayStatistic/100 调用接口测试。我们可以看到已经可以调通了

springcloud拆分服务 springcloud使用fegin_fegin_03

3.负载均衡配置

我们知道Fegin里面整合了Ribbon,然后我们就可以通过个性化配置来使用Ribbon的一些特性,我们的Fegin调用默认超时时间是1秒,但是有些很复杂的业务处理往往要高于1秒的,这时候可以设置Ribbon的超时时间,然后Fegin就会以Ribbon的超时时间为准了。
我们需要在项目的配置文件(application.yml)中添加关于Ribbon的配置

# 单独对这个spring-cloud-order-service-provider 服务的调用生效,如果想配置全局生效的话可以不用写这个服务名,
spring-cloud-order-service-provider:
  ribbon:
  	# 这个是连接超时时间
    ConnectTimeout: 1000
    # 这个是服务处理请求超时时间
    ReadTimeout: 5000
    # 对所有的操作进行重试工作
    OkToRetryOnAllOperations: true
    # 当超时的时候,最大重试次数,这里是设置了3次,不包含第一次请求那次 ,这个请求重试是在超时服务上试
    MaxAutoRetries: 2 
    # 如果在调用当前服务重试次数没了,就换个服务
    MaxAutoRetriesNextServer: 1 
    #负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

为了演示方便我们需要修改下服务提供者的接口代码,需要将7070端口的sheep 10s ,7071端口的服务不变。

@GetMapping("/getTodayFinishOrderNum/{id}")
 public Integer getTodayFinishOrderNum(@PathVariable("id") Integer id){
       System.out.println("我是"+port);
       if (port==7070){
           try {// 睡眠10s
               Thread.sleep(10000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
       return port;
}

重启服务提供者与服务消费者服务并测试

我这里第一次调用访问到了7071,然后我又调用了一次

springcloud拆分服务 springcloud使用fegin_服务调用_04


我们可以看到在7070 访问了3次,1次是我手动调用,然后2次是超时重试,再来看下7071的日志信息

springcloud拆分服务 springcloud使用fegin_springcloud_05


7071 第一次是我手动调用的,然后第2次是重试完7070服务还不行,然后访问的7071。从接口调用返回的结果也是这样的

springcloud拆分服务 springcloud使用fegin_springcloud拆分服务_06

4.熔断器配置

Fegin也是集成了咱们熔断器,接下来我们就看看对于熔断器的配置

4.1 服务调用者改造
4.1.1 配置类开启熔断器

我们需要在项目配置类appliaction.yml 中开启对熔断器的支持

# 开启Fegin对熔断器的支持
feign:
  hystrix:
    enabled: true

接着配置熔断器的一些参数,其实这里熔断器的一些参数还跟咱们之前Hystirx学习中配置文件配置一样
我们这里配置一个熔断器的超时时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            # 配置熔断器的超时时间,我这里配置了12s
            timeoutInMilliseconds: 12000

当我们开启熔断器后,Fegin里面的方法都会被进行管理,一旦出现熔断,就会服务降级,也就是执行咱们的服务降级方法fallback方法。
下面我们需要编写fallback处理。

4.1.2 服务降级

我们需要写一个对应的服务降级处理类,也就是我们fallback类,这里需要实现Fegin调用接口就可以了

@Component  // 将该fallback类交由给Spring管理
public class OrderStatisticFeginClientFallback  implements OrderStatisticFeginClient {
    // fallback 处理逻辑
    @Override
    public Integer getTodayFinishOrderNum(Integer id) {
        return -1;
    }
}

其实这里我们还需要改一下 Fegin调用接口,这里也就是OrderStatisticFeginClient ,需要把接口上面的@RequestMapping("/order/data") 这个注解值放到 @FeignClient注解的path属性中

@FeignClient(name = "spring-cloud-order-service-provider",path = "/order/data",fallback = OrderStatisticFeginClientFallback.class)
//@RequestMapping("/order/data")// 这里你服务提供者接口controller 啥样 可以照着搬过来,当然也可以写到FeignClient注解的path属性上。
public interface OrderStatisticFeginClient {
    // 请求路径,FeginClient增加了对Springmvc的支持,所以可以直接将服务提供者接口controller 方法搬过来,然后去掉方法体
    @GetMapping("/getTodayFinishOrderNum/{id}")
    public Integer getTodayFinishOrderNum(@PathVariable("id") Integer id);

}
4.2 重启服务测试

这里我们需要修改下Ribbon的配置,不让它重试

# 单独对这个spring-cloud-order-service-provider 服务的调用生效,如果想配置全局生效的话可以不用写这个服务名,
spring-cloud-order-service-provider:
  ribbon:
  	# 这个是连接超时时间
    ConnectTimeout: 1000
    # 这个是服务处理请求超时时间
    ReadTimeout: 5000
    # 对所有的操作进行重试工作
    OkToRetryOnAllOperations: false
    # 当超时的时候,最大重试次数,这个请求重试是在超时服务上试 , 这里是设置了0次,就是不进行重试
    MaxAutoRetries: 0 
    # 如果在调用当前服务重试次数没了,就换个服务
    MaxAutoRetriesNextServer: 0 
    #负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

重启用户服务,也就是服务调用者服务。

postman发起请求

springcloud拆分服务 springcloud使用fegin_springcloud_07


我们可以看到5秒左右就发生了熔断,执行了咱们fallback方法。这是因为,当我们配置了Fegin超时时间 与Hystrix 超时时间时,熔断超时取的是最小的那个时间。

5.压缩配置

我们在使用Fegin的时候发起服务调用的时候,可以对请求与响应进行压缩,然后来减少网络通信的性能开销,我们可以通过配置就可以开启对请求与响应的压缩功能,需要我们在配置文件application.yml中添加如下配置:

feign:
  compression:
    request:
    	# 开启请求压缩功能
      enabled: true  
      #设置压缩的数据类型,此处也是默认值
      mime-types: text/html,application/xml,application/json
      # 设置什么时候触发压缩,当大小超过2048的时候 
      min-request-size: 2048
      # 开启响应压缩功能
    response: 
      enabled: true

6.日志配置

我们还可以通过配置开启Fegin的日志功能,这样就能够看到一些更细节的请求信息与响应信息。
我们要看到Fegin的日志信息需要2处配置,分别是Fegin自身日志 与 系统log的一个配置,开启Fegin日志功能

6.1 配置Fegin日志

开启Fegin自身日志需要我们使用配置类来配置

@Configuration
public class FeginLogConfiguration {
    @Bean
    public Logger.Level  feginLogLevel(){
        return Logger.Level.FULL;
    }
}

我们来看下Fegin log level 都有哪些

Logger.Level

解释

NONE

表示不显示任何日志,默认

BASIC

基本的日志,能够记录请求方法、URL、响应状态码以及执行时间 适用于生产

HEADERS

在BASIC级别的基础上记录请求和响应的header

FULL

全部日志,记录请求和响应的header、body和元数据 适用于开发

6.2 log日志配置

需要我们在配置文件application.yml中配置log日志

#Feign日志只会对日志级别为debug的做出响应
logging:
  level:
    com.xuzhaocai.consumer.service.OrderStatisticFeginClient: debug
6.3 重启测试

我们重启服务调用者服务

浏览器发起请求:http://127.0.0.1:8080/user/data/getTodayStatistic/100

查看服务调用者日志,我们就可以看到Fegin调用信息了

springcloud拆分服务 springcloud使用fegin_fegin_08