前のプロジェクトでは、リモートインターフェイスを呼び出すためにFeignを使用することを実現しました。この章では、主にセンチネルを使用してFeignインターフェイスのヒューズ機能を実現します。
概要概要
まず、ヒューズを使用せずに未起動のサービスを呼び出すことの効果を見てから、センチネルヒューズを使用することの効果を見てみましょう。
上記のようFeignController
に、呼び出しではアカウントサービスインターフェイスのorder-serviceを使用します。ヒューズが有効になっていない場合、インターフェイスは例外500をスローします。
成し遂げる
センチネルを使用してヒューズを実現するのは非常に簡単で、ほんの数ステップです。
-
フォールバッククラスを定義し、回線が切断されたときにデフォルトデータを返します
package com.javadaily.feign.fallback;
@Slf4j
public class AccountFeignFallback implements AccountFeign {
@Setter
private Throwable cause;
@Override
public ResultData<String> insert(AccountDTO accountDTO) {
return ResultData.fail("接口熔断");
}
@Override
public ResultData<String> delete(String accountCode) {
return ResultData.fail("接口熔断");
}
@Override
public ResultData<String> update(AccountDTO accountDTO) {
return ResultData.fail("接口熔断");
}
@Override
public ResultData<AccountDTO> getByCode(String accountCode) {
log.error("查询失败,接口异常" ,cause);
AccountDTO account = new AccountDTO();
account.setAccountCode("000");
account.setAccountName("测试Feign");
return ResultData.success(account);
}
@Override
public ResultData<String> reduce(String accountCode, BigDecimal amount) {
return ResultData.fail("接口熔断");
}
}
-
FallbackFactoryを書く
@Component
public class AccountFeignFallbackFactory implements FallbackFactory<AccountFeign> {
@Override
public AccountFeign create(Throwable throwable) {
AccountFeignFallback accountFeignFallback = new AccountFeignFallback();
accountFeignFallback.setCause(throwable);
return accountFeignFallback;
}
}
-
ヒューズファクトリを偽のインターフェイスに割り当てます
@FeignClient(name = "account-service",fallbackFactory = AccountFeignFallbackFactory.class)
public interface AccountFeign {
...
}
-
消費プロファイルで回路ブレーカーをオンにします
feign:
sentinel:
enabled: true
上記の4つの手順を実行すると、インターフェースの融合を実現し、注文サービスを再起動して結果を確認できます。システムが正常に起動しません!!!
スタック情報は次のとおりです。
2020-10-23 15:22:14,286 ERROR SpringApplication:826 - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'feignController': Unsatisfied dependency expressed through field 'accountFeign'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.javadaily.feign.account.AccountFeign': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: No fallbackFactory instance of type class com.javadaily.feign.factory.AccountFeignFallbackFactory found for feign client account-service
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
問題が解決しました
ことわざにあるように、「問題はひどいものではありません。ひどいのは、問題を恐れていることです。」上記の起動ログを見ると、見つけることができないはずAccountFeignFallbackFactory
です。次に、FeignClientのソースコードを見てみましょう。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
...省略部分代码,保留关键代码...
/**
* Fallback class for the specified Feign client interface. The fallback class must
* implement the interface annotated by this annotation and be a valid spring bean.
* @return fallback class for the specified Feign client interface
*/
Class<?> fallback() default void.class;
...省略部分代码,保留关键代码...
}
コメントに注意してください。FeignのダウングレードされたクラスはFeignインターフェースを実装する必要があり、SpringBeanである必要があると言われています。
エラーの理由は、「ダウングレードされたクラスはSpringBeanとして登録されていません」である必要があります。
SpringBootが起動すると、メインのスタートアップクラスが配置されているパッケージとサブパッケージが、デフォルトでBeanのインスタンス化のためにスキャンされることは誰もが知っています。
マスターブートタイプにあるオーダーサービスアイテムcom.javadaily.order
、次にプロジェクトの開始com.javadaily.order
とcom.javadaily.order
サブパケットのスキャンオーダーサービスのみ、劣化したクラスAccountFeignClientAccountFeignFallback
パッケージパスはcom.javadaily.feign.fallback
、Springをインスタンス化できないため、最終的にプロジェクトにつながります起動失敗。
問題の原因が特定されたので、Feignダウングレードクラスのパッケージパスがスタートアップクラスで構成されている限り、簡単に解決できます。
@SpringBootApplication(scanBasePackages = {"com.javadaily.feign"})
この設定を追加した後、システムは正常に起動できますが、呼び出し元のインターフェイスは次のエラーを返します。
{
"timestamp": "2020-10-27T03:30:44.664+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/order/getAccount/jianzh5"
}
この問題の理由は、scanBasePackagesを介してFeignダウングレードクラスのパスを構成した後、独自のBeanをインスタンス化できないため、独自のプロジェクトのスキャンパスも構成する必要があるためです。
@SpringBootApplication(scanBasePackages = {"com.javadaily.feign","com.javadaily.order"})
これまでのところ、すべての問題が解決されたので、インターフェイスに再度アクセスし、システムに障害が発生するとデフォルトの結果に戻ります。
概要
この章では、Feignインターフェースにヒューズを追加します。インスタンスに障害が発生すると、システムはデフォルトのデータを返します。このように、特定のサービスが利用できない場合、そのコンシューマーは長時間待機し、スレッドプールが使い果たされ、他のサービスのスレッド呼び出しに影響を与えます。これは一般に「アバランシェ効果」とも呼ばれます。 。
もちろん、実装プロセスには少し後退がありました。要約は、「Feignクライアントがコンシューマーによって作成されている場合、この問題はコンシューマー自身のモジュールでは発生しません。プロデューサーによって作成および提供されている場合は、 Spring Beanのインスタンス化されたスキャンパスに注意を払うために、インスタンス化されたクラスヒューズをスキャンできない場合は、スタートアップクラスでscanBasePackages
、対応する "へのパスをスキャンするだけです。
これは皆へのささやかな贈り物です。公式アカウントに従って、次のコードを入力してください。Baiduネットワークディスクアドレスを取得できます。ルーチンはありません。
001:「プログラマーにとって必読の本」
002:「中小規模のインターネット企業向けのバックエンドサービスアーキテクチャと運用および保守アーキテクチャをゼロから構築する」
003:「インターネット企業向けの高同時実行ソリューション」
004:「インターネットアーキテクチャ教育ビデオ "
006:
注文システムのSpringBoot実現" 007: "SpringSecurity実際の戦闘ビデオ"
008: "Hadoop実際の戦闘教育ビデオ"
009: "Tencent 2019 Techo Developer Conference PPT"
010:WeChat交換グループ