中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何深入學習SpringCloud Fegin

發布時間:2021-10-22 16:57:42 來源:億速云 閱讀:177 作者:iii 欄目:編程語言

本篇內容主要講解“如何深入學習SpringCloud Fegin”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何深入學習SpringCloud Fegin”吧!

與Fegin相遇之前 

在我們平時的工作中,我們經常會遇到要調用內部API或者其他第三方服務的API,在遇到Fegin之前我們基本會使用以下幾種方式。

1.HttpURLConnection

簡介:

URLConnection是個抽象類,它有兩個直接子類分別是HttpURLConnection和JarURLConnection。

另外一個重要的類是URL,通常URL可以通過傳給構造器一個String類型的參數來生成一個指向特定地址的URL實例。
每個 HttpURLConnection 實例都可用于生成單個請求,但是其他實例可以透明地共享連接到 HTTP 服務器的基礎網絡。

請求后在 HttpURLConnection 的 InputStream 或 OutputStream 上調用 close() 方法可以釋放與此實例關聯的網絡資源,但對共享的持久連接沒有任何影響。

如果在調用 disconnect() 時持久連接空閑,則可能關閉基礎套接字。

任何網絡連接都需要經過socket才能連接,HttpURLConnection不需要設置socket,所以,HttpURLConnection并不是底層的連接,而是在底層連接上的一個請求

這就是為什么HttpURLConneciton只是一個抽象類,自身不能被實例化的原因。HttpURLConnection只能通過URL.openConnection()方法創建具體的實例。

雖然底層的網絡連接可以被多個HttpURLConnection實例共享,但每一個HttpURLConnection實例只能發送一個請求。

請求結束之后,應該調用HttpURLConnection實例的InputStream或OutputStream的close()方法以釋放請求的網絡資源,不過這種方式對于持久化連接沒用。對于持久化連接,得用disconnect()方法關閉底層連接的socket。

HttpURLConnection請求響應流程:

如何深入學習SpringCloud Fegin

2.HttpClient

簡介:

HttpClient是Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。


它是一個HTTP通信庫、一個工具包,因此它只提供一個通用瀏覽器應用程序所期望的功能子集。


HttpClient與瀏覽器最根本的區別是:HttpClient中沒有用戶界面,瀏覽器需要一個渲染引擎來顯示頁面,并解釋用戶輸入(例如鼠標點擊顯示頁面上的某處之后如何響應、計算如何顯示HTML頁面、級聯樣式表和圖像、javascript解釋器運行嵌入HTML頁面或從HTML頁面引用的javascript代碼、來自用戶界面的事件被傳遞到javascript解釋器進行處理等等等等)。


HttpClient只能以編程的方式通過其API用于傳輸和接受HTTP消息,它對內容也是完全不可知的。

HttpClient還是有很多好的特點(摘自Apache HttpClient官網)

1.基于標準、純凈的java語言。實現了HTTP1.0和HTTP1.1;

2.以可擴展的面向對象的結構實現了HTTP全部的方法(GET, POST等7種方法);

3.支持HTTPS協議;

4.通過HTTP代理建立透明的連接;

5.利用CONNECT方法通過HTTP代理建立隧道的HTTPS連接;

6.Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認證方案;

7.插件式的自定義認證方案;

8.便攜可靠的套接字工廠使它更容易的使用第三方解決方案;

9.連接管理器支持多線程應用;支持設置最大連接數,同時支持設置每個主機的最大連接數,發現并關閉過期的連接;

10.自動處理Set-Cookie中的Cookie;

11.插件式的自定義Cookie策略;

12.Request的輸出流可以避免流中內容直接緩沖到socket服務器;

13.Response的輸入流可以有效的從socket服務器直接讀取相應內容;

14.在HTTP1.0和HTTP1.1中利用KeepAlive保持持久連接;

15.直接獲取服務器發送的response code和 headers;

16.設置連接超時的能力;

17.實驗性的支持HTTP1.1 response caching;

