• SpringCloud基础知识【Feign声明式系统调用】


    1. Feign 概述

    • Feign是一个声明式的REST客户端,它用了基于接口的注解方式,很方便实现客户端配置。
    • Feign最初由Netflix公司提供,但不支持SpringMC注解,由SprinaCloud.对其封装,支持了SpringMMC注解,让使用者更易于接受。
    • Feign是用于简化RestTemplateRibbon的调用方式的。

    在这里插入图片描述

    2. Feign快速入门

    2.1 前期准备(初始默认代码)

    在这里插入图片描述
    在这里插入图片描述

    2.1.1 feign-parent模块

    在父模块中,我们只需要在父模块的pom.xml中引入spring-cloud依赖即可

    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
    
        <groupId>com.itheimagroupId>
        <artifactId>feign-parentartifactId>
        <packaging>pompackaging>
        <version>1.0-SNAPSHOTversion>
        <modules>
            <module>eureka-servermodule>
            <module>feign-providermodule>
            <module>feign-consumermodule>
        modules>
    
    
        
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.1.0.RELEASEversion>
            <relativePath/>
        parent>
    
    
        <properties>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
            <java.version>1.8java.version>
            
            <spring-cloud.version>Greenwich.RELEASEspring-cloud.version>
        properties>
    
        
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloudgroupId>
                    <artifactId>spring-cloud-dependenciesartifactId>
                    <version>${spring-cloud.version}version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
    
            dependencies>
        dependencyManagement>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    2.1.2 eureka-server模块

    • pom.xml
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>feign-parentartifactId>
            <groupId>com.itheimagroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>eureka-serverartifactId>
    
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
            dependency>
    
        dependencies>
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • application.yml
    server:
      port: 8761
    
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
        register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
        fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
      server:
        enable-self-preservation: false # 关闭自我保护机制
        eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动类

    package com.itheima.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    // 启用EurekaServer
    @EnableEurekaServer
    public class EurekaApp {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaApp.class,args);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.1.3 feign-consumer模块

    • pom.xml
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>feign-parentartifactId>
            <groupId>com.itheimagroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>feign-consumerartifactId>
    
        <dependencies>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
    
    
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
            dependency>
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • applicaion.yml
    server:
      port: 9000
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    spring:
      application:
        name: feign-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 启动类
    package com.itheima.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @EnableDiscoveryClient // 激活DiscoveryClient
    @EnableEurekaClient
    @SpringBootApplication
    public class ConsumerApp {
    
        public static void main(String[] args) {
    
            SpringApplication.run(ConsumerApp.class,args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • config配置类
    package com.itheima.consumer.config;
    
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class RestTemplateConfig {
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
    
            return new RestTemplate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • controller控制类
    package com.itheima.consumer.controller;
    
    import com.itheima.consumer.domain.Goods;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
    		/*
    		 * 未使用ribbon之前需要拿到主机名:端口号
             * String url = "http://localhost:8000/goods/findOne/"+id;
            */
            
            //使用ribbon后,通过{FEIGN-PROVIDER}代替{主机名:端口号},
            //前提须在RestTemplate 模板控制类加上 @LoadBalanced注解
            String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
    
            return goods;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • domain实体类
    package com.itheima.consumer.domain;
    
    /**
     * 商品实体类:Goods 
     */
    public class Goods {
    
        private int id;
        private String title;//商品标题
        private double price;//商品价格
        private int count;//商品库存
    
        public Goods() {
        }
    
        public Goods(int id, String title, double price, int count) {
            this.id = id;
            this.title = title;
            this.price = price;
            this.count = count;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    2.1.4 feign-provider模块

    • pom.xml
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>feign-parentartifactId>
            <groupId>com.itheimagroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>feign-providerartifactId>
    
    
        <dependencies>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
    
    
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
            dependency>
    
        dependencies>
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • application.yml
    server:
      port: 8001
    
    eureka:
      instance:
        hostname: localhost # 主机名
        prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名
        ip-address: 127.0.0.1 # 设置当前实例的ip
        instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # 设置web控制台显示的 实例id
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    spring:
      application:
        name: feign-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 启动类(无修改)
    package com.itheima.provider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    /**
     * 启动类
     */
    
    @EnableEurekaClient //该注解 在新版本中可以省略
    @SpringBootApplication
    public class ProviderApp {
    
    
        public static void main(String[] args) {
            
            SpringApplication.run(ProviderApp.class,args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • domain实体类(提供方和消费方的实体类一致)
    package com.itheima.provider.domain;
    
    /**
     * 商品实体类
     */
    public class Goods {
    
        private int id;
        private String title;//商品标题
        private double price;//商品价格
        private int count;//商品库存
    
        public Goods() {
        }
    
        public Goods(int id, String title, double price, int count) {
            this.id = id;
            this.title = title;
            this.price = price;
            this.count = count;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • dao层接口
    package com.itheima.provider.dao;
    
    import com.itheima.provider.domain.Goods;
    import org.springframework.stereotype.Repository;
    
    import javax.validation.ReportAsSingleViolation;
    
    /**
     * 商品Dao
     */
    
    @Repository
    public class GoodsDao {
    
    
        public Goods findOne(int id){
    
            return new Goods(1,"华为手机",3999,10000);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • service层接口
    package com.itheima.provider.service;
    
    import com.itheima.provider.dao.GoodsDao;
    import com.itheima.provider.domain.Goods;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * Goods 业务层
     */
    @Service
    public class GoodsService {
    
        @Autowired
        private GoodsDao goodsDao;
    
    
        /**
         * 根据id查询
         * @param id
         * @return
         */
        public Goods findOne(int id){
    
            return goodsDao.findOne(id);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • controller控制类
    package com.itheima.provider.controller;
    
    import com.itheima.provider.domain.Goods;
    import com.itheima.provider.service.GoodsService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * Goods Controller 服务提供方
     */
    
    @RestController
    @RequestMapping("/goods")
    public class GoodsController {
    
        @Autowired
        private GoodsService goodsService;
    
        @Value("${server.port}")
        private int port;
    
        @GetMapping("/findOne/{id}")
        public Goods findOne(@PathVariable("id") int id){
    
            Goods goods = goodsService.findOne(id);
    
            goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到了 商品标题上
            return goods;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2.2 Feign应用(代码修改)

    1. 在消费端引入 open-feign 依赖
    2. 编写Feign调用接口
    3. 在启动类添加EnableEeianClients注解,开启Feign功能
    4. 测试调用

    2.2.1 feign-consumer模块

    • 消费端引入 open-feign 依赖
     
     <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
     dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 编写Feign调用接口(包名:feign)
    package com.itheima.consumer.feign;
    
    import com.itheima.consumer.domain.Goods;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /*
     * Feign声明式接口,发起远程调用的。简化controller包下OrderController的代码。
            String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
            Goods goods = restTemplate.getForObject(url, Goods.class);
     * 1.定义接口
     * 2.接口上添加@FeignClient注解,设置value属性为【服务提供方的应用名称】
     * 3.编写调用接口,接口的声明规则和提供方接口保持一致。方法名可以不一样,即下面的【findOne】改为【findGooodsById】也行
     */
    @FeignClient(value = "FEIGN-PROVIDER")
    public interface GoodsFeignClient {
        @GetMapping("/goods/findOne/{id}")//这样就拼接好了路径:http://FEIGN-PROVIDER/goods/findOne/"+id
        //因为要使用的提供方提供的Goods商品服务,所以复制提供方controller包下的GoodsController方法
        public Goods findOne(@PathVariable("id") int id);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 别忘记在消费方启动类开启Feign功能
    package com.itheima.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @EnableDiscoveryClient // 激活DiscoveryClient
    @EnableEurekaClient
    @SpringBootApplication
    
    @EnableFeignClients //开启Feign功能
    public class ConsumerApp {
    
    
        public static void main(String[] args) {
    
            SpringApplication.run(ConsumerApp.class,args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 修改config中 OrderController 代码
    package com.itheima.consumer.controller;
    
    
    import com.itheima.consumer.domain.Goods;
    import com.itheima.consumer.feign.GoodsFeignClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private GoodsFeignClient goodsFeignClient;
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
    
           /* String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
            Goods goods = restTemplate.getForObject(url, Goods.class);
            return goods;*/
    
            Goods goods = goodsFeignClient.findOne(id);
            return goods;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 测试调用

    在这里插入图片描述

    3. Feign 其他功能

    3.1 超时设置

    • Feign 底层依赖于Ribbon实现负载均衡和远程调用。
    • Ribbon默认1秒超时
    • 超时配置:
    ribbon:
    	connectTimeout: 1000 # 连接超时时间,毫秒
    	ReadTimeout: 1000 # 逻辑处理超时时间,毫秒
    
    • 1
    • 2
    • 3

    即:

    • 采用超时配置后,如果1秒后,provider 没有向 consumer 反馈结果。就会报一些错误。

    浏览器报错

    在这里插入图片描述

    控制台报错

    在这里插入图片描述

    3.2 日志记录

    Feign只能记录 debug 级别的日志信息。

    • 在consumer模块中的applicaton.yml中设置下面信息
    logging:
    	level:
    	com.itheima: debug  # 某个包名下的日志级别
    
    • 1
    • 2
    • 3
    • 定义Feign日志级别Bean
    package com.itheima.consumer.config;
    
    import feign.Logger;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FeignLogConfig {
        /*
            NONE,不记录
            BASIC,记录基本的请求行,响应状态码数据
            HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
            FULL;记录完成的请求 响应数据
         */
    
        @Bean
        public Logger.Level level(){
            return Logger.Level.FULL;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 在GoodsFeignClient 启动该Bean
    package com.itheima.consumer.feign;
    
    
    import com.itheima.consumer.config.FeignLogConfig;
    import com.itheima.consumer.domain.Goods;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    @FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)//启动该Bean
    public interface GoodsFeignClient {
    
        @GetMapping("/goods/findOne/{id}")
        public Goods findGoodsById(@PathVariable("id") int id);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 重启oonsumer启动类,查看控制台信息

    在这里插入图片描述

  • 相关阅读:
    金仓数据库 KingbaseGIS 使用手册(8.7. 栅格编辑函数、8.8. 栅格波段编辑函数)
    09 【Attributes继承 provide与inject】
    C语言中的结构体和联合体有什么区别?
    STM32的HAL和LL库区别和性能对比
    最新Java面试题,常见面试题及答案汇总
    对强缓存和协商缓存的理解
    C# WPF 开发一个 Windows 动态屏保软件
    spring高级篇(二)
    解析java中的String类中的常用方法(三)
    TensorFlow入门(二十、损失函数)
  • 原文地址:https://blog.csdn.net/qq_40926887/article/details/127796500