前の章では、ネットマイクロサービスの実践(3)[ゲートウェイ]:Ocelot構成のルーティングと要求の集約、ルーティングとサービスの集約の主な機能であるOcelotの構成を紹介しました。次に、Ocelotの現在の制限、融合、キャッシング、負荷分散について紹介します。
現在の制限
まず、現在の制限設定を見てみましょう
Rerouteノードの構成は次のとおりです。
{
"DownstreamPathTemplate": "/api/orders",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/orders",
"UpstreamHttpMethod": [ "Get" ],
"RateLimitOptions": {
"ClientWhitelist": [],
"EnableRateLimiting": true,
"Period": "10m",
"PeriodTimespan": 3,
"Limit": 1
}
}
GlobalConfigurationの構成は次のとおりです。
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5000",
//限流
"RateLimitOptions": {
"QuotaExceededMessage": "您的请求量超过了配额1/10分钟",
"HttpStatusCode": 999
}
}
設定手順
RerouteノードとGlobalConfigurationノードにRateLimitOptionsノードを追加
- 無制限フロー制御のクライアントであるClientWhitelist-Whitelist
- EnableRateLimiting-現在の制限を有効にするかどうか
- 期間と制限-一定期間に許可されるリクエストの数
- PeriodTimespan-クライアントの再試行間隔。クライアントの間隔を再試行できる時間
- 現在の制限後のQuotaExceededMessage-promptメッセージ
- クォータを超えたときに返されるHttpStatusCode-HTTPステータスコード
説明の例
クライアントは、http:// localhost:5000 / api / Ordersを10分以内に1回のみリクエストでき、リクエスト後3秒後に再試行できます。
確認する
構成を変更し、サンプルプログラムを実行します。
http:// localhost:5000 / api / Ordersにアクセスします。最初に正常に戻り結果を得ることができます。再度アクセスすると、「リクエストボリュームがクォータを1/10分超え、レスポンスステータスコードは999です。
PeriodTimespan検証
現在の構成では要求を1秒で許可し、10秒後に再試行するように、Periodを1秒に、PeriodTimespanを10に変更します。サンプルプログラムを再度実行してください。
http:// localhost:5000 / api / Ordersにアクセスします。最初に正常に結果が返される場合は、2秒待ってください。もう一度訪問してください、誰もが考えます、今度は通常の結果に戻ります(2秒が経過しました)。この時点ではまだ999を返しますが、なぜですか? クォータは許可されていますが、構成ではクライアントが10秒後に再試行できるため、2秒しか待機しないため、999が返されます。
ヒューズ
OcelotのfuseはPollyを使用して達成し、OcelotGatewayプロジェクトにPollyパッケージを追加します
ポリーを注入する
services
.AddOcelot()
.AddPolly();
構成を変更する
{
"DownstreamPathTemplate": "/api/orders",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/orders",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 2,
"DurationOfBreak": 5000,
"TimeoutValue": 2000
}
}
設定手順
QoSOptionsノードをRerouteノードに追加
- ExceptionsAllowedBeforeBreaking-融合前に許可される例外の数
- DurationOfBreak-ヒューズの持続時間(ミリ秒)
- TimeoutValue-リクエストのタイムアウト設定(ミリ秒)
説明の例
http:// localhost:5000 / api / ordersにアクセスした後、2つの例外があります。5秒間のサービスヒューズです。サービス応答が2秒を超えると、ヒューズ状態もトリガーされます
確認する
-
シナリオ1:サービスが停止し
て構成を変更し、ゲートウェイのみを開始します。始まらないoder api、http:// localhost:5000 / api / Ordersにアクセスします。最初の応答には時間がかかり、500が返されます。2番目の応答にも時間がかかります。500が返されます。3回目はすぐに503を返します。サービス不可、サービスヒューズあまりにも。 -
シナリオ2:タイムアウト
変更構成
api /注文コードを変更し、3秒待ちます
// GET: api/orders
[Route("api/orders")]
[HttpGet]
public IEnumerable<string> Get()
{
Task.Delay(3000).Wait();
return new string[] { "刘明的订单", "王天的订单" };
}
ゲートウェイを開始し、order-apiを開始し、http:// localhost:5000 / api / Ordersにアクセスし、503を返します。
- シナリオ3:サービスは正常に応答しますが、サービス500は内部
で構成を
変更し、API /注文コードを変更して、例外をスローします
// GET: api/orders
[Route("api/orders")]
[HttpGet]
public IEnumerable<string> Get()
{
throw new Exception("获取所有订单出错");
}
ゲートウェイを開始し、order-apiを開始して、http:// localhost:5000 / api / ordersにアクセスします。
キャッシュ
キャッシュはCacheManageerを使用して実装され、CacheManagerパッケージを追加します
Install-Package Ocelot.Cache.CacheManager
キャッシュコンポーネントを挿入する
services.AddOcelot()
.AddCacheManager(x =>
{
x.WithDictionaryHandle();
});
Ocelot.json構成ファイルの変更
{
"DownstreamPathTemplate": "/api/orders",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/orders",
"UpstreamHttpMethod": [ "Get" ],
"FileCacheOptions": {
"TtlSeconds": 60,
"Region": "orders"
}
}
キャッシングは、ダウンストリームサービスのURLに従ってキャッシングするための設定手順です
RerouteノードにFileCacheOptionsノードを追加
- TtlSecondsキャッシュの有効期間(秒)
- リージョンキャッシュパーティション。バックグラウンドAPIを呼び出すことにより、リージョンの下のキャッシュをクリアできます
説明の例
http:// localhost:5000 / api / Ordersにアクセスした後、結果は60秒間キャッシュされます。キャッシュの有効期間中に元のOrder APIが結果を変更した場合でも、ゲートウェイを介してリクエストされたときに、キャッシュされた結果が返されます。
確認する
- 構成を変更し、ゲートウェイのみを開始し、オーダAPIを開始し、http:// localhost:5000 / api / Ordersにアクセスすると、返される結果は次のようになります。
"刘明的订单", "王天的订单"
- API /注文を変更し、API /注文を再起動します
[Route("api/orders")]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "帅的订单", "我的订单" };
}
- http:// localhost:5000 / api / Ordersに再度アクセスします。 現在、どのような結果が返されますか?、表示を確認するか戻る
"刘明的订单", "王天的订单"
結果がキャッシュされるため
- 2分間待ってから、http:// localhost:5000 / api / Ordersにアクセスします。現在、どのような結果が返されますか?、新しい結果が返されることを確認します
"帅的订单", "我的订单"
キャッシュの有効期限が過ぎているため
ヘッダー変換
Ocelotは、アップストリームサービスのリクエストとダウンストリームサービスの応答のヘッダーに情報を追加および置換できます
構成は次のとおりです。
{
"DownstreamPathTemplate": "/api/shopping-carts",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"DownstreamHeaderTransform": {
"devops": "rdc"
},
"UpstreamPathTemplate": "/api/shopping-carts",
"UpstreamHttpMethod": [ "Get" ],
"UpstreamHeaderTransform": {
"lakin": "rdc",
"CI": "msbuild, jenkins",
"Location": "http://localhost:5001, {BaseUrl}"
}
}
設定手順
RestreamノードにDownstreamHeaderTransformノードとUpstreamHeaderTransformノードを追加しました
"DownstreamHeaderTransform": {
"devops": "rdc"
}
説明:ダウンストリームサービスの応答にヘッダーを追加します。キーはdevops、値はrdcです
"UpstreamHeaderTransform": {
"lakin": "rdc",
"CI": "msbuild, jenkins",
"Location": "http://localhost:5001, {BaseUrl}"
}
- ヘッダー情報を追加
します。上流のサービスリクエストにヘッダーを追加します。キーはlakin、値はrdcです。
アップストリームサービスリクエストのヘッダー情報を置き換えます。キーはCIヘッダーであり、その値はmsbuildによってjenkinsに置き換えられます- 置き換えるとき
は、上流のサービスリクエストでプレースホルダーを使用します。キーはLocationヘッダーで、その値はhttp:// localhost:5001 with {BaseUrl} placehokderに置き換えられます
説明の例
http:// localhost:5000 / api / Ordersにアクセスした後、結果は60秒間キャッシュされます。キャッシュの有効期間中に元のOrder APIが結果を変更した場合でも、ゲートウェイを介してリクエストされたときに、キャッシュされた結果が返されます。
確認する
- Order Serviceを変更し、ShoppingCart APIを追加します。コードは次のとおりです
// GET: api/shopping-carts
[Route("api/shopping-carts")]
[HttpGet]
public IEnumerable<string> Get()
{
Console.WriteLine($"开始打印header信息");
foreach (var item in this.Request.Headers)
{
Console.WriteLine($"{item.Key} - {item.Value}");
}
Console.WriteLine($"打印header信息完成");
return new string[] { "洗发水", "无人机" };
}
- ゲートウェイを開始し、注文サービスを開始します
- Postmanを使用してhttp:// localhost:5000 / api / shopping-cartsを呼び出し、リクエストに2つのヘッダー項目を追加します
"CI": "msbuild",
"Location": "http://localhost:5001"
- リクエストする
- 注文サービスのコンソールで、次の出力を確認し、ヘッダーアイテムを追加し、2つのヘッダーアイテムの値を置き換えます。
开始打印header信息CI
lakin - rdc
CI - jenkins
Location - http://localhost:5000
打印header信息完成
- Postmanで応答のヘッダー情報を確認すると、次のヘッダー項目が追加されていることがわかります
devops - rdc
HTTPメソッド変換
Ocelotはルーティング時にHTTPメソッドの変換を可能にします
{
"DownstreamPathTemplate": "/api/shopping-carts",
"DownstreamScheme": "http",
"DownstreamHttpMethod": "POST",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/shopping-carts",
"UpstreamHttpMethod": [ "Get" ]
}
例の説明
上記の例では、GET / api / shopping-cartsをPOST / api / shopping-cartsにルーティングし、GETをPOSTに変換します。
該当するシナリオ:たとえば、いくつかの既存のAPIは、歴史的な理由でPOSTを使用します。ゲートウェイを介してサービスを提供する場合、標準のAPIに従って変換できます。
確認する
- 現在、GET / api / shopping-cartsは次の結果を返します
"洗发水", "无人机"
- ShoppingCartControllerに新しいPOST APIを追加します
[Route("api/shopping-carts")]
[HttpPost]
public string Post()
{
return "添加商品到购物车成功";
}
- ゲートウェイを実行してサービスを注文する
- GET http:// localhost:5000 / api / shopping-cartsにアクセスすると、返される結果は次のようになります。GETはPOSTに変換されています
添加商品到购物车成功
負荷分散
Ocelotにはロードバランシングが組み込まれています。最初に構成を見てみましょう
{
"DownstreamPathTemplate": "/api/orders",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
},
{
"Host": "localhost",
"Port": 6001
}
],
"UpstreamPathTemplate": "/api/orders",
"UpstreamHttpMethod": [ "Get" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
構成手順
DownstreamHostAndPortsで、複数のサービスアドレス
を指定し、RerouteノードにLoadBalancerOptionsを追加します。これは、負荷分散構成ノードです。Type属性は、負荷分散アルゴリズムを指定します。次の値があります。
- LeastConnection-最もアイドル状態のサーバーにリクエストを送信します
- RoundRobin-Sendを順番に
- NoLoadBalance –常に最初のリクエストに送信します(サービス検出が設定されている場合は、常に最初に検出されたサービスアドレスに送信します)
確認する
- ゲートウェイを開始する
- api /注文のコードを変更し、注文サービスを開始します
[Route("api/orders")]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "刘明的订单", "王天的订单" };
}
- 注文サービスのコピーを作成し、api /注文コードを変更して、コピーの開始ポートを6001に変更し、注文サービスを開始します。
[Route("api/orders")]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "帅的订单", "我的订单" };
}
- GET httpを呼び出す:// localhost:5000 / api / Postmanの注文
最初の結果は
"刘明的订单", "王天的订单"
2番目の結果は
"帅的订单", "我的订单"
3番目の結果は
"刘明的订单", "王天的订单"
ミドルウェアの挿入/書き換え
Ocelot自体はミドルウェアのセットであり、ミドルウェアの一部を挿入して書き換える方法も提供します。
- PreErrorResponderMiddleware-すべてのOcelotミドルウェアの前に実行されるため、ユーザーはOcelotパイプラインの実行前後に動作を提供できます。
- PreAuthenticationMiddlewareは、アイデンティティー前の認証ロジックを提供し、アイデンティティー認証ミドルウェアの前に実行されます
- AuthenticationMiddleware-Ocelotミドルウェアによって提供される上書きID認証ロジック
- PreAuthorisationMiddleware-事前承認ロジックを提供し、ミドルウェアを承認する前に実行されます
- AuthorizationMiddleware-Ocelotミドルウェアによって提供される上書き承認ロジック
- PreQueryStringBuilderMiddleware-QueryString変換前の前処理ロジックを提供します
以下は、PreErrorResponderMiddlewareミドルウェアに挿入されたコードの例です。
//注入中间件
var configuration = new OcelotPipelineConfiguration
{
PreErrorResponderMiddleware = async (ctx, next) =>
{
ctx.HttpContext.Request.Headers.Add("myreq", "ocelot-request");
await next.Invoke();
}
};
app.UseOcelot(configuration).Wait();
注:Ocelotはミドルウェアのセットでもあるため、通常の方法でOcelotミドルウェアの前にミドルウェアを追加できますが、Ocelotミドルウェアの後に追加することはできません。
バックグラウンド管理
Ocelotは、バックグラウンド管理用の一連のAPIを提供します。最初の3つの記事からわかるように、Ocelotは主に構成ファイルの管理を指すため、APIは主に管理構成を指します。
- 管理バックグラウンドのトークン
POST {adminPath} / connect / tokenを取得します - 構成を取得
GET {adminPath} /構成 - 構成の作成/変更
POST {adminPath} /構成 - キャッシュの
削除DELETE {adminPath} / outputcache / {region}
最後
この記事では、Ocelotの現在の制限、融合、キャッシング、負荷分散、その他の機能を紹介しました。これまでに、Ocelotの基本的な構成と機能について説明しました。次に、consulを導入して、サービスディスカバリとOcelotとConsulの統合を紹介します。
サンプルコードのダウンロードアドレス:https : //github.com/lcyhjx/ocelot-demo/tree/master