ダイナミックルーティングゲートウェイチュートリアルの春の雲の2.xバージョン

概要

スプリング雲2.1.8RELEASE、バージョン= Greenwich.SR3は、本明細書中で使用されます

記事に基づいていくつかの春のクラウドゲートウェイの前で達成。参照

序文

春クラウドゲートウェイの発見についてのいくつかの記事を書いた後、知識ゲートウェイは広すぎる、本当に深遠な経験である「深い海に春の雲。」

春クラウドゲートウェイを使用して、実際の生産環境は、システムの高可用性を確保するために、すべてのトラフィックへの入り口として使用され、システムを再起動回避しようと、それが処理するために、クラウドゲートウェイのルーティング春ダイナミックに必要です。前の記事「ゲートウェイルーティングゲートウェイガイド」システム起動時、ルーティング設定とルールがメモリにロードされ、ルーティング設定を提供し、サービスを再起動せずに行うことができない、メモリを動的にルーティングする、削除、変更、追加することができますコンフィギュレーションとルール。

達成するためのシンプルな動的ルーティング

春クラウドゲートウェイはGatewayControllerEndpointクラスのルーティング設定を変更するためのソースコードを提供していますが、単にいくつかの簡単なAPIインターフェイスを導入し、使用するための公式文書に詳細な指示を思えません。最初の公式ドキュメント(見ることができます興味のジュニアパートナー11節APIのアクチュエータを)。

公式文書の原因:

/gatewayアクチュエータのエンドポイントは、監視し、春の雲Gatewayアプリケーションと対話することができます。リモートでアクセスできるように、エンドポイントがなければならない有効HTTPまたはJMXを介して露出されたアプリケーションのプロパティで。

1.1関連ポンポン依存追加

スプリング・ゲートウェイ上の元の依存に基づいて、ばねブートスタータアクチュエータを増加させます

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
复制代码

application.yml増加に配置された1.2

management:
  endpoints:
    web:
      exposure:
        include: "*"
复制代码

設定の説明:すべてのゲートウェイエンドポイントを公開management.endpoints.web.exposure.include

1.3サービスの起動

HTTPを訪問し、サービスを開始します:// localhostを:私たちはすべての情報を見ることができる経路である8100 /アクチュエータ/ゲートウェイ/ルート。

我々はまた、単一のルーティング情報にアクセスすることができます: HTTP:// localhostを:8100 /アクチュエータ/ゲートウェイ/ルート/ CompositeDiscoveryClient_EUREKA-CLIENT

それは次のようになります。

1.4ルーティング情報を修正し、追加

ゲートウェイは、このクラスは、GatewayControllerEndpointもAbstractGatewayControllerEndpointクラスを継承し、デフォルトGatewayControllerEndpointで使用されます。

方法に関連わずか数の列を提供:(方法、自分のソースコードを見ることができる男の他の方法)

  1. /ゲートウェイ/ルートは、すべてのルートを照会します
  2. ルーティング情報照会単一IDに応じて/ゲートウェイ/ルート/ {ID}
  3. 新しいルートを@PostMapping /ゲートウェイ/ルート/ {ID}
  4. /ゲートウェイ/ルート/ {ID} @DeleteMappingルートを削除

1.4.1の新ルート

我々/ゲートウェイ/ルートが要求パラメータ@PostMappingをシミュレートするために戻ったルーティング情報

{
    "uri": "http://httpbin.org:80",
    "predicates": [
        {
            "args": {
                "pattern": "/ribbon/**"
            },
            "name": "Path"
        }
    ],
    "filters": []
}
复制代码

これが示すように、POSTリクエストは、郵便配達によって送信されても​​よいです。

1つの応答が挿入された戻り、我々は、HTTPことができ、成功した証明:// localhostを:8100 /アクチュエータ/ゲートウェイ/ルート/ビュールート情報、次のように結果を表示します。

スクリーンショット赤いボックスの情報が新たに追加されています

1.4.2は、ルーティング情報を削除します

私たちは、直接郵便配達依頼、DeleteMappingシミュレーションを使用することができます// localhostを:8100 /アクチュエータ/ゲートウェイ/ルート/ addroutes HTTPを

それは次のようになります。

私たちは、HTTPを訪問し、この時間:// localhostを:8100 /アクチュエータ/ゲートウェイ/ルートは、あなたが新しく追加されたルートが成功した削除されている見ることができます。

1.5まとめ

サービスが再開されると、春のクラウド・ゲートウェイのデフォルトの動的ルーティング方法私はこのアプローチを実現JVMメモリに基づいており、私はすでに冒頭で言及した、終わりだ実装に基づいて、新しいルーティング構成情報が完全になくなっています。すべての今回は、動的ルーティング方法の独自のセットを達成するために、このような参照GatewayControllerEndpointの可能性を検討した後、ルーティング情報の永続することができます。

カスタムダイナミックルーティング

1.1定義関連するクラス

1.1.1カスタムエンティティクラス

あなたはエンティティクラスをカスタマイズすることができ、ここで私が興味を持ってパートナーが小さなクラスRouteDefinition独自の拡張を参照して、カスタムクラスRouteDefinitionに変換する変換クラスを記述することができ、RouteDefinitionクラスのゲートウェイを直接使用怠惰を盗みました。

1.1.2カスタムRedisRouteDefinitionRepositoryクラス

私はRedisのルーティング設定情報を使用して永続層としてここにいるので、RedisRouteDefinitionRepositoryを書きます。

package spring.cloud.demo.spring.gateway.component;

import com.google.common.collect.Lists;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import spring.cloud.demo.spring.gateway.redis.RedisUtils;
import spring.cloud.demo.spring.gateway.util.JsonUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @auther: maomao
 * @DateT: 2019-11-03
 */
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {

    //存储的的key
    private final static String KEY = "gateway_dynamic_route";

    @Resource
    private RedisUtils redisUtils;

    /**
     * 获取路由信息
     * @return
     */
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> gatewayRouteEntityList = Lists.newArrayList();
        redisUtils.hgets(KEY).stream().forEach(route -> {
            RouteDefinition result = JsonUtils.parseJson(route.toString(), RouteDefinition.class);
            gatewayRouteEntityList.add(result);
        });
        return Flux.fromIterable(gatewayRouteEntityList);
    }

    /**
     * 新增
     * @param route
     * @return
     */
    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> {
            redisUtils.hset(KEY, routeDefinition.getId(), JsonUtils.toString(routeDefinition));
            return Mono.empty();
        });
    }

    /**
     * 删除
     * @param routeId
     * @return
     */
    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id -> {
            if (redisUtils.hHashKey(KEY, id)) {
                redisUtils.hdel(KEY, id);
                return Mono.empty();
            }
            return Mono.defer(() -> Mono.error(new NotFoundException("route definition is not found, routeId:" + routeId)));
        });
    }
}

复制代码

1.1.3カスタムコントローラとサービス

package spring.cloud.demo.spring.gateway.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import spring.cloud.demo.spring.gateway.service.GatewayDynamicRouteService;

import javax.annotation.Resource;

/**
 * 自定义动态路由
 * @auther: maomao
 * @DateT: 2019-11-03
 */
@RestController
@RequestMapping("/gateway")
@Slf4j
public class GatewayDynamicRouteController {

    @Resource
    private GatewayDynamicRouteService gatewayDynamicRouteService;

    @PostMapping("/add")
    public String create(@RequestBody RouteDefinition entity) {
        int result = gatewayDynamicRouteService.add(entity);
        return String.valueOf(result);
    }

    @PostMapping("/update")
    public String update(@RequestBody RouteDefinition entity) {
        int result = gatewayDynamicRouteService.update(entity);
        return String.valueOf(result);
    }

    @DeleteMapping("/delete/{id}")
    public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
        return gatewayDynamicRouteService.delete(id);
    }

}

复制代码
package spring.cloud.demo.spring.gateway.service;

import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import spring.cloud.demo.spring.gateway.component.RedisRouteDefinitionRepository;

import javax.annotation.Resource;

/**
 * @auther: maomao
 * @DateT: 2019-11-03
 */
@Service
public class GatewayDynamicRouteService implements ApplicationEventPublisherAware {

    @Resource
    private RedisRouteDefinitionRepository redisRouteDefinitionRepository;

    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 增加路由
     * @param routeDefinition
     * @return
     */
    public int add(RouteDefinition routeDefinition) {
        redisRouteDefinitionRepository.save(Mono.just(routeDefinition)).subscribe();
        applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return 1;
    }

    /**
     * 更新
     * @param routeDefinition
     * @return
     */
    public int update(RouteDefinition routeDefinition) {
        redisRouteDefinitionRepository.delete(Mono.just(routeDefinition.getId()));
        redisRouteDefinitionRepository.save(Mono.just(routeDefinition)).subscribe();
        applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return 1;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    public Mono<ResponseEntity<Object>> delete(String id) {
        return redisRouteDefinitionRepository.delete(Mono.just(id)).then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
                .onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
    }


    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

复制代码

1.2 application.yml

application.ymlゲートウェイを排出嵐するすべてのエンドポイントを設定するには、試験前に設定情報を見ることができます。

1.3サービスの起動

スタートの春クラウドゲートウェイサービス、最初の訪問はhttp:// localhostを:8100 /アクチュエータ /ゲートウェイ/ルートは、 既存のルーティング設定情報を表示します。私たちは、その後、メソッドの郵便配達の要求を追加し、HTTP:// localhostを:8100 /ゲートウェイ/追加し、示された場合:

スクリーンショットの赤いボックスの内容に注意してください。証明は正常に追加されました。

その後、我々は、httpを訪問:// localhostを:8100 /アクチュエータ/ゲートウェイ/ルートが結果を確認すること。あなたは、このような場合:

同様に、我々は、更新にアクセスし、私はあまりないが、ここで説明する方法を削除することができます。

概要

カスタム動的ルーティングコア原理は前述RedisRouteDefinitionRepositoryクラスであるゲートウェイモジュールを書き換える必要があります。私は形式が不正なエラーであれば、対応するエンティティクラスを再定義するために、着信のパラメータのフォーマットはapplication.ymlに従って構成されなければならないことをここで注意することは、その後、JSONに変わり、ここで怠け者ではありませんよ。

コードアドレス

GitHubのアドレス


「Srpingクラウド2.X白チュートリアル」ディレクトリ

  • 書き込みは容易ではありませんパートナーの数が少ないが、より多くの記事を見て国民が好き焦点を当てることができるように、ソースを明記してください。
  • 連絡先:[email protected]

おすすめ

転載: juejin.im/post/5dbee3dde51d456e652839ea