SpringCloud之使用Feign跨服務呼叫最佳方式

Awbeci 發表於 2022-01-14
Spring

前言

最近在學習如何使用springcloud,當學習到跨服務呼叫介面時接觸到Feign和Ribbon,網上有好多文章是介紹他們倆的區別的,有興趣的可以看看,本文主要推薦使用Feign並記錄操作過程。

Feign和Ribbon對比

Ribbon
Ribbon 是一個基於 HTTP 和 TCP 客戶端的負載均衡器
它可以在客戶端配置 ribbonServerList(服務端列表),然後輪詢請求以實現均衡負載
它在聯合 Eureka 使用時
ribbonServerList 會被 DiscoveryEnabledNIWSServerList 重寫,擴充套件成從 Eureka 註冊中心獲取服務端列表
同時它也會用 NIWSDiscoveryPing 來取代 IPing,它將職責委託給 Eureka 來確定服務端是否已經啟動

Feign
Spring Cloud Netflix 的微服務都是以 HTTP 介面的形式暴露的,所以可以用 Apache 的 HttpClient 或 Spring 的 RestTemplate 去呼叫
而 Feign 是一個使用起來更加方便的 HTTP 客戶端
總結起來就是:釋出到註冊中心的服務方介面,是 HTTP 的,也可以不用 Ribbon 或者 Feign,直接瀏覽器一樣能夠訪問
只不過 Ribbon 或者 Feign 呼叫起來要方便一些,最重要的是:它倆都支援軟負載均衡
注意:spring-cloud-starter-feign 裡面已經包含了 spring-cloud-starter-ribbon(Feign 中也使用了 Ribbon)
從實踐上看,採用feign的方式更優雅(feign內部也使用了ribbon做負載均衡)。

操作

1、引入feign依賴包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、啟用feign:@EnableFeignClients

@SpringBootApplication
// 資源保護服務
@EnableResourceServer
// 服務發現
@EnableDiscoveryClient
// 啟用feign
@EnableFeignClients
@RefreshScope
public class NofityServiceApplication {
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

3、配置feign傳遞token

@Configuration
public class FeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String authorization = request.getHeader("authorization");
        log.info("--- authorization ---:{}", authorization);
        if (authorization != null) {
            log.info(" ---- set authorization ---");
            //新增token
            requestTemplate.header("authorization", authorization);
        }
    }
}

4、使用feign呼叫其它微服務介面

新建AccountFeignClient.java檔案

@FeignClient("account-service")
public interface AccountFeignClient {

    @GetMapping("/userInfo/{userName}")
    User getAccountInfoByUserName(@PathVariable("userName") String userName);
}

這樣就完成了feign配置的所有操作,試試呼叫是不是OK了!

總結

1、feign跨服務呼叫的時候會有token的傳遞,所以一定要加上上面的config配置
2、如果被呼叫的服務介面不需要token,如果你呼叫的介面傳遞了token會報401,這個要注意一下!

引用

SpringCloud系列之服務消費Ribbon和Feign區別