目次
1. SpringBoot は Feign を迅速に統合します
応答タイプに適切な HttpMessageConverter が見つかりません
この章では、主要な目標とユーザー指向について説明します。
この章の目的 | ふりの原理を理解する ふりの使い方をマスターする feign のさまざまなヘッダーを設定する方法を学ぶ ログ制御を装う方法を学ぶ 高度な設定項目を理解する その他の開発上の考慮事項 |
ユーザー指向の | 研究開発初級者、中級者、上級者 |
高レベル アーキテクチャの学生が Http サービス呼び出しを作成しているとき、コードをデバッグおよび追跡するときに、インターフェイス署名だけがあり、okhttp のような呼び出しプロセス コードを記述していないことがよくわかります。この記事を読んだ後、実装計画をマスターし、実際の戦闘を完了するのに役立つデモを提供します。技術的な質問がある場合は、プライベート メッセージでアドバイスを求めることができます。
1. SpringBoot は Feign を迅速に統合します
1.Pom 依存関係を追加する
<properties>
<spring-cloud-feign.version>3.1.3</spring-cloud-feign.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring-cloud-feign.version}</version>
</dependency>
</dependencies>
2. スタートアップ クラスにアノテーションを追加する
@EnableFeignClients
3. レファレンスフェイクサービス
@RestController
@RequestMapping("/stock")
public class StockController {
@Autowired
private LocalFeignService service;
@GetMapping("/get")
public String get(){
service.add("10");
return "Hello world";
}
}
2. リクエストにヘッダーを追加する 3 つの方法
1. 固定ヘッダーを追加する
@RestController
public class HomeController {
@Resource
private FeignClientService feignClientService;
@RequestMapping(value = "/add")
public String add(@RequestBody FeignReq req) {
return "ok";
}
@RequestMapping("/test-add")
public Object testAdd() {
FeignReq req = new FeignReq();
req.setId(System.currentTimeMillis());
return feignClientService.add(req);
}
}
@PostMapping アノテーションの headers パラメーターに固定ヘッダー値を追加し、構成ファイルから読み取られたいくつかの構成項目もヘッダー値として含めます
@Component
@FeignClient(name = "feignClientService", url = "http://localhost:8081")
public interface FeignClientService {
@PostMapping(value = "/add", headers = {"Authorization=myFeignSignToken", "Content-Type=text/plain", "App=${my.name}"})
public String add(@RequestBody FeignReq req);
}
ブラウザアクセス: http://localhost:8081/test-add
2. インターフェイス署名を通じてヘッダーを追加します
@RestController
public class HomeController {
@Resource
private FeignClientService feignClientService;
@PostMapping(value = "/query")
public String query(@RequestParam("queryName") String queryName) {
return queryName + "ok";
}
@RequestMapping("/test-query")
public Object testQuery() {
Map<String, String> map = new HashMap<>();
map.put("token", "ikong_token"+System.currentTimeMillis());
return feignClientService.query("ikong", map);
}
}
Map 型のヘッダーに焦点を当てています。ここでは、Map オブジェクトは、インターフェイス署名の @RequestHeader アノテーションを通じてリクエスト ヘッダーに変換されます。
@Component
@FeignClient(name = "feignClientService", url = "http://localhost:8081", configuration = TestRequestInterceptor.class)
public interface FeignClientService {
@PostMapping(value = "/query")
public String query(@RequestParam("queryName") String queryName, @RequestHeader Map<String, String> headers);
}
ブラウザアクセス: http://localhost:8081/test-query
3. ヘッダーを動的に追加する
@RestController
public class HomeController {
@Resource
private FeignClientService feignClientService;
@RequestMapping("/search")
public Object search(@RequestBody FeignReq req) {
return "ok";
}
@RequestMapping("/test-search")
public Object testSearch() {
FeignReq req = new FeignReq();
req.setId(System.currentTimeMillis());
return feignClientService.search(req);
}
}
@Component
@FeignClient(name = "feignClientService", url = "http://localhost:8081", configuration = TestRequestInterceptor.class)
public interface FeignClientService {
@PostMapping("/search")
public String search(@RequestBody FeignReq req);
}
FeignClientアノテーションによりconfiguration = TestRequestInterceptor.classを注入し、TestRequestInterceptorでのヘッダ動的追加機能を実現
public class TestRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
template.header(HttpHeaders.AUTHORIZATION, createApiSign());
}
/**
* 创建接口签名
*
* @return
*/
private String createApiSign() {
return UUID.randomUUID().toString();
}
}
ブラウザアクセス: http://localhost:8081/test-search
3. リクエストにタイムアウト設定を追加します。
1. デフォルトのタイムアウト
接続タイムアウト: 10秒、読み取りタイムアウト: 60秒
public static class Options {
private final int connectTimeoutMillis;
private final int readTimeoutMillis;
public Options(int connectTimeoutMillis, int readTimeoutMillis) {
this.connectTimeoutMillis = connectTimeoutMillis;
this.readTimeoutMillis = readTimeoutMillis;
}
public Options() {
this(10 * 1000, 60 * 1000);
}
/**
* Defaults to 10 seconds. {@code 0} implies no timeout.
*
* @see java.net.HttpURLConnection#getConnectTimeout()
*/
public int connectTimeoutMillis() {
return connectTimeoutMillis;
}
/**
* Defaults to 60 seconds. {@code 0} implies no timeout.
*
* @see java.net.HttpURLConnection#getReadTimeout()
*/
public int readTimeoutMillis() {
return readTimeoutMillis;
}
}
3. タイムアウト例外
exception:feign.RetryableException: connect timed out executing POST http://xxx.ik.com/your/api
4. グローバルタイムアウト設定
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=5000
5. 個々のサービスのタイムアウト構成を設定する
さまざまなサービスにさまざまなタイムアウトを実装するには、次のように構成できます。
feign.client.config.yourService.connectTimeout=5
feign.client.config.yourService.readTimeout=5
4. リクエストのクライアント負荷分散モードを構成します。
OpenFeign は単なる REST クライアントであり、負荷分散操作はありません。 OpenFeign の最下層は引き続き Netflix リボン負荷分散コンポーネントを呼び出します。では、OpenFeign を使用してサービス呼び出しを実装する場合、負荷分散戦略をどのように変更すればよいでしょうか?
リボンの負荷分散構成をカスタマイズする
@Configuration
// name为服务名
@RibbonClient(name = "my-provider", configuration = MyLoadBalanceConfiguration.class)
public class MyLoadBalanceConfiguration {
@Bean
public IRule ribbonRule() {
return new RandomRule(); // 采用随机策略
}
}
ここではランダム戦略を使用していますが、デフォルトはラウンドロビン戦略です。
リボンはオプションの負荷分散分類を提供します
- ランダム戦略- RandomRule
- ポーリング戦略- RoundRobinRule 注: リボンのデフォルト戦略
- 再試行戦略- RetryRule
- 最小同時実行ポリシー- BestAvailableRule
- 利用可能なフィルタリング戦略- AvailabilityFilteringRule は、継続的な接続障害により回線トリップとしてマークされたバックエンド サーバーをフィルタリングし、同時実行性が高い (アクティブな接続が設定されたしきい値を超えている) バックエンド サーバーをフィルタリングします。パフォーマンスは、最も低い同時実行戦略。
- 応答時間の重み付け戦略——WeightedResponseTimeRule では、サーバーの応答時間を 30 秒ごとに計算し、応答時間を重みとして使用します。応答時間が短いほど、選択される確率が高くなります。
- ゾーン トレードオフ戦略——ZoneAvoidanceRule
リボンの負荷分散戦略を使用する場合の提案
一般に、デフォルトのポーリング戦略よりもパフォーマンスがはるかに高い、最も低い同時実行戦略を使用することをお勧めします。
5、偽ログ
Feign のログはデバッグ ログ モードに基づいています。グローバル設定またはローカル設定、コード設定またはプロパティ設定のいずれであっても、最初にログ モードをデバッグ モードに変更する必要があります (以下は、ログ モードの呼び出しの例です)。 FeignClientService インターフェース)
1. ログレベル
OpenFeign のログ レベルは次のとおりです。
NONE: デフォルトでは、ログは表示されません。
BASIC: リクエスト メソッド、URL、レスポンス ステータス コード、および実行時間のみをログに記録します。
ヘッダー: BASIC のカスタム情報に加えて、要求ヘッダーと応答ヘッダーがあります。
FULL: HEADERS で定義された情報に加えて、リクエストおよびレスポンスの本文とメタデータがあります。
2. ログ構成クラス
@Configuration
public class OpenFeignLogConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
3. 設定ファイル
logging:
level:
*[feign日志以什么级别监控哪个接口]:
com.ik.ikong.service.FeignClientService: debug
6 つの高レベルの構成
セブン、フェイン、スプリングブーツバージョン
バージョンの比較関係は次のとおりです。詳細については、ここのリンクをクリックして公式 Web サイトの最新バージョンの互換性関係を確認することもできます。
8. 技術的な問題
Idea がインターフェイスを呼び出すときにエラーを報告する
応答タイプに適切な HttpMessageConverter が見つかりません
解決プロセス
1. ログを手放す
@Configuration
public class FeignConfiguration {
@Bean
public feign.Logger logger() {
return new Slf4jLogger();
}
@Bean
public Logger.Level level() {
return Logger.Level.FULL;
}
}
logging:
level:
feign.Logger: debug
詳細なログ
リリースされたログから、インターフェイスによって返されるヘッダー: content-type: text/html; charset=UTF-8
インターフェイス署名に生産と消費を追加しましたが、
@PostMapping(value = "/xxxxx/your/api", produces = "application/json;charset=utf-8", consumes = "application/json;charset=utf-8")
効果がなく、依然として異常であることがわかります。応答タイプに適した HttpMessageConverter が見つかりません。
ネイティブ http 戻り値は、インターフェイスによって返される content-type: text/html である application/json タイプに対して一般的な逆シリアル化処理のみを実行すると推測されます。json 逆シリアル化処理は実行できないため、このタイプの json 逆シリアル化処理を追加します。処理;
@Bean
public HttpMessageConverters customConverters() {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_HTML,MediaType.APPLICATION_JSON));
return new HttpMessageConverters(false, Arrays.asList(mappingJackson2HttpMessageConverter, new StringHttpMessageConverter()));
}
注目されたmappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList( MediaType.TEXT_HTML,MediaType.APPLICATION_JSON ));
最後に、content-type: text/html による json の逆シリアル化が正常に完了しました。
参考:Spring Cloud
Feign はサービス間の Http 呼び出しを実装します。_feign http call_Half-life i のブログ-CSDN ブログ