SpringCloud之Open Feign服务调用快速入门分析案例

Open Feign 是什么

官方文档 : Declarative REST Client: Feign

Feign 是声明性Web服务客户端。它使编写Web服务客户端更加容易。

要使用Feign,请创建一个接口并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。

Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并支持使用HttpMessageConvertersSpring Web中默认使用的注释。

Spring Cloud集成了Ribbon和Eureka以及Spring Cloud LoadBalancer,以在使用Feign时提供负载平衡的http客户端。

简言之

Feign可以进行远程服务调用
Feign 采用的是基于接口的注解
Feign 整合了ribbon,具有负载均衡的能力
Feign整合了Hystrix,具有熔断的能力


Open Feign实现服务调用

注册中心与服务提供者,请看之前的案例。

SpringCloud微服务概述及项目聚合实例之支付模块)

feign相当于一个客户端即(RestTemplate + Ribbon),所以我们只需要建立一个模块来封装这个客户端即可,也就相当于我们的消费者了

1、建Module

cloud-consumer-feign-order80

2、改pom

   <dependencies>
        <!--open feign整合包,feign中也包含了ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

        <!--删除掉entities后,将公用代码打包放到公共模块中,引入模块-->
        <dependency>
            <groupId>com.lejia.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

        <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.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

3、写yml

server:
  port: 80

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true     open feign作为客户端就不需要注册了
    register-with-eureka: false
    #是否从EurekaServe抓取已有的注册信息,默认为true
    # 单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      #      defaultZone: http://localhost:7001/eureka    单机版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
  instance:
    instance-id: order80
    prefer-ip-address: true     #默认false,显示IP地址

4、主启动

在主启动上添加注解@EnableFeignClients ,开启feign远程调用功能

@SpringBootApplication
@EnableFeignClients     //添加feign客户端
@EnableDiscoveryClient
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class,args);
    }
}

5、业务类

新建远程调用接口

package com.lejia.springcloud.service;

PaymentFeignService.java

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")	//关联到注册中心上需要调用的服务名称
public interface PaymentFeignService {
	
	//调用服务提供者所暴露出来的接口
    @GetMapping("/payment/get/{id}")
    public CommentResult<Payment> getPaymentById(@PathVariable("id") Long id);

}

新建业务层

package com.lejia.springcloud.controller;

OrderFeignController.class

@RestController
@Slf4j
@RequestMapping("/consumer/payment")
public class OrderFeignController {
	
	//feign服务接口
    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping("/feign/get/{id}")
    public CommentResult<Payment> paymentById(@PathVariable("id") Long id){
        return paymentFeignService.getPaymentById(id);
    }
}

6、项目结构图

image-20201203134550000

7、测试

在地址栏输入客户端所提供的接口

http://localhost/consumer/payment/get/1

我们发现Open Feign已经自动开启了负载均衡功能,并默认以轮询作为负载策略

image-20201208165003528

image-20201208165012199

image-20201208165029681

Open Feign实现其他负载均衡规则

我们在上面可以看出,OpenFeign默认集成了ribbon并且以轮询作为默认的负载规则现在我们尝试一下其他的负载策略

首先我们需要在主启动类的上一个文件夹下新建一个包
image-20201208170909745
新建一个负载IRule规则,将它声明为一个@Bean

package com.lejia.myrole;
@Configuration
public class MySelfRule {

    @Bean
    public IRule getIRule(){
        return new RandomRule();
    }

}

在主启动类上开启我们自定义的配置

//name为注册中心上服务提供者集群的名称,configuration为我们自定义的规则
@RibbonClient(name="CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderFeignMain80 {
}

再次启动重新测试,发现随机策略已经成功的配置了。

总结:

经过两种服务调用的测试(Open Feign)与(RestTemplate + Ribbon)我们可以发现,在一般的使用中,两者并没有太多的不同。

image-20201208171312082

image-20201208171402090

自定义策略可以查看以下博客或者自行查找ribbon官网文档

Open Feign超时调用测试

feign的超时调用时间默认为1s中。

当我们访问请求时,如果服务端的响应时间超过1秒以后,客户端直接会返回超时错误。

测试方法

1、在服务提供者8001/8002/8003中添加方法

目的是使请求在服务端响应3秒后再返回给客户端

@GetMapping("/payment/feign/timeout")
public String getPaymentFeignTimeout(){
    try {
        TimeUnit.SECONDS.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "调用的端口为"+serverPort;
}

2、将方法添加到80服务的feign访问接口中

package com.lejia.springcloud.service;
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
    @GetMapping("/payment/get/{id}")
    public CommentResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping("/payment/feign/timeout")
    public String getPaymentFeignTimeout();
}

3、暴露给用户的接口

package com.lejia.springcloud.controller;

public class OrderFeignController {
    ...
    @GetMapping("/feign/timeout")
    public String getPaymentTimeout(){
        return paymentFeignService.getPaymentFeignTimeout();
    }
}

4、测试

示例,服务端延时3秒响应,此时客户端响应一秒钟后就报超时错误

image-20201208172942149

5、解决feign超时连接问题

在80客户端的application.yml配置文件中设置feign的超时请求时间即可

# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  # 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
  # 指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

ps : 客户端经过设置最久等待时间为10s

此时,再次测试,客户端请求经过三秒后得到了服务器的响应

image-20201208173225872

Open Feign日志打印监控功能

Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。

总的来说就是对Feign接口的调用情况进行监控和输出

Feign日志级别

  • NONE : 默认的,不显示任何日志;
  • BASIC : 仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS : 除了BASIC中定义的信息之外,还有请求和响应的头信息;
  • FULL : 除了HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

配置详解

在客户端中添加配置类FeignConfig

package com.lejia.springcloud.config;

新建FeignConfig.class

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;		//Full级别
    }
}

image-20201208173642950

在yml中添加配置开启日志

logging:
  level:
    #Feign日志以什么级别监控那个接口
    com.lejia.springcloud.service.PaymentFeignService: debug

查看日志

再次发送请求测试,我们可以看到,feign记录的接口日志非常全面

image-20201208173849010

感谢你的访问,你的每一个点赞都是对我最大的帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值