Sentinel は優れたフロー制御フレームワークです。実際の運用では、プロジェクトは Spring Boot や Dubbo などのフレームワークを使用します。これらのフレームワークにフロー制御が実装されている場合、どのような構成が最適なソリューションですか? この記事では、Sentinel がどのように適応するかを分析することに焦点を当てています。さまざまなオープンソース フレームワークに対応します。
Web サーブレット
Sentinel は、Web リクエストのフローを制御できるサーブレットのネイティブ統合を提供します。使用する場合は、次のモジュールを導入する必要があります (Maven を例にします)。
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
<version>x.y.z</version>
</dependency>
Spring で構成を追加し、Bean を定義します。
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
実際には、Filter メカニズムを通じてインターセプトされ、フロー制御を具体的に実装するクラスは CommonFilter です。
1) URL をクリーンアップする
ユーザーは、UrlCleaner インターフェイスを実装してリソースをクリーンアップし (たとえば、/foo/:id を満たす URL を /foo/* リソースの下に置きます)、WebCallbackManager に登録する必要があります。そうしないと、リソースの数が大きすぎて、リソース数のしきい値 (現在 6000) を超えたときに超過リソースのルールが有効になりません。
// Clean and unify the URL.
// For REST APIs, you have to clean the URL (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
// the amount of context and resources will exceed the threshold.
UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner();
if (urlCleaner != null) {
target = urlCleaner.clean(target);
}
アダプテーション Web サーブレットでは、ソースに応じたフロー制限をサポートします。リソースは処理された URL であり、メソッド名も結合できます。定義されたリソース タイプは Web です。
ダボ
Dubbo では、サービス プロバイダーとサービス コンシューマーに分けることができますが、この 2 つの側面の焦点は少し異なります。
サービスプロバイダー
トラフィックの急増によってプロバイダーが引きずられ、安定性に影響を与えるのを防ぐために、プロバイダーの QPS モードのフロー制限を構成して、1 秒あたりのリクエスト数が設定されたしきい値を超えると、多くのリクエストが制限されるようにすることができます。自動的に拒否されました。現在の制限粒度は、サービス インターフェイスとサービス メソッドの 2 種類の粒度にすることができます。
具体的な実装は、Dubbo フィルターと SPI メカニズムに基づいています。
定義されているリソース タイプは RPC です。
サービス利用者
Service Consumer 作为客户端去调用远程服务。每一个服务都可能会依赖几个下游服务,若某个服务 A 依赖的下游服务 B 出现了不稳定的情况,服务 A 请求 服务 B 的响应时间变长,从而服务 A 调用服务 B 的线程就会产生堆积,最终可能耗尽服务 A 的线程数。我们通过用并发线程数来控制对下游服务 B 的访问,来保证下游服务不可靠的时候,不会拖垮服务自身。基于这种场景,推荐给 Consumer 配置线程数模式的限流,来保证自身不被不稳定服务所影响。
代码基本与 Provider一致,Entry方向为 EntryType.OUT。
gRPC
在使用 Sentinel gRPC Adapter 时,只需要将对应的 Interceptor 注册至对应的客户端或服务端中。其中客户端的示例如下:
public class ServiceClient {
private final ManagedChannel channel;
ServiceClient(String host, int port) {
this.channel = ManagedChannelBuilder.forAddress(host, port)
.intercept(new SentinelGrpcClientInterceptor()) // 在此处注册拦截器
.build();
// 在此处初始化客户端 stub 类
}
}
服务端的示例如下:
import io.grpc.Server;
Server server = ServerBuilder.forPort(port)
.addService(new MyServiceImpl()) // 添加自己的服务实现
.intercept(new SentinelGrpcServerInterceptor()) // 在此处注册拦截器
.build();