18.源代碼基于Apache License 可免費獲取。

Get Demo

public static void main(String[] args) throws IOException {        //1.打開瀏覽器        CloseableHttpClient httpClient = HttpClients.createDefault();        //2.聲明get請求        HttpGet httpGet = new HttpGet("http://www.baidu.com/s?wd=java");        //3.發送請求        CloseableHttpResponse response = httpClient.execute(httpGet);        //4.判斷狀態碼        if(response.getStatusLine().getStatusCode()==200){            HttpEntity entity = response.getEntity();           //使用工具類EntityUtils,從響應中取出實體表示的內容并轉換成字符串            String string = EntityUtils.toString(entity, "utf-8");            System.out.println(string);        }        //5.關閉資源        response.close();        httpClient.close();    }

Post Demo

public static void main(String[] args) throws IOException {        //1.打開瀏覽器        CloseableHttpClient httpClient = HttpClients.createDefault();        //2.聲明get請求        HttpPost httpPost = new HttpPost("https://www.oschina.net/");        //3.開源中國為了安全,防止惡意攻擊,在post請求中都限制了瀏覽器才能訪問        httpPost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36");        //4.判斷狀態碼        List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);        parameters.add(new BasicNameValuePair("scope", "project"));        parameters.add(new BasicNameValuePair("q", "java"));        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters,"UTF-8");        httpPost.setEntity(formEntity);        //5.發送請求        CloseableHttpResponse response = httpClient.execute(httpPost);        if(response.getStatusLine().getStatusCode()==200){            HttpEntity entity = response.getEntity();            String string = EntityUtils.toString(entity, "utf-8");            System.out.println(string);        }        //6.關閉資源        response.close();        httpClient.close();    }

3.OKHttp

給大家推薦一篇文章,個人覺得寫得很好。

https://blog.csdn.net/iispring/article/details/51661195?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

4.RestTemplate

簡介:

RestTemplate 是從 Spring3.0 開始支持的一個 HTTP 請求工具,它提供了常見的REST請求方案的模版,例如 GET 請求、POST 請求、PUT 請求、DELETE 請求以及一些通用的請求執行方法 exchange 以及 execute。

RestTemplate 繼承自 InterceptingHttpAccessor 并且實現了 RestOperations 接口,其中 RestOperations 接口定義了基本的 RESTful 操作,這些操作在 RestTemplate 中都得到了實現。接下來我們就來看看這些操作方法的使用。

Get Demo

public void doHttpGetTest() throws UnsupportedEncodingException {    // -------------------------------> 獲取Rest客戶端實例    RestTemplate restTemplate = new RestTemplate();        // -------------------------------> 解決(響應數據可能)中文亂碼 的問題    List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();    converterList.remove(1); // 移除原來的轉換器    // 設置字符編碼為utf-8    HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);    converterList.add(1, converter); // 添加新的轉換器(注:convert順序錯誤會導致失敗)    restTemplate.setMessageConverters(converterList);        // -------------------------------> (選擇性設置)請求頭信息    // HttpHeaders實現了MultiValueMap接口    HttpHeaders httpHeaders = new HttpHeaders();    // 給請求header中添加一些數據    httpHeaders.add("Java 學習部落", "這是一個學習技術的公眾號!");        // -------------------------------> 注:GET請求 創建HttpEntity時,請求體傳入null即可    // 請求體的類型任選即可;只要保證 請求體 的類型與HttpEntity類的泛型保持一致即可    String httpBody = null;    HttpEntity<String> httpEntity = new HttpEntity<String>(httpBody, httpHeaders);        // -------------------------------> URI    StringBuffer paramsURL = new StringBuffer("http://127.0.0.1:8080/restTemplate/doHttpGet");    // 字符數據最好encoding一下;這樣一來,某些特殊字符才能傳過去(如:flag的參數值就是“&”,不encoding的話,傳不過去)    paramsURL.append("?flag=" + URLEncoder.encode("&", "utf-8"));    URI uri = URI.create(paramsURL.toString());        //  -------------------------------> 執行請求并返回結果    // 此處的泛型  對應 響應體數據   類型;    // 即:這里指定響應體的數據裝配為String    ResponseEntity<String> response =         restTemplate.exchange(uri, HttpMethod.GET, httpEntity, String.class);        // -------------------------------> 響應信息    //響應碼,如:401、302、404、500、200等    System.err.println(response.getStatusCodeValue());    Gson gson = new Gson();    // 響應頭    System.err.println(gson.toJson(response.getHeaders()));    // 響應體    if(response.hasBody()) {      System.err.println(response.getBody());    }      }

Post Demo

public void doHttpPostTest() throws UnsupportedEncodingException {  // 獲取Rest客戶端實例  RestTemplate restTemplate = new RestTemplate();    //  解決(響應數據可能)中文亂碼 的問題  List<HttpMessageConverter<?>> converterList         = restTemplate.getMessageConverters();  converterList.remove(1); // 移除原來的轉換器  // 設置字符編碼為utf-8  HttpMessageConverter<?> converter         = new StringHttpMessageConverter(StandardCharsets.UTF_8);  // 添加新的轉換器(注:convert順序錯誤會導致失敗)  converterList.add(1, converter);   restTemplate.setMessageConverters(converterList);    // (選擇性設置)請求頭信息  // HttpHeaders實現了MultiValueMap接口  HttpHeaders httpHeaders = new HttpHeaders();  // 設置contentType  httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);  // 給請求header中添加一些數據  httpHeaders.add("Java 學習部落", "這是一個學習java的公眾號 !");    // 將請求頭、請求體數據,放入HttpEntity中  // 請求體的類型任選即可;只要保證 請求體 的類型與HttpEntity類的泛型保持一致即可  // 這里手寫了一個json串作為請求體 數據 (實際開發時,可使用fastjson、gson等工具將數據轉化為json串)  String httpBody = "{\"motto\":\"java真強大啊 !\"}";  HttpEntity<String> httpEntity             = new HttpEntity<String>(httpBody, httpHeaders);   // URI  StringBuffer paramsURL         = new StringBuffer("http://127.0.0.1:8080/restTemplate/doHttpPost");  // 字符數據最好encoding一下;這樣一來,某些特殊字符才能傳過去(如:flag的參數值就是“&”,不encoding的話,傳不過去)  paramsURL.append("?flag=" + URLEncoder.encode("&", "utf-8"));  URI uri = URI.create(paramsURL.toString());    // 執行請求并返回結果  // 此處的泛型  對應 響應體數據   類型;即:這里指定響應體的數據裝配為String  ResponseEntity<String> response =       restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);    //  響應信息  //響應碼,如:401、302、404、500、200等  System.err.println(response.getStatusCodeValue());  Gson gson = new Gson();  // 響應頭  System.err.println(gson.toJson(response.getHeaders()));  // 響應體  if(response.hasBody()) {    System.err.println(response.getBody());  }}

此處只是簡單介紹下RestTemplate的Get請求和Post請求,并未深入探討RestTemplate,以及實現RestTemplate的其它形式的請求。

因為我已經迫不及待的想和Fegin來一個美麗的邂逅了。

與Fegin的美麗邂逅

什么是Fegin?

Feign是Netflix開發的聲明式、模板化的HTTP客戶端, Feign可以幫助我們更快捷、優雅地調用HTTP API。

在Spring Cloud中,使用Feign非常簡單:創建一個接口,并在接口上添加一些注解,代碼就完成了。Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等。

Spring Cloud對Feign進行了增強,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,從而讓Feign的使用更加方便。

Spring Cloud Feign是基于Netflix feign實現,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供這兩者的強大功能外,還提供了一種聲明式的Web服務客戶端定義的方式。

Spring Cloud Feign幫助我們定義和實現依賴服務接口的定義。在Spring Cloud feign的實現下,只需要創建一個接口并用注解方式配置它,即可完成服務提供方的接口綁定,簡化了在使用Spring Cloud Ribbon時自行封裝服務調用客戶端的開發量。

Spring Cloud Feign具備可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。

Feign實際上是對普通HTTP客戶端的一層封裝,其目的是降低集成成本、提升可靠性。Feign支持三種HTTP客戶端,包括JDK自帶的HttpURLConnection、Apache HttpClient和Square OkHttp,默認使用Apache HttpClient。

Fegin有什么作用?

Feign可以把Rest的請求進行隱藏,偽裝成類似SpringMVC的Controller一樣。

你不用再自己拼接url,拼接參數等等操作,一切都交給Feign去做。

Netflix Feign還是Open Feign?

在這個時間節點上,很多人對這“兩種”Feign傻傻分不清楚,不知有何區別和聯系,本文將給與告知。首先需要明確:他倆是屬于同一個東西,Feign屬于Netflix開源的組件。針對于于差異性,下面分這幾個方面展開做出對比

1、GAV坐標差異

<dependency><groupId>com.netflix.feign</groupId><artifactId>feign-core</artifactId></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId></dependency>

2、官網地址差異https://github.com/Netflix/feignhttps://github.com/OpenFeign/feign。不過現在訪問https://github.com/Netflix/feign已經被重定向到了后者上。

3、發版歷史

  • Netflix Feign1.0.0發布于2013.6,于2016.7月發布其最后一個版本8.18.0

  • Open Feign:首個版本便是9.0.0版,于2016.7月發布,然后一直持續發布到現在(未停止)

從以上3個特點其實你可以很清楚的看到兩者的區別和聯系,簡單的理解:Netflix Feign僅僅只是改名成為了Open Feign而已,然后Open Feign項目在其基礎上繼續發展至今。

9.0版本之前它叫Netflix Feign,自9.0版本起它改名叫Open Feign了。

但是請注意,雖然GAV完全變了,但是源碼的包名和核心API是沒有任何變化的,所以扔具有很好的向下兼容性(并不是100%向下兼容)。

spring-cloud-starter-feign還是spring-cloud-starter-openfeign?

他倆的差異類似于上述描述的差異,也從幾個方面說明:

1、GAV坐標差異

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

發版歷史

  • spring-cloud-starter-feign:2015.3發布1.0.0版本,2019.5.23發布器最后一個版本1.4.7.RELEASE

    • 值得注意的是,從1.4.0.RELEASE開始,它的1.4.x的發版軌跡完全同下的1.4.x的發版軌跡

  • spring-cloud-starter-openfeign:2017.11發布其首個版本,版本號為:1.4.0.RELEASE。現在仍持續更新中,當下最新版為2.2.1.RELEASE

說明:1.4.7.RELEASE是整個Spring Cloud1.x關于Feign方面的最終版本,2.x版本還在持續維護更新中

注意:老的spring-cloud-starter-feign 1.2.0.RELEASE開始 已放棄Netflix feign而全面使用更新的Open Feign版本,而spring-cloud-starter-openfeign更是和Netflix Feign已經沒有關系了。

如何深入學習SpringCloud Fegin

對于版本,可粗略的理解為:spring-cloud-starter-openfeign是為Spring Cloud2.x準備的,只不過維持了一段時間的對1.x的兼容。而spring-cloud-starter-feign是專為Spring Cloud1.x服務。

核心API包名:Spring Cloud的大版本升級具有向下不兼容性,這也體現在了Feign上:

@FeignClient注解:

說明:這里的1.x不僅僅指的feign,還包括openfeign的1.4.x版本哦

1.x版本包名是org.springframework.cloud.netflix.feign.FeignClient,所在Jar是spring-cloud-netflix-core

2.x版本包名是org.springframework.cloud.openfeign.FeignClient,所在Jar是spring-cloud-openfeign-core

@EnableFeignClients注解:差異同上

    如何深入學習SpringCloud Fegin

                                                                       如何深入學習SpringCloud Fegin

     ----引自:https://cloud.tencent.com/developer/article/1588509


    與Fegin的相知相識

    Fegin 的九大組件

    如何深入學習SpringCloud Fegin

    1.注解翻譯器 Contract 

    我們都知道,在 Feign 中可以通過定義 API 接口的方式來調用遠程的 Http API,在定義調用 Client 的時候需要增加一些注解來描述這個調用 API 的基本信息,比如請求類型是 GET 還是 POST,請求的 URI 是什么。

    Contract 允許用戶自定義注解翻譯器去解析注解信息。

    Contract 決定了哪些注解可以標注在接口/接口方法上是有效的,并且提取出有效的信息,組裝成為MethodMetadata元信息。

    最典型的應用場景就是在 Spring Cloud 中使用 Feign,我們可以使用 Spring MVC 的注解來定義 Feign 的客戶端,就是因為 Spring Cloud OpenFeign 中實現了自己的 SpringMvcContract。

    2.Encoder 編碼器

    將我們的請求信息通過指定的編碼方式進行編碼到Http請求體中進行傳輸。

    3.QueryMapEncoder 參數查詢編碼器

    QueryMapEncoder 是針對實體類參數查詢的編碼器,可以基于 QueryMapEncoder 將實體類生成對應的查詢參數。

    4.Decoder 解碼器

    Decoder 解碼器作用于Response,用于解析Http請求的響應,提取有用信息數據。

    Decoder 解碼器將HTTP響應feign.Response解碼為指定類型的單一對象

    5.ErrorDecoder 錯誤解碼器

    ErrorDecoder 錯誤解碼器是在發生錯誤、異常情況時使用的解碼器,允許你對異常進行特殊處理。

    6.Logger 日志記錄

    Feign自己抽象出來的一個日志記錄器,負責 Feign 中記錄日志的,可以指定 Logger 的級別以及自定義日志的輸出。

    7.Client 請求執行組件

    Client 是負責 HTTP 請求執行的組件,Feign 將請求信息封裝好后會交由 Client 來執行。

    默認情況下,服務之間調用使用的HttpURLConnection,沒有使用連接池,每次使用都會創建HttpURLConnection連接,效率非常低。

    為了通過連接池提高效率,我們可以使用appache httpclient做為連接池。當然了配置OkHttpClient連接池,也是類似的方法。

    8.Retryer 重試組件

    重試并不是報錯以后的重試,而是負載均衡客戶端發現遠程請求實例不可到達后,去重試請求其他實例。

    Feign本身也具備重試能力,在早期的Spring Cloud中,Feign使用的是 feign.Retryer.Default#Default() ,重試5次。

    但Feign整合了Ribbon,Ribbon也有重試的能力,此時,就可能會導致行為的混亂。

    Spring Cloud意識到了此問題,因此做了改進,將Feign的重試改為 feign.Retryer#NEVER_RETRY ,如需使用Feign的重試,只需使用Ribbon的重試配置即可。

    9.RequestInterceptor 請求攔截器

    我們可以通過實現RequestInterceptor接口的apply方法,在請求執行前設置一些擴展的參數信息或者是修改請求頭信息,因為feign在發送請求之前都會調用該接口的apply方法,所以我們也可以通過實現該接口來記錄請求發出去的時間點。

    Fegin 的執行過程

    如何深入學習SpringCloud Fegin

    與Fegin的纏綿悱惻

    Fegin的原生API的使用

    public interface GitHub {  @RequestLine("GET /repos/{owner}/{repo}/contributors")  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repository);  class Contributor {    String login;    int contributions;  }}public class MyApp {  public static void main(String[] args) {    GitHub github = Feign.builder()                         .decoder(new GsonDecoder())                         .target(GitHub.class, "https://api.github.com");    /* The owner and repository parameters will be used to expand the owner and repo expressions     * defined in the RequestLine.     *     * the resulting uri will be https://api.github.com/repos/OpenFeign/feign/contributors     */    github.contributors("OpenFeign", "feign");  }}

    這段代碼是我從 OpenFeign 的 GitHub 主頁上示例代碼。

    這是一個 GET 請求的示列,定義了一個 GitHub 的接口,接口中定義了一個查詢的方法和參數。在方法上有 @RequestLine 注解,定義了請求類型和請求的 URI,URI 中有對應的參數占位符,返回值是集合,集合中是對應的返回結構對象。

    我們通過 Feign 的 builder 模式構建了 GitHub 接口對象后,就可以直接通過 GiuHub 接口對象調用里面的 contributors 方法,然后可以得到返回結果。Feign 的這種方式就跟 Dubbo 中的調用方式是一樣的,就像調用本地方法一樣。

    使用原生的 Feign 來調用 API,只需要通過特定的注解來描述調用的 API 信息,這些信息的請求方式可以是 GET 或者 POST 等,請求參數是什么?請求的地址是什么? 把這些信息定義好后就可以直接使用這個定好了的接口來調用對應的遠程 API。

    Fegin結合SpringCloud使用

    1.首先創建一個OpenFeginClient模塊,pom.xml代碼如下:

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

    2.在啟動類上添加 @EnableFeignClients 啟用 Feign

    package com.javaer.study.openfeginclient;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;/** * @Author 公眾號【Java學習部落】 * * 關注公眾號獲取4000G精品視頻資源 * * 更有更多學習Java后端、中間件,大數據、微服務、分布式、大數據等學習干貨 **/@SpringBootApplication@EnableFeignClients@EnableEurekaClientpublic class OpenfeginclientApplication {    public static void main(String[] args) {        SpringApplication.run(OpenfeginclientApplication.class, args);    }}
    3.配置appliation.yml 注冊到Eureka Server。
    server:  port: 8888spring:  application:    name: spring-cloud-feign-openClienteureka:  client:    service-url:      defaultZone: http://localhost:8761/eureka/
    4.使用@FeignClient為本應用聲明一個簡單的能調用的客戶端。為了方便,我們依然使用Github開放的api。
    package com.javaer.study.openfeginclient;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;/** * 一個可以調用的客戶端 * * @author topJavaer * 公眾號:【Java學習部落】 * @create 2020 11 10 * @Version 1.0.0 *///@FeignClient 即是指定客戶端信息注解,務必聲明在接口上面,url手動指定了客戶端的接口地址@FeignClient(name = "github-client", url = "https://api.github.com")public interface GitHubApiClient {    @RequestMapping(value = "/search/repositories", method = RequestMethod.GET)    String searchRepositories(@RequestParam("q") String queryStr);}

    5.添加測試代碼

    package com.javaer.study.openfeginclient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/** * 測試類 * * @author topJavaer * 公眾號:【Java學習部落】 * @create 2020 11 10 * @Version 1.0.0 */@RestControllerpublic class GitHubApiTest {    @Resource    private GitHubApiClient gitHubApiClient;    @RequestMapping("/search/github/repository")    public String searchGithubRepositoryByName(@RequestParam("name") String repositoryName) {        return gitHubApiClient.searchRepositories(repositoryName);    }}

    6.最后我們啟動之前再講述Eureka時編寫的Eureka Server,然后啟動該模塊。

    訪問:http://localhost:8888/search/github/repository?name=spring-cloud-dubbo

    得到如下結果:

    如何深入學習SpringCloud Fegin

    上述就是Spring Cloud 使用OpenFegin的基本流程,是不是很簡單,看一眼,操作一遍,立馬就會了,當然了,如果說想要深入了解,僅僅這樣是遠遠不夠的,還是需要大家自己繼續去專研,去深入探究。

    Fegin的核心注解@FeignClient詳解

    package org.springframework.cloud.netflix.feign; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FeignClient {   @AliasFor("name") String value() default "";   @Deprecated String serviceId() default "";  @AliasFor("value")   String name() default "";   String qualifier() default "";   String url() default "";   boolean decode404() default false;   Class<?>[] configuration() default {};   Class<?> fallback() default void.class;   Class<?> fallbackFactory() default void.class;   String path() default "";   boolean primary() default true; }

    name: 指定Feign Client的名稱,如果項目使用了 Ribbon,name屬性會作為微服務的名稱,用于服務發現。

    serviceId: 用serviceId做服務發現已經被廢棄,所以不推薦使用該配置。

    value: 指定Feign Client的serviceId,如果項目使用了 Ribbon,將使用serviceId用于服務發現,但上面可以看到serviceId做服務發現已經被廢棄,所以也不推薦使用該配置。

    qualifier: 為Feign Client 新增注解@Qualifier

    url: 請求地址的絕對URL,或者解析的主機名

    decode404: 調用該feign client發生了常見的404錯誤時,是否調用decoder進行解碼異常信息返回,否則拋出FeignException。

    fallback: 定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback 指定的類必須實現@FeignClient標記的接口。實現的法方法即對應接口的容錯處理邏輯。

    fallbackFactory: 工廠類,用于生成fallback 類示例,通過這個屬性我們可以實現每個接口通用的容錯邏輯,減少重復的代碼。

    path: 定義當前FeignClient的所有方法映射加統一前綴。

    primary: 是否將此Feign代理標記為一個Primary Bean,默認為ture

    Fegin的核心配置

    Fegin的配置方式有兩種。

    一種是Java 代碼配置,需要在主程序啟動入口用@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.java)來引用配置。

    第二種是直接配置文件配置,在application.yml或者application.properties中配置。

    我們應該知道的是,如果通過Java代碼的方式配置 Feign,然后有通過屬性文件的方式配置Feign,屬性文件中的Frign的配置會覆蓋Java代碼的配置。

    但是可以配置 feign.client.default-to-properties=fasle來改變Feign配置生效的優先級。

    本文主要講解一些日常常用的配置,通過配置文件。

    Spring Cloud Feign 支持請求和響應進行GZIP壓縮來提高通信效率。

          # 開啟GZIP壓縮配置      #請求GZIP壓縮      feign.compression.request.enable=true                       #響應GIZP壓縮      feign.compression.response.enable=true                    #壓縮支持的mime type      feign.compression.request.mime-types=text/xml,application/xml.application/json                        feign.compression.request.min-request-size=1024               #壓縮數據大小的最小值

    Feign 為每一個FeignClient都提供了feign.logger實例,可在配置中或者java代碼中開啟日志。

    NONE 表示不輸出日志。BASIC 表示只輸出請求方法的 URL 和響應的狀態碼以及執行的時間。HEADERS 將 BASIC 信息和請求頭信息輸出。FULL 會輸出全部完整的請求信息。
    logging:  level:    com.javaer.study: debugfeign:  client:    config:      # 要調用服務的名稱      java-master:        loggerLevel: full

    Fegin的超時配置

    Ribbon 超時配置

    當系統出現Read time out,說明是 Ribbon 超時了,需要在配置文件中進行控制處理

    ### Ribbon 配置ribbon:  # 連接超時  ConnectTimeout: 2000  # 響應超時  ReadTimeout: 5000

    Hystrix 超時配置

    Fegin 高版本的 Hystrix 默認是關閉的。需要以下配置開啟:

    ### Feign 配置feign:  # 開啟斷路器(熔斷器)  hystrix:    enabled: true

    為了避免超時,我們可以根據業務情況來配置自己的超時時間,此處配置熔斷時間為:5000/毫秒。

    注意:建議 Ribbon 的超時時間不要大于 Hystrix 的超時時間

    ### Hystrix 配置hystrix:  # 這樣將會自動配置一個 Hystrix 并發策略插件的 hook,這個 hook 會將 SecurityContext 從主線程傳輸到 Hystrix 的命令。  # 因為 Hystrix 不允許注冊多個 Hystrix 策略,所以可以聲明 HystrixConcurrencyStrategy  # 為一個 Spring bean 來實現擴展。Spring Cloud 會在 Spring 的上下文中查找你的實現,并將其包裝在自己的插件中。  shareSecurityContext: true  command:    default:      circuitBreaker:        # 當在配置時間窗口內達到此數量的失敗后,進行短路。默認20個        requestVolumeThreshold: 1        # 觸發短路的時間值,當該值設為5000時,則當觸發 circuit break 后的5000毫秒內都會拒絕request        # 也就是5000毫秒后才會關閉circuit。默認5000        sleepWindowInMilliseconds: 15000        # 強制打開熔斷器,如果打開這個開關,那么拒絕所有request,默認false        forceOpen: false        # 強制關閉熔斷器 如果這個開關打開,circuit將一直關閉且忽略,默認false        forceClosed: false      execution:        isolation:          thread:            # 熔斷器超時時間,默認:1000/毫秒            timeoutInMilliseconds: 5000

    Fegin的繼承特性

    Spring Cloud Feign提供了繼承特性,所謂的繼承特性就是將一些公共操作提取到一個父接口中,從而繼承父接口中的操作,減少代碼的重復開發,節約開發成本。

    1、優點

        可以將接口的定義從 Controller 中剝離,同時配合 Maven 私有倉庫就可以輕易地實現接口定義的共享,不用再復制粘貼接口進行綁定,而是實現在構建期的接口綁定,從而有效減少服務客戶端的綁定配置。

    2、缺點

        由于接口在構建期間就建立起了依賴,那么接口變動就會對項目構建造成影響,可能服務提供方修改了一個接口定義,那么會直接導致客戶端工程的構建失敗。

        所以,如果開發團隊通過此方法來實現接口共享的話,建議在開發評審期間嚴格遵守面向對象的開閉原則,盡可能地做好前后版本的兼容,防止牽一發而動全身的后果,增加團隊不必要的維護工作量。

    Fegin重試機制

    在 Spring Cloud Feign 中默認實現了請求的重試機制,下面配置作用是:當訪問到故障請求的時候,它會再嘗試訪問一次當前實例(次數由 MaxAutoRetries 配置),如果不行,就換一個實例進行訪問,如果還不行,再換一次實例訪問(更換次數由 MaxAutoRetriesNextServer 配置),如果依然不行,返回失敗信息。

    注意Ribbon 的超時與 Hystrix 的超時是兩個概念。為了讓上述實現有效,我們需要讓 Hystrix 的超時時間大于 Ribbon 的超時時間,否則 Hystrix 命令超時后,該命令直接熔斷,重試機制就沒有任何意義了。

    #斷路器的超時時長需要大于Ribbon的超時時間,不然不會觸發重試hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000#請求連接超時時間fegin-service.ribbon.ConnectTimeout=500#請求處理的超時時間fegin-service.ribbon.ReadTimeout=1000#對所有請求都進行重試(是否所有操作都重試,若false則僅get請求重試)fegin-service.ribbon.OkToRetryOnAllOperations=true#對當前實例的重試次數fegin-service.ribbon.MaxAutoRetries=1#切換實例的重試次數fegin-service.ribbon.MaxAutoRetriesNextServer=2

    到此,相信大家對“如何深入學習SpringCloud Fegin”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    库尔勒市| 新密市| 蓬溪县| 淮南市| 确山县| 阿坝| 武鸣县| 南靖县| 徐汇区| 哈巴河县| 吉首市| 顺平县| 青海省| 广昌县| 涞水县| 济宁市| 赞皇县| 米易县| 静宁县| 锦州市| 宁国市| 广水市| 京山县| 西乡县| 册亨县| 上林县| 廉江市| 泰和县| 海门市| 海兴县| 富顺县| 红原县| 含山县| 阿图什市| 南投县| 长沙县| SHOW| 宣汉县| 霍林郭勒市| 同心县| 铜山县|