Spring Cloud --- リモート呼び出しを装う

1.RestTemplateの問題

まず、RestTemplate を使用してリモート呼び出しを開始するために使用したコードを見てみましょう。

以下の問題があります。

  • コードの可読性が低く、プログラミング エクスペリエンスに一貫性がない
  • 複雑なパラメータを持つ URL は保守が困難です

Feign は宣言型 http クライアントです。公式アドレス: GitHub - OpenFeign/feign: Feign を使用すると Java http クライアントの作成が簡単になります

その役割は、http リクエストの送信をエレガントに実装し、上記の問題を解決するのに役立ちます。

 

 

2. Feign が RestTemplate を置き換える

Feginを使用する手順は次のとおりです。

1) 依存関係を導入する


order-service サービスの pom ファイルに偽の依存関係を導入します。

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

2) 注釈を追加する


order-service のスタートアップ クラスにアノテーションを追加して、Feign の機能を有効にします。


3) Feign のクライアントを書く


次の内容を含む新しいインターフェイスを order-service に作成します。

package cn.itcast.order.client;

import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

このクライアントは主に SpringMVC アノテーションに基づいて、次のようなリモート呼び出し情報を宣言します。

  • サービス名: ユーザーサービス

  • リクエストメソッド:GET

  • リクエストパス: /user/{id}

  • リクエストパラメータ: 長い ID

  • 戻り値の型: ユーザー

このように、Feign は、RestTemplate を使用せずに http リクエストを送信するのに役立ちます。


4) テスト


order-service の OrderService クラスの queryOrderById メソッドを変更し、RestTemplate の代わりに Feign クライアントを使用します。

よりエレガントに見えませんか。


5) まとめ


Feign を使用する手順:

  1. 依存関係を導入する
  2. @EnableFeignClients アノテーションを追加
  3. FeignClient インターフェースを作成する
  4. RestTemplate の代わりに FeignClient で定義されたメソッドを使用する

 

 

3. カスタム構成

Feign は、次の表に示すように、多くのカスタム構成をサポートできます。

タイプ 効果 説明する
偽りのロガーレベル ログレベルの変更 4 つの異なるレベルが含まれます: NONE、BASIC、HEADERS、FULL
feign.codec.Decoder 応答結果のパーサー json 文字列を Java オブジェクトに解析するなど、http リモート呼び出しの結果を解析します。
feign.codec.Encoder リクエストパラメータのエンコーディング http リクエスト経由で送信するためのリクエスト パラメータをエンコードする
ふりをする。契約 サポートされている注釈形式 デフォルトはSpringMVCのアノテーションです
ふりをする。リトライアー 失敗時の再試行メカニズム リクエスト失敗時の再試行メカニズム。デフォルトは「いいえ」ですが、リボンの再試行が使用されます。

通常はデフォルト値で十分ですが、カスタマイズする場合は、カスタム @Bean を作成してデフォルト Bean をオーバーライドするだけです。

以下では、例としてログを使用して、構成をカスタマイズする方法を示します。

設定ファイル方式


構成ファイルに基づいて feign のログ レベルを変更すると、単一のサービスを対象にすることができます。

feign:  
  client:
    config: 
      userservice: # 针对某个微服务的配置
        loggerLevel: FULL #  日志级别 

すべてのサービスをターゲットにすることもできます。

feign:  
  client:
    config: 
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别 

ログレベルは次の 4 種類に分類されます。

  • NONE: ログ情報を記録しません。これがデフォルト値です。

  • BASIC: リクエストメソッド、URL、レスポンスステータスコード、実行時間のみをログに記録します。

  • HEADERS: BASICをベースに、リクエストとレスポンスのヘッダ情報を追加記録します。

  • FULL: ヘッダー情報、リクエスト本文、メタデータを含む、すべてのリクエストとレスポンスの詳細を記録します。


Javaコードメソッド


Java コードに基づいてログ レベルを変更することもできます。最初にクラスを宣言し、次に Logger.Level オブジェクトを宣言します。

public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志级别为BASIC
    }
}

グローバルに有効にしたい場合は、スタートアップ クラスの @EnableFeignClients アノテーションに追加します。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 

ローカルで有効な場合は、対応する @FeignClient アノテーションに入れます。

@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 

 

 

4、偽使用の最適化

Feign の最下層は http リクエストを開始し、他のフレームワークに依存します。その基礎となるクライアント実装には次のものが含まれます。

  • URLConnection: デフォルトの実装、接続プーリングをサポートしません
  • Apache HttpClient: 接続プールのサポート
  • OKHttp: 接続プールのサポート

したがって、Feign のパフォーマンスを向上させる主な手段は、デフォルトの URLConnection の代わりに接続プールを使用することです。

ここでは、Apache の HttpClient を使用してデモンストレーションします。

1) 依存関係を導入する

order-service の pom ファイルに Apache の HttpClient 依存関係を導入します。

<!--httpClient的依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

2) 接続プールを構成する

order-service の application.yml に設定を追加します。

feign:
  client:
    config:
      default: # default全局的配置
        loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 50 # 每个路径的最大连接数

次に、FeignClientFactoryBean のloadBalance メソッドを中断します。

デバッグ モードで order-service サービスを開始します。ここにクライアントが表示されます。最下層は Apache HttpClient です。

要約すると、Feign の最適化は次のようになります。

1. ログレベルとしてベーシックを使用してみます。

2. URLConnection の代わりに HttpClient または OKHttp を使用します。

  • feign-httpClient 依存関係を導入する
  • 構成ファイルは httpClient 機能を有効にし、接続プールのパラメータを設定します。

 

 

5. ベストプラクティス

いわゆる最近の実践とは、使用プロセス中に要約された経験、つまりそれを使用する最良の方法を指します。

自己調査によると、Feign のクライアントはサービス プロバイダーのコントローラー コードと非常によく似ていることがわかりました。

偽のクライアント:

ユーザーコントローラー:

この繰り返しのコーディングを簡素化する方法はあるでしょうか?

 

5.1. 継承方法

同じコードは継承を通じて共有できます。

1) API インターフェースを定義し、定義メソッドを使用し、SpringMVC アノテーションに基づいてステートメントを作成します。

2) Feign クライアントとコントローラーの両方がインターフェースを統合します

アドバンテージ:

  • 単純

  • コードシェア

欠点:

  • サービスプロバイダーとサービスコンシューマーは密接に結合されています

  • パラメータリストのアノテーションマッピングは継承されないため、メソッド、パラメータリスト、アノテーションをコントローラで再度宣言する必要があります。

  

5.2. 抽出方法

Feign のクライアントを独立したモジュールとして抽出し、インターフェイス関連の POJO とデフォルトの Feign 設定をすべてのコンシューマーが使用できるようにこのモジュールに組み込みます。

たとえば、UserClient、User、および Feign のデフォルト構成はすべて feign-api パッケージに抽出され、この依存関係パッケージを参照することですべてのマイクロサービスを直接使用できます。

 

5.3. 抽出ベースのベストプラクティスの実装

1) 抽出


まず、feign-api という名前のモジュールを作成します。

プロジェクトの構造:

 

feign-api で、feign のスターター依存関係を導入します。

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

次に、order-service に記述された UserClient、User、DefaultFeignConfiguration がすべて feign-api プロジェクトにコピーされます

 


2) order-service で feign-api を使用する


まず、order-service 内の UserClient、User、DefaultFeignConfiguration などのクラスまたはインターフェイスを削除します。

   

order-service の pom ファイルに feign-api の依存関係を導入します。

<dependency>
    <groupId>cn.itcast.demo</groupId>
    <artifactId>feign-api</artifactId>
    <version>1.0</version>
</dependency>

order-service の上記 3 つのコンポーネントに関連するパッケージのインポート部分をすべて変更し、feign-api でパッケージをインポートするように変更します。


3) テストを再開します


再起動後、サービスがエラーを報告したことが判明しました。

これは、UserClient が cn.itcast.feign.clients パッケージの下にあるためです。

order-service の @EnableFeignClients アノテーションは、同じパッケージ内ではなく cn.itcast.order パッケージの下にあるため、UserClient をスキャンできません。


4) パッケージのスキャンの問題を解決する


方法 1:

Feign がスキャンする必要があるパッケージを指定します。

@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

方法 2:

ロードする必要があるクライアント インターフェイスを指定します。

@EnableFeignClients(clients = {UserClient.class})

おすすめ

転載: blog.csdn.net/a1404359447/article/details/130347567