SpringCloud系列之 openfeign

简介

openfeign 是一个服务调用的组件,用来实现两个服务之间的相互调用,Feign是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上申明注解。使用起来比传统的RestTemplate 更加简单。

使用

使用前阅读

由于openfeign 是只是服务调用,需要注册中心的先注册服务在可以被调用,本文注册中心使用的是eureka,当然也可以使用其它的注册中心,有兴趣的可以自行创建。
openfeign的使用方法很简单,只需要简答的配置就可以实现服务之间的调用,使用起来和传统的单体项目很相似,但是一般使用的过程中,openfeign要和 hystrix 一起使用,可以实现更加丰富的功能,本文主要是对openfeign 进行简单的使用。
springcloud-eureka-server 为注册中心
springcloud-openfeign-a: 服务调用端A
springcloud-openfeign-b: 服务调用端B

项目中使用

创建eureka服务注册中心,提供服务注册和发现,新建springBoot项目springcloud-eureka-server,并导入pom依赖:

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

在启动类类上加注解:

@EnableEurekaServer

编写配置文件application.yml:

server:
  port: 2222

eureka:
  instance:
    hostname: localhost  #eureka服务端的实例名称
  client:
    #false表示不向注册中心注册自己(想注册也可以,不过没必要)
    register-with-eureka: false
    #false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

新建SpringBoot项目,服务调用端springcloud-openfeign-a,并导入pom文件:


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--工具包-->
        <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.5.4</version>
        </dependency>

启动类上加注解

@EnableEurekaClient
@EnableFeignClients //开启Feign

编写测试用例DemoController:


@RestController
@RequestMapping("/demo")
public class DemoController {

    @Value("${server.port}")
    private String serverPort;
    @Value("${spring.application.name}")
    private String serverName;

    @Autowired
    BOpenFeignService bOpenFeignService;


    @GetMapping("/getServerInfo/{name}")
    public String getServerInfo(@PathVariable("name") String name) {
        if (StrUtil.isBlank(name)) {
            return "请输入请求数据!";
        }
        String result = "当前服务器:" + serverName + " 端口号:" + serverPort + " 时间戳:" + DateUtil.now();
        ;
        if (!"a".equalsIgnoreCase(name)) {
            result += "<br>目标服务器:<br>" + bOpenFeignService.getServerInfo(name);
        }
        return result;
    }

    @GetMapping("/test/threadSleep/{seconds}")
    public String threadSleep(@PathVariable("seconds")Long seconds){
        try {
            TimeUnit.SECONDS.sleep(seconds);
        }catch (Exception e){
            e.printStackTrace();
        }
        return "执行完成!";
    }
}

编写openfeign 的服务调用service:

@Component
@FeignClient(value = "SPRINGCLOUD-OPENFEIGN-B")  //value是另一个项目的服务名
public interface BOpenFeignService {

    @GetMapping("/demo/getServerInfo/{name}")
    @ResponseBody
    public String getServerInfo(@PathVariable("name") String name);
}

编写配置文件application.yml:

server:
  port: 3333
spring:
  application:
    name: springcloud-openfeign-a
eureka:
  client:
    #true表示向注册中心注册自己,默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:2222/eureka

新建SpringBoot项目,服务调用端springcloud-openfeign-b,并导入pom文件:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.4</version>
        </dependency>

启动类上加注解

@EnableEurekaClient
@EnableFeignClients //开启Feign

编写测试用例DemoController:


@RestController
@RequestMapping("/demo")
public class DemoController {

    @Value("${server.port}")
    private String serverPort;
    @Value("${spring.application.name}")
    private String serverName;

    @Autowired
    AOpenFeignService aOpenFeignService;
    
    @GetMapping("/getServerInfo/{name}")
    public String getServerInfo(@PathVariable("name") String name) {
        if (StrUtil.isBlank(name)) {
            return "请输入请求数据!";
        }
        String result = "当前服务器:" + serverName + " 端口号:" + serverPort + " 时间戳:" + DateUtil.now();
        ;
        if (!"b".equalsIgnoreCase(name)) {
            result += "<br>目标服务器:<br>" + aOpenFeignService.getServerInfo(name);
        }
        return result;
    }

    @GetMapping("/test/threadSleep/{seconds}")
    public String threadSleep(@PathVariable("seconds") Long seconds){
        return aOpenFeignService.threadSleep(seconds);
    }
}

编写openfeign 的服务调用service:

@Component
@FeignClient(value = "SPRINGCLOUD-OPENFEIGN-A")
public interface AOpenFeignService {

    @GetMapping("/demo/getServerInfo/{name}")
    @ResponseBody
    public String getServerInfo(@PathVariable("name") String name);

    @GetMapping("/demo/test/threadSleep/{seconds}")
    public String threadSleep(@PathVariable("seconds") Long seconds);
}

编写配置文件application.yml:

server:
  port: 5555
spring:
  application:
    name: springcloud-openfeign-b
eureka:
  client:
    #true表示向注册中心注册自己,默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:2222/eureka
feign:
  client:
    config:
      default:
        #建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间
        ConnectTimeOut: 5000
        #指建立连接后从服务端读取到可用资源所用的时间
        ReadTimeOut: 5000

启动项目

依次启动项目

springcloud-eureka-server ,springcloud-openfeign-a,springcloud-openfeign-b

检测注册中心是否有服务

访问:

http://127.0.0.1:2222/

如下图,可以看到两个服务已经被注册进来了

a 调用 a:

http://127.0.0.1:3333/demo/getServerInfo/a

a 调用 b:

http://127.0.0.1:3333/demo/getServerInfo/b

b 调用 a 发生超时:

http://127.0.0.1:5555/demo/test/threadSleep/6

springcloud-openfeign-b 中加入 openfeign超时配置application.yml:

feign:
  client:
    config:
      default:
        #建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间
        ConnectTimeOut: 7000
        #指建立连接后从服务端读取到可用资源所用的时间
        ReadTimeOut: 7000

再次调用:

http://127.0.0.1:5555/demo/test/threadSleep/5

项目地址

git@gitee.com:anxc/study-demo.git

参考链接

https://www.jianshu.com/p/e1561b45a6b2
https://github.com/OpenFeign/
https://www.cnblogs.com/my-ordinary/p/12508997.html

原文地址:https://www.cnblogs.com/Anxc/p/14232050.html