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 を使用する手順:
- 依存関係を導入する
- @EnableFeignClients アノテーションを追加
- FeignClient インターフェースを作成する
- 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})