微服务组件之Feign远程服务调用

目录

    • Feign
    • OpenFeign
      • 核心注解
      • OpenFeign远程服务调用示例
        • 搭建producer服务(被调用方)
        • 搭建consumer服务(调用方)
        • 服务启动
        • 接口调用测试
      • OpenFeign超时控制
      • OpenFeign日志增强
      • 总结

Feign

Feign是一种声明式服务调用组件,它在RestTemplate的基础上做了进一步的封装。通过Feign,我们只需声明一个接口,并通过注解进行简单的配置,即可实现对HTTP接口的绑定。

Feign Ribbon进行了集成,通过 Ribbon 实现了客户端的负载均衡调用。

OpenFeign

OpenFeignSpring Cloud Feign 的二次封装,它具有 Feign 的所有功能,并在Feign的基础上增加了对 Spring MVC 注解的支持。

核心注解

@FeignClient 该注解用于通知 OpenFeign 组件对 @RequestMapping 注解下的接口进行解析,并通过动态代理的方式产生实现类,实现负载均衡和服务调用。

@EnableFeignClients该注解用于开启 OpenFeign 功能,当 Spring Cloud 应用启动时,OpenFeign 会扫描标有 @FeignClient 注解的接口,生成代理并注册到 Spring 容器中。

OpenFeign远程服务调用示例

搭建producer服务(被调用方)

1.创建一个springboot应用

(1)pom文件添加相关依赖


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

(2)配置

server.port=8091
spring.application.name=producer-service

#可以注册到eureka服务注册中心
eureka.client.enabled=true
eureka.client.service-url.defaultZone=http://admin:[email protected]:10001/eureka

(3)启动类

@EnableEurekaClient
@SpringBootApplication
public class ProducerApplication {

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

}

(4)接口

@Controller
@RequestMapping("/orderService/service")
public class UserController {

    @ResponseBody
    @RequestMapping("/get")
    public String get(){
        return "producer info";
    }
}

搭建consumer服务(调用方)

1.创建一个springboot应用

(1)pom文件添加依赖


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
    <version>${spring.cloud.netflix.version}version>
dependency>

(2)配置

server.port=8092
spring.application.name=consumer-service
#可以注册到eureka服务注册中心
eureka.client.enabled=true

spring.security.user.name=admin
spring.security.user.password=123456
eureka.client.service-url.defaultZone=http://admin:[email protected]:10001/eureka

#服务消费者客户端需要去检索服务
eureka.client.fetch-registry=true

(3)启动类

启动类上添加@EnableFeignClients注解开启 OpenFeign 功能

@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {

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

}

(4)创建一个接口,使用注解@FeignClient,实现对服务接口的绑定,value属性值即为服务提供者的实例名称

@Component
@FeignClient(value = "producer-service")
public interface FeignService {

    //value值即为producer服务的接口地址
    @RequestMapping(value = "orderService/service/get", method = RequestMethod.GET)
    String get();
}

(5)controller入口

@Controller
@RequestMapping("/orderService/service")
public class UserController {

    @Autowired
    FeignService feignService;

    @ResponseBody
    @RequestMapping("/get")
    public String get(){
        return feignService.get();
    }
}

服务启动

依次启动eureka serverproducer服务consumer服务

接口调用测试

浏览器访问http://localhost:8092/orderService/service/get请求接口,返回结果如下:

微服务组件之Feign远程服务调用_第1张图片

OpenFeign超时控制

1.producer提供一个超时接口

@ResponseBody
@RequestMapping("/getTimeOut")
public String getTimeOut(){
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    
    return "producer info";
}

2.consumer接口调用producer的超时接口

@ResponseBody
@RequestMapping("/getTimeOut")
public String getTimeOut(){
    return feignService.getTimeOut();
}

尝试请求http://localhost:8092/orderService/service/getTimeOut接口,结果:

微服务组件之Feign远程服务调用_第2张图片

OpenFeign客户端默认等待一秒钟,超时就会报错。

3.修改consumer的配置

feign.client.config.producer-service.connect-timeout=6000
feign.client.config.producer-service.read-timeout=6000

4.重启consumer

尝试请求http://localhost:8092/orderService/service/getTimeOut接口,返回结果如下:

微服务组件之Feign远程服务调用_第3张图片

OpenFeign日志增强

1.开启日志相关配置

Feign 为每一个 FeignClient 都提供了一个 feign.Logger 实例,通过它可以对 OpenFeign 服务绑定接口的调用情况进行监控。

# com.example.consumer.service.FeignService 即为开启@FeignClient 注解的接口的全类名
# debug:表示监听该接口的日志级别
logging.level.com.example.consumer.service.FeignService=debug

2.创建一个配置类

@Configuration
public class ConfigOpenFeignLog {
    /**
     * OpenFeign 日志增强
     * 配置 OpenFeign 记录哪些内容
     */
    @Bean
    Logger.Level feginLoggerLevel() {
        //Logger.Level.FULL: 记录所有请求与响应的明细,包括头信息、请求体、元数据等等
        return Logger.Level.FULL;
    }
}

访问接口http://localhost:8092/orderService/service/get,查看控制台打印日志

2022-11-01 14:31:53.134 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] ---> GET http://producer-service/orderService/service/get HTTP/1.1
2022-11-01 14:31:53.135 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] ---> END HTTP (0-byte body)
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] <--- HTTP/1.1 200 (2ms)
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] cache-control: no-cache, no-store, max-age=0, must-revalidate
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] content-length: 13
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] content-type: text/plain;charset=UTF-8
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] date: Tue, 01 Nov 2022 06:31:53 GMT
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] expires: 0
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] pragma: no-cache
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] x-content-type-options: nosniff
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] x-frame-options: DENY
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] x-xss-protection: 1; mode=block
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] 
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] producer info
2022-11-01 14:31:53.138 DEBUG 62672 --- [nio-8092-exec-1] c.example.consumer.service.FeignService  : [FeignService#get] <--- END HTTP (13-byte body)

控制台打印了该接口请求与响应的所有明细

总结

本节内容主要记录了声明式的服务调用组件,OpenFeign如何进行远程服务调用,以及对调用服务接口的超时控制相关的配置,还有接口调用过程的日志增强…

你可能感兴趣的:(微服务,微服务,spring,cloud)