記事ディレクトリ
OpenFeignの概要
オープンフェインとは何ですか?
Spring Cloud OpenFeign は Spring Cloud エコシステムの一部であり、RESTful サービスを呼び出すための宣言的かつ簡素化された方法を提供します。これにより、開発者は注釈とインターフェイス定義を使用してサービス リクエストを記述することができ、これらのリクエストを処理するクライアント コードが自動的に生成されます。
Spring Cloud OpenFeign を使用すると、開発者はインターフェイスを定義するだけでリモート サービスを呼び出すことができます。開発者は @GetMapping や @PostMapping などの Spring MVC アノテーションを使用するだけでインターフェイスを定義でき、OpenFeign はこれらのインターフェイスを RESTful サービスに自動的にマッピングできます。開発者は、フォールバック機能を使用してリモート サービスの障害を処理することもできます。
Spring Cloud OpenFeign は、サービス検出や負荷分散などの他の機能も提供します。これらの機能は、分散システムで使用するために、Eureka、Consul、Zookeeper などのサービス レジストリと統合できます。
RestTemplate を使用して呼び出すために OpenFeign が必要な理由
前の章では、Ribbon+RestTemplate を使用してサービスのリモート呼び出しを実現しましたが、多くの欠点がありました。
- 宣言型 Web サービス クライアント: OpenFeign を使用すると、開発者は注釈を使用して RESTful サービスへのリクエストを定義でき、多くの定型コードを記述する必要がなくなります。これにより、コードがより簡潔になり、理解しやすく、保守しやすくなります。
- より高いレベルの抽象化: OpenFeign は RestTemplate よりも高いレベルの抽象化を備えています。開発者は、単純なインターフェイスを作成し、アノテーションを使用してリクエストを定義するだけでよく、基礎となる HTTP リクエストとレスポンスの処理を気にする必要はありません。これにより、コードの作成、テスト、保守が容易になります。
- RESTful サービスの自動マッピング: OpenFeign は、インターフェイスを RESTful サービスに自動的にマッピングできるため、開発者が記述する必要がある定型コードの量が削減されます。これにより、コードがシンプルになり、保守が容易になり、バグが少なくなります。
- サーキット ブレーカー パターンのサポート: OpenFeign は、Hystrix などのサーキット ブレーカー ライブラリと統合して、リモート サービスが失敗した場合のフォールバック処理を提供できます。これにより、システムの堅牢性と信頼性が向上し、サービスの高可用性が保証されます。
- エンコードとデコードのサポート: OpenFeign は、JSON、XML などの複数のエンコードおよびデコード形式をサポートします。これにより、データ送信がより柔軟になり、より多くのアプリケーション シナリオをサポートできるようになります。
Feign と OpenFeign の違い
-
基礎となる実装: OpenFeign は Spring Cloud と Spring MVC に依存していますが、Feign は Netflix のオープンソース プロジェクトに依存しています。
-
アノテーションのサポート: OpenFeign は @RequestParam、@RequestBody などの Spring MVC アノテーションをサポートしますが、Feign は独自のアノテーションを使用する必要があります。
-
カスタム コントラクト: OpenFeign はカスタム コントラクトを実装することで拡張およびカスタマイズできますが、Feign にはそのような拡張メソッドがありません。
-
サーキット ブレーカーのサポート: OpenFeign は Hystrix を統合しますが、Feign はサーキット ブレーカーのサポートを実装するために Hystrix を別途導入する必要があります。
-
インターセプタのサポート: OpenFeign は、より柔軟で包括的な HTTP リクエストと応答のインターセプタ サポートを提供します。これにより、リクエストと応答のよりきめ細かい処理を実行できますが、Feign のインターセプタ サポートは比較的小規模です。
OpenFeign は、基礎となる実装、アノテーションのサポート、カスタム コントラクト、サーキット ブレーカーのサポート、およびインターセプターのサポートの点で Feign とは異なります。特定のビジネス ニーズと開発の背景に応じて、RESTful サービスを開発して呼び出すための適切なフレームワークを選択します。
OpenFeign の使用方法
デモビルド
新しい呼び出しサービス モジュールを作成するか、認証サービス (RestTemplate から OpenFeign に変更する特定のサービス呼び出し) を参照します。
- 認証サービスをコピーする
- pom.xml
の違いは主に、openfeign 依存関係の追加です。
<dependencies>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--一般基础通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.yml は、
認証サービスのコピーを変更せずに直接コピーします。
server:
port: 9002
spring:
application:
name: lf-auth
eureka:
instance:
# 配置eureka的状态显示
hostname: localhost
instance-id: ${
eureka.instance.hostname}:${
spring.application.name}:${
server.port}
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
スタートアップ クラス
は主に @EnableFeignClients アノテーションを追加します。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignAuthApplication {
public static void main(String[] args) {
SpringApplication.run(FeignAuthApplication.class,args);
}
}
サービス インターフェイス ビジネス
ロジック インターフェイス + @FeignClient 構成を通じて LF-USER サービスを呼び出すためのアノテーション @FeignClient を追加します
@FeignClient(value = "LF-USER")
public interface AuthService {
@GetMapping("/user/info/{username}")
String getUserInfo(@PathVariable("username") String username);
}
コントローラ
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
AuthService authService;
@PostMapping("login")
public String login(@RequestBody String name)
{
return authService.getUserInfo(name);
}
}
テスト
まずはサービスを起動し、各サービスにeurekaサーバーが正常に登録されていることを確認してください。
通話インターフェイスのテストが成功しました
タイムアウトを装う
以下の図に示すように、OpenFeign にはデフォルトのタイムアウト時間が設定されており、ソース
コードを確認してください。デフォルトの接続タイムアウト時間は 10 秒、読み取りタイムアウト時間は 60 秒です。 ;
テストのタイムアウト
このテストでは、ポート 9001 上のユーザー サーバーに 3 秒の遅延を追加します。そしてこのサーバーのみを起動してください。
その結果、エラーがタイムアウトしたことが分かります。
スリープを 3 秒間設定しただけでタイムアウトが報告されるのはなぜですか? 上記の接続タイムアウトと読み取りタイムアウトには程遠いです。実際、openFeign はリボンを統合しています. デフォルトのリボンのタイムアウト接続時間と読み取りタイムアウト時間は 1 秒です. ソースコードは次のとおりです:
openFeign のデフォルトのタイムアウトが設定されていない場合は、Ribbon のタイムアウトが適用されます。
タイムアウトを設定する
リボンのタイムアウトを設定する (推奨されません)
lf-feign-auth サービスの yml ファイルを変更する
ribbon:
# 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间
ReadTimeout: 5000
# 指的是建立链接后从服务器读取可用资源所用的时间
ConectTimeout: 5000
テストの成功:
偽装のタイムアウトを設定する (推奨)
feign:
client:
config:
## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
default:
connectTimeout: 5000
readTimeout: 5000
同じテストは成功します。
偽装のタイムアウト期間を設定することが推奨される理由
OpenFeign では、タイムアウトはクライアントの構成ファイルで指定されます。この構成ファイルでは、サービス インスタンスごとに個別のタイムアウトを設定できます。これにより、サービス インスタンスごとに応答時間が異なる可能性があるため、タイムアウトをより正確に制御できるようになります。リボンでタイムアウト期間が設定されている場合、応答時間が長いサービス インスタンスにリクエストが割り当てられる可能性があり、その結果、リクエストがタイムアウトになり、タイムリーな応答を取得できなくなります。
さらに、負荷分散にリボンが使用されている場合、タイムアウト期間はリボンの再試行メカニズムの影響も受けます。デフォルトでは、リボンは 5 回再試行し、再試行の間隔は徐々に長くなります。タイムアウト期間が設定されているにもかかわらずリクエストが再試行され続けると、タイムアウト期間が延長され、アプリケーションのパフォーマンスと安定性に影響を与える可能性があります。
したがって、タイムアウト時間をより正確に制御し、リボンの再試行メカニズムの影響を避けるために、OpenFeign でタイムアウト時間を設定することをお勧めします。
代替の HTTP クライアント:
デフォルトでは、openFeign は JDK のネイティブ URLConnection を使用して HTTP リクエストを送信し、接続プールはありませんが、アドレスごとに長い接続が維持される、つまり HTTP の永続接続が使用されます。運用環境では、デフォルトの http クライアントは通常使用されません。通常は 2 つのオプションがあります: ApacheHttpClient または OkHttp を使用します。どちらにも独自の長所と短所があります。pom.xml を変更して次の依存関係を追加し
ます
。
<!-- 使用 Apache HttpClient 替换 Feign原生httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
OpenFeignログ印刷機能
openFeign はログ拡張機能を提供しますが、デフォルトではログは表示されませんが、デバッグ段階で開発者が自分でログ レベルを設定できます。
openFeign のログ レベルは次のとおりです。
- NONE: デフォルト、ログを表示しません。
- BASIC: リクエストメソッド、URL、レスポンスステータスコード、実行時間のみを記録します。
- HEADERS: BASIC で定義された情報に加えて、リクエストおよびレスポンスのヘッダー情報があります。
- FULL: HEADERS で定義された情報に加えて、リクエストおよびレスポンスの本文とメタデータがあります。
構成ログ
次のように、構成クラスをカスタマイズし、ログ レベルを設定します。
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
application.yml を変更して
構成を追加します
logging:
level:
# feign日志以什么级别监控哪个接口
com.lufei.springcloud.service: debug
テスト効果
リクエストヘッダーとリクエストボディの内容がログに詳細に出力されます。