SpringCloud実戦小贴士のZuulルートマッチング

4254 ワード

伝統的なルートの構成方式を使っても、サービスルートの構成方式を使っても、各ルート規則のためにマッチング式を定義する必要があります。つまり、前述のパスパラメータです。Zuulではルートマッチングのパス表現がAntスタイル定義を採用しています。
Antスタイルのパス表現はとても簡単です。全部で次の三つのワイルドカードがあります。
ワイルドカード
説明

任意の1文字にマッチします。

任意の数の文字にマッチします。
**
任意の数の文字にマッチし、多段ディレクトリに対応します。
この3つのワイルドカードの意味を以下の表の例でさらに理解し、参照して使用することができます。
URLパス
説明
//user-service/
これはマッチします /user-service/ 後にタスクのパスをつづり合わせます。たとえば、 /user-service/a 、 /user-service/b 、 /user-service/c
//user-service/*
これはマッチします /user-service/ その後、任意の文字のパスをつづり合わせます。例えば、 /user-service/a 、 /user-service/aa 、 /user-service/bb 。マッチしませんでした。 /user-service/a/b
//user-service/*
これはマッチします /user-service/* 含まれる内容に加えて、例えば /user-service/a/b のマルチレベルディレクトリパス
また、私たちがワイルドカードを使うと、一つのURLパスが複数の異なるルーティングの表現にマッチする可能性があるという問題がよくあります。例えば、このようなシーンがあります。私たちはシステム建設の最初にuser-serviceサービスを実現しました。そして、次のようなルートルールを設定しました。

zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.serviceId=user-service
しかし、バージョンの反復に従って、私たちはuser-serviceサービスにいくつかの機能を分割して、user-serviceサービスに属するいくつかの機能を別の新しいサービスuser-service-extに分割しました。これらの分割された外部のURLパスは、規則/user-service/ext/xt/*に適合することを望んでいます。この時、私たちは設定ファイルにルートルールを追加したいです。完全な構成は以下の通りです。

zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.serviceId=user-service

zuul.routes.user-service-ext.path=/user-service/ext/**
zuul.routes.user-service-ext.serviceId=user-service-ext
このとき、user-service-extサービスを呼び出すURLパスは、実際には同時に/user-service/***と/user-service/ext/*の2つの表現にマッチします。論理的には、APIゲートウェイサービスは、優先的に/user-service/ext/*ルートを選択し、その後、/user-service/*ルートに適合してこそ、上記の需要を実現することができる。しかし、上の構成を使うと、そのようなルーティングの優先順位は実際には保証されない。
次のルーティング・マッチングアルゴリズムからは、ルーティング・ルール整合要求経路を使用する際に、線形巡回により、要求経路が最初の一致したルーティング・ルールを取得した後に、マッチングプロセスを終了することが分かる。したがって、複数の整合したルーティングルールが存在する場合、整合結果はルーティングルールの保存順序に完全に依存する。

@Override
public Route getMatchingRoute(final String path){
 ...
 ZuulRoute route = null;
 if (!matchesIgnoredPatterns(adjustedPath)) {
 for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
  String pattern = entry.getKey();
  log.debug("Matching pattern:" + pattern);
  if (this.pathMatcher.match(pattern, adjustedPath)) {
  route = entry.getValue();
  break;
  }
 }
 }
 log.debug("route matched=" + route);
 return getRoute(route, adjustedPath);
}
以下に示すコードは基本的なルーティングルールのロードアルゴリズムであり、これらのルーティングルールはLinkedHashMapによって保存されており、つまりルーティングルールの保存は秩序化されており、コンテンツのロードは構成ファイルを巡回することによってルーティングルールが順次追加されるので、問題の根本的な原因は構成ファイルの内容の読み取りである。

protected Map<String, ZuulRoute> locateRoutes(){
 LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
 for (ZuulRoute route : this.properties.getRoutes().values()) {
 routesMap.put(route.getPath(), route);
 }
 return routesMap;
}
propertiesの構成内容は秩序を保つことができないので、このような場合には、ルートの優先順位を保証するために、YAMLファイルを使用して構成する必要があります。

zuul:
routes:
user-service-ext:
path: /user-service/ext/**
serviceId: user-service-ext
user-service:
path: /user-service/**
serviceId: user-service
式を無視する
パスパラメータによって定義されたAnt表現はAPIゲートウェイ上のルーティング規則の設定機能を完了しましたが、より細かい粒度とより柔軟な配置のために、Zuulはまた、表現パラメータを無視するために提供しました。このパラメータは、APIゲートウェイによってルーティングされたくないURL表現を設定するために使用されてもよい。
例えば、クイックエントリの例をベースにして、もし私たちがハローインターフェースをルーティングしたくないなら、このように設定できます。

zuul.ignored-patterns=/**/hello/**
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=hello-service
そして、ネットワークを介してハローサービスにアクセスすることができる/ハローインターフェース:http://localhost:5555/api-a/hello。このアクセス経路はpathパラメータ定義の/appi-a/***規則に完全に一致しているが、この経路はzul.ignored-patternsパラメータ定義の規則に適合しているので、正確にルートされない。同時に、コントロールやログでは、ルートに合致していない出力情報を見ることができます。

o.s.c.n.z.f.pre.PreDecorationFilter   : No route found for uri: /api-a/hello
また、このパラメータは、使用時に、その範囲があるルートではなく、すべてのルートに対してのものであることにも注意が必要です。したがって、設定時にはURLルールを全面的に考慮し、無視してはいけないURLパスを無視することを防止する必要があります。
何か考えや問題があれば、討論や交流が必要です。交流エリアに入って、あなたの考えや問題を発表してもいいです。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。