SpringCloud组件---OpenFeign

OpenFeign的介绍:

    1. 什么是OpenFeign?
    
    在前面的spring cloud使用中。我们使用restTemplate实现了系统之间的通信,但是这种使用方式,代码耦合性还是比较高;
因此,我们需要一种更加方便优雅的使用方式。这就需要用到OpenFeign了。
    OpenFeign:是一个声明式的WebService客户端,内部封装了restTemplate,用于实现微服务系统之间的远程调用。
    
    2. OpenFeign的使用:
    
        1. 加入OpenFeign的起步依赖:哪里需要使用,在哪里添加即可;
            在user-consumer端加入依赖:
            <!--配置feign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            
        2. 编写一个接口,声明相关的请求和参数:和user-provider端的Controller中的方法一致即可;
            在之前的使用过程中,我们使用restTemplate向user-provider端的Controller发送了请求,请求方法是:findByUser();
        请求路径是:"http://user-provider/user/findByUser",返回值是User。因此我们只需将此方法拷贝到该feign接口中来,保持请求路径一致,
        同时,使用注解@FeignClient(name = "user-provider")指定要调用的微服务名称是user-provider。
        
        习惯问题: 
            1. 在类上加注解:@RequestMapping("/user"),在方法上加注解:@RequestMapping(value = "/findByUser");
            2. 上述方式等价于:在方法上加注解:@RequestMapping(value = "/user/findByUser"),并且这种方式在feign调用时更实用。
            推荐使用这种方式,使用第一种方式,在编写Feign接口的实现类时,可能会报错:Cannot map 'com.it.feign.UserFeign' method。
        
            package com.it.feign;

            import com.it.pojo.User;
            import org.springframework.web.bind.annotation.RequestMapping;

            /**
             * ToDo
             *
             * @author Lyle
             * @date 2020/4/4
             */
            
            @FeignClient(name = "user-provider")
            public interface UserFeign {

                @RequestMapping("/user/findByUser")
                public User findByUser();
            }
            
        3. 在user-consumer端的启动类使用注解@EnableFeignClients来开启声明式Feign的调用;
        
        4. 在需要使用feign的地方注入feign,调用feign的方法即可:
            package com.it.controller;

            import com.it.feign.UserFeign;
            import com.it.pojo.User;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.web.bind.annotation.RequestMapping;
            import org.springframework.web.bind.annotation.RestController;

            /**
             * ToDo
             *
             * @author Lyle
             * @date 2020/4/4
             */
            @RestController
            @RequestMapping("/feign")
            public class TestFeignController {

                @Autowired
                private UserFeign userFeign;

                @RequestMapping("/test")
                public User findByUser(){
                    System.out.println("Feign调用了。。。。");
                    User user = userFeign.findByUser();
                    return user;
                }
            }
            
    3. Feign接口编写的要求:
        1. 接口编写时,方法一般与被调用的微服务方法一致(但并非必须一致);
        2. 方法中的参数类型与参数的个数一定要和被调用的微服务方法中的参数类型和个数保持一致;
        3. 若被调用的微服务方法中使用了springmvc注解:@PathVariable、@RequestParam、@RequestBody等,
        在接口中编写的方法也一定要加上springmvc注解;
        4. 接口中编写的方法返回值一定要与被调用的微服务方法中返回值保持一致。
        
    4. OpenFeign集成了Ribbon,支持负载均衡:
        Ribbon配置的负载均衡策略是什么,Feign调用的时候就按照什么策略进行调用;
    
    5. OpenFeign支持熔断机制:
        
        熔断机制的使用:
        1. 编写一个feign接口的实现类,使用注解@Component将类交给spring容器管理,
        类的方法就是熔断处理方法(备胎方法),用于返回默认数据;
            
            package com.it.feign.impl;

            import com.it.feign.UserFeign;
            import com.it.pojo.User;
            import org.springframework.stereotype.Component;

            /**
             * ToDo
             *
             * @author Lyle
             * @date 2020/4/4
             */
            @Component
            public class UserFeignImpl implements UserFeign {
                @Override
                public User findByUser() {
                    User user = new User();
                    user.setName("备胎方法,返回默认数据。。。");
                    user.setId(123);

                    return user;
                }
            }
            
        2. 在Feign接口中,使用注解@FeignClient(name = "user-provider",fallback = UserFeignImpl.class),
        指定指定要调用的微服务名称是user-provider,同时指定处理熔断的类:UserFeignImpl.classpackage com.it.feign;

            import com.it.feign.impl.UserFeignImpl;
            import com.it.pojo.User;
            import org.springframework.cloud.openfeign.FeignClient;
            import org.springframework.web.bind.annotation.RequestMapping;

            /**
             * ToDo
             *fallback:指定发生错误时,处理熔断的类,然后根据方法名进行处理
             * @author Lyle
             * @date 2020/4/4
             */

            @FeignClient(name = "user-provider",fallback = UserFeignImpl.class)//指定要调用的微服务名称:即application.name,指定后feign会发送请求到该微服务中
            public interface UserFeign {

                @RequestMapping("/user/findByUser")
                public User findByUser();
            }
        
        3. 配置熔断策略,并配置开启feign支持熔断机制(默认没有开启):
        在user-consumer端application.yml中进行如下配置:
            # 配置熔断策略:
            hystrix:
              command:
                default:
                  circuitBreaker:
                    # 强制打开熔断器 默认false关闭的。测试配置是否生效
                    forceOpen: false
                    # 触发熔断错误比例阈值,默认值50%
                    errorThresholdPercentage: 50
                    # 熔断后休眠时长,默认值5秒
                    sleepWindowInMilliseconds: 10000
                    # 熔断触发最小请求次数,默认值是20
                    requestVolumeThreshold: 10
                  execution:
                    isolation:
                      thread:
                        # 熔断超时设置,默认为1秒
                        timeoutInMilliseconds: 2000
            feign:
              hystrix:
                enabled: true #开启feign支持熔断机制,默认没有开启
                
        4. feign的日志的使用:
                
            1. feign的日志级别配置:
                # com.it 包下的日志级别都为Debug
                logging:
                  level:
                    com.it: debug

            2. 在启动类中通过@Bean注册Logger.Level:
                /***
                 * 日志级别:NONE,BASIC,HEADERS,FULL;
                 * @return
                 */
                @Bean
                public Logger.Level feignLoggerLevel(){
                    return Logger.Level.FULL;
                }

        
        

            

        
        




    




















    
            
原文地址:https://www.cnblogs.com/lyle-liu/p/12631028.html