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;
                }

        
        

            

        
        




    




















    
            

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM