SpringCloud之OpenFeign简单使用

简介: 当远程服务调用失败时,会采用熔断降级策略,调用熔断降级的方法返回。

OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。


一、远程调用功能


创建提供服务的模块remote-feign-provider


引入依赖


<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

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

版本信息如下

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>2.4.2</spring-boot.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
        <nacos.version>2021.1</nacos.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-bootstrap.version>3.0.3</spring-cloud-bootstrap.version>
        <spring-cloud-loadbalancer.version>3.0.1</spring-cloud-loadbalancer.version>
        <spring-cloud-openfeign.version>3.0.1</spring-cloud-openfeign.version>
</properties>
  • 创建主类
@EnableDiscoveryClient
@SpringBootApplication
public class RemoteFeignProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(RemoteFeignProviderApplication.class, args);
    }
}
  • 创建bootstrap.yml
spring:
  application:
    name: remote-feign-provider
  cloud:
    nacos:
      discovery:
        group: remote-group
        namespace: remoteinvoke
        server-addr: 192.168.56.102:8848
        weight: 5

server:
  port: 8082

注意nacos面板中需要新建相应的命名空间


  • 创建TestController,提供相应的调用服务
@RestController
public class TestController {

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

    @GetMapping("/service")
    public String test(){
        return "provicer servvice: [from port]:" + port;
    }
}

开启8081,8082两个端口的remote-feign-provider服务集群


  1. 下面开始创建调用模块,consumer模块
  • 创建remote-feign-service模块
  • 引入依赖
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    </dependencies>
  • 主类
@SpringBootApplication
@EnableFeignClients(basePackages = "cn.axj.remote.feign.feign")
@EnableDiscoveryClient
public class FeignServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignServiceApplication.class, args);
    }
}

@EnableDiscoveryClient默认要注册到注册中心,这个注解可加可不加。


@EnableFeignClients : basePackages 用于OpenFeign扫描定义的FeignClient包路径


  • bootstrap.yml
spring:
  application:
    name: remote-feign-service
  cloud:
    nacos:
      discovery:
        group: remote-group
        namespace: remoteinvoke
        server-addr: 192.168.56.102:8848
        weight: 5

server:
  port: 8080
使用url形式的方式


  • 创建LoadBalanceProviderOriginalFeignClient的接口,并利用SpringMvc的特性,将provider提供的服务/service声明成springmvc形式
@FeignClient(url = "http://localhost:8082",name = "remoteFeignSerivce")
public interface LoadBalanceProviderOriginalFeignClient {

    @GetMapping("/service")
    String service();

}


定义一个url为http://localhost:8082的服务ip/端口的服务,指定该类访问的基础ip地址和端口固定


关于@FeignClient注解,参数释义如下


参数名称 释义 示例
name/value 指定远程服务的名称,用于服务发现和调用。 @FeignClient(name = "user-service")
url 直接指定远程服务的 URL 地址。当提供了 url 时,name 将被忽略。 @FeignClient(url = "http://localhost:8080")

configuration

用于自定义 Feign 客户端的配置,可以包含自定义的 Encoder、Decoder、LoggerLevel 等。

@FeignClient(name = "user-service", configuration = MyFeignConfiguration.class)

fallback

用于指定熔断降级类,当远程服务调用失败时,会调用这个降级类中的方法。

@FeignClient(name = "user-service", fallback = UserServiceClientFallback.class)

fallbackFactory

用于创建熔断降级类的工厂,允许在创建降级类时注入其他依赖。

@FeignClient(name = "user-service", fallbackFactory = UserServiceClientFallbackFactory.class)

path

定义所有请求的基础路径,会添加到每个请求的前面。

@FeignClient(name = "user-service", path = "/api/v1")

decode404

当服务器返回 404 时,是否应该解码响应体。默认为 false

@FeignClient(name = "user-service", decode404 = true)

loggerLevel

设置 Feign 客户端的日志级别,可选值包括 NONEBASICHEADERSFULL

@FeignClient(name = "user-service", loggerLevel = Logger.Level.FULL)

primary

当在 Spring 上下文中存在多个同名的 Feign 客户端时,标记哪个作为主要的 bean。

@FeignClient(name = "user-service", primary = true)

qualifier

当需要区分多个同类型的 Feign 客户端时,用于指定一个唯一的名称,以便在注入时区分。

@FeignClient(name = "user-service", qualifier = "myFeignClient")


  • 创建入口类Controller
@RestController
public class TestController {

    @Resource
    private LoadBalanceProviderOriginalFeignClient loadBalanceProviderOriginalFeignClient;

    @GetMapping("/test")
    public String test(){
        return loadBalanceProviderOriginalFeignClient.service();
    }
}


将FeignClient用组件的形式注入到Spring中,类似于Mybatis的Mapper类,OpenFeign会生产代理对象注入到Spring容器中

测试


启动remote-feign-service模块,访问localhost:8080/test,返回

provicer servvice: [from port]:8082


反复刷新,观察返回情况,可以看到返回信息一直是8082服务器返回的。

二、负载功能


OpenFeign默认开启负载,使用注册到注册中心的服务名称定义FeignClient。


  • 在remote-feign-service模块中增加loadBalancer依赖
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
  • 创建负载类的LoadBalanceProviderFeignClient接口
@FeignClient(name = "remote-feign-provider") 
public interface LoadBalanceProviderFeignClient {

    @GetMapping("/service")
    String service();
}

name: 在注册中心中注册的调用服务名称


  • 在TestController中注入该FeignClient
@RestController
public class TestController {

    @Resource
    private LoadBalanceProviderOriginalFeignClient loadBalanceProviderOriginalFeignClient;

    @Resource
    private LoadBalanceProviderFeignClient loadBalanceProviderFeignClient;

    @GetMapping("/test")
    public String test(){
        return loadBalanceProviderOriginalFeignClient.service();
    }

    @GetMapping("/test2")
    public String test2(){
        return loadBalanceProviderFeignClient.service();
    }
}
测试


重启remote-feign-service模块,访问localhost:8080/test2,观察返回

provicer servvice: [from port]:8082
provicer servvice: [from port]:8081
provicer servvice: [from port]:8082
provicer servvice: [from port]:8081
provicer servvice: [from port]:8082
....

此时已默认加入负载功能


三、熔断降级


当远程服务调用失败时,会采用熔断降级策略,调用熔断降级的方法返回。


熔断降级需要搭配熔断降级组件使用,这里使用hystrix进行熔断


由于springcloud高版本openFeign已经默认移除了hystrix组件,这里需要手动加上hystrix依赖



    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
  • bootstrap.yml中增加配置
feign:
  circuitbreaker:
    enabled: true
  • 新建LoadBalanceProviderFeignClientFallback熔断类
@Component
public class LoadBalanceProviderFeignClientFallback implements LoadBalanceProviderFeignClient{
    
    @Override
    public String service() {
        return "error fall back";
    }
}

tips: 必须将熔断类放入Spring容器中


  • 配置FeignClient的熔断类,配置FeignClient fallback属性
@FeignClient(name = "remote-feign-provider",fallback = LoadBalanceProviderFeignClientFallback.class)
public interface LoadBalanceProviderFeignClient {

    @GetMapping("/service")
    String service();
}

重启remote-feign-service模块,并将remote-feign-provider服务全部关掉。模拟熔断现象产生,访问localhost:8080/test2,观察返回

error fall back

返回结果是有熔断类逻辑返回。


目录
打赏
0
2
2
1
8
分享
相关文章
Spring Cloud OpenFeign 远程调用传递请求头信息
import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.util.Assert; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;
320 0
|
8月前
|
Java一分钟之-Spring Cloud OpenFeign:声明式服务调用
【6月更文挑战第9天】Spring Cloud OpenFeign是声明式服务调用库,简化了微服务间调用。通过动态代理,它允许开发者用Java接口调用HTTP服务,支持服务发现、负载均衡。本文介绍了OpenFeign的基本概念,展示了如何添加依赖、开启客户端和定义服务接口。还讨论了接口调用失败、超时重试和日志配置等问题及其解决方案,并提供了自定义Feign配置的代码示例。通过学习,读者可以更好地在微服务架构中使用OpenFeign进行服务通信。
431 4
|
8月前
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
431 0
Spring Cloud 之 OpenFeign
Spring Cloud OpenFeign是Spring官方的声明式服务调用组件,简化了远程服务调用,使其如同调用本地方法。核心注解包括`@FeignClient`、`@EnableFeignClients`、`@GetMapping`和`@PostMapping`。实践中,通过在`pom.xml`添加依赖,创建Feign接口,配置`@FeignClient`,在启动类启用Feign,以及自定义超时设置来实现远程调用和负载均衡。
|
8月前
springCloud之服务调用RestTemplate、OpenFeign
springCloud之服务调用RestTemplate、OpenFeign
110 0
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(五)OpenFeign的使用
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(五)OpenFeign的使用
130 0
springcloud3-服务到服务调用ribbon及openfeign
springcloud3-服务到服务调用ribbon及openfeign
95 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等