サービスのミクロ現在のレベルあなたはマイクロサービスフレームワーク技術を学ぶことができない場合には、人気のあるそう。どのように缶プロモーションや賃上げ、チップ再開を増やしますか?春の雲とダボだけでは学ぶために。時間がありませんの?いいえエネルギーん?フレームワークの両方を習得するには?春クラウドalibabaのはあなただけa'llマイクロテクノロジーサービス管理フレームワークの2種類を持って学ぶ必要があります。なぜそれをしませんか?さあ!サン猿の年
zuul前に、我々はそれについて話しています。ダイナミックルーティングを取得する方法。息子として春クラウドゲートウェイはダイナミックルーティングをサポートしていませんでしたプロが存在します。予備今日はダイナミックルーティングゲートウェイを見てください。
需要フロント。動的ルーティングの理解。あなたは我々のデータはデータベースに保存されているか、それらをRedisのことを期待することができるかもしれません。そこはまた、エンティティクラスに格納されています。
思考:
配置中心刷新routes配置信息。路由信息刷新改变。利用事件发布,利用配置中心完成动态刷新路由。本次改造我们使用自定义存储方式达到手动触发动态路由
InMemoryRouteDefinitionRepository 默认使用。这个类就是把握们当前的所有的路由routes 存储在内存当中。当服务重启或者刷新,内存就不复存在。ps: 因为本项目是用nacos 注册中心也是配置中心。可以存储在nacos 配置中心里面。
RouteDefinitionRepository 接口是InMemoryRouteDefinitionRepository 是它的接口类 继承了 RouteDefinitionLocator 、RouteDefinitionWriter俩个接口。
RouteDefinitionLocatorインタフェース
RouteDefinitionWriterは、追加および削除ルートを実装するために使用されます。
思考:
基于这个原则我们在动态添加或者删除路由的时候,就可以根据这个接口实现去满足我们动态的控制路由规则。
RouteDefinitionRepositoryこのインタフェースは、実際に達成するために、動的インターフェイスに基づいて再ルーティングに我々が持っている重要なポイントとなっています
Entityクラス
package com.xian.cloud.model;
import lombok.Data;
/**
* @Author: xlr
* @Date: Created in 5:10 PM 2019/9/29
*/
@Data
public class GatewayRoutesEntity {
private Long id;
private String serviceId;
private String uri;
private String predicates;
private String filters;
}
GatewayRoutesServiceインタフェース
package com.xian.cloud.service;
import com.xian.cloud.model.GatewayRoutesEntity;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import java.util.List;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 16:08
*/
public interface GatewayRoutesService {
List<GatewayRoutesEntity> findAll() throws Exception;
String loadRouteDefinition() throws Exception;
GatewayRoutesEntity save(GatewayRoutesEntity gatewayDefine) throws Exception;
void deleteById(String id) throws Exception;
boolean existsById(String id)throws Exception;
List<PredicateDefinition> getPredicateDefinition(String predicates) ;
List<FilterDefinition> getFilterDefinition(String filters) ;
}
GatewayRoutesService実装クラス
package com.xian.cloud.service.impl;
import com.alibaba.fastjson.JSON;
import com.xian.cloud.model.GatewayRoutesEntity;
import com.xian.cloud.service.GatewayRoutesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.List;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 16:09
*/
@Service
@Slf4j
public class GatewayRoutesServiceImpl implements GatewayRoutesService {
public static final String GATEWAY_DEFINE_LIST_KEY = "gateway_routes_list_key";
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
@Override
public List <GatewayRoutesEntity> findAll() throws Exception {
Long size = redisTemplate.opsForList().size( GATEWAY_DEFINE_LIST_KEY );
List<GatewayRoutesEntity> list = redisTemplate.opsForList().range( GATEWAY_DEFINE_LIST_KEY, 0, size );
return list;
}
@Override
public String loadRouteDefinition() {
try {
List <GatewayRoutesEntity> gatewayDefineServiceAll = findAll();
if (gatewayDefineServiceAll == null) {
return "none route defined";
}
for (GatewayRoutesEntity gatewayDefine : gatewayDefineServiceAll) {
RouteDefinition definition = new RouteDefinition();
definition.setId( gatewayDefine.getServiceId() );
definition.setUri( new URI( gatewayDefine.getUri() ) );
List <PredicateDefinition> predicateDefinitions = getPredicateDefinition(gatewayDefine.getPredicates());
if (predicateDefinitions != null) {
definition.setPredicates( predicateDefinitions );
}
List <FilterDefinition> filterDefinitions = getFilterDefinition(gatewayDefine.getFilters());
if (filterDefinitions != null) {
definition.setFilters( filterDefinitions );
}
routeDefinitionWriter.save( Mono.just( definition ) ).subscribe();
publisher.publishEvent( new RefreshRoutesEvent( this ) );
}
return "success";
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
}
/**
* 获取所有的 自定义路由规则
* @param gatewayDefine
* @return
* @throws Exception
*/
@Override
public GatewayRoutesEntity save(GatewayRoutesEntity gatewayDefine) throws Exception {
log.info( "save RouteDefinition : {}",gatewayDefine );
redisTemplate.opsForList().rightPush( GATEWAY_DEFINE_LIST_KEY, gatewayDefine );
return gatewayDefine;
}
@Override
public void deleteById(String id) throws Exception {
List <GatewayRoutesEntity> all = findAll();
for (GatewayRoutesEntity gatewayDefine : all) {
if(gatewayDefine.getServiceId().equals( id )){
redisTemplate.opsForList().remove( GATEWAY_DEFINE_LIST_KEY,0, gatewayDefine);
}
}
}
@Override
public boolean existsById(String id) throws Exception {
List <GatewayRoutesEntity> all = findAll();
for (GatewayRoutesEntity gatewayDefine : all) {
if(gatewayDefine.getServiceId().equals( id )){
return true;
}
}
return false;
}
@Override
public List<PredicateDefinition> getPredicateDefinition(String predicates) {
if ( StringUtils.isNotBlank( predicates )) {
List<PredicateDefinition> predicateDefinitionList = JSON.parseArray(predicates, PredicateDefinition.class);
return predicateDefinitionList;
} else {
return null;
}
}
@Override
public List<FilterDefinition> getFilterDefinition(String filters) {
if (StringUtils.isNotBlank( filters )) {
List<FilterDefinition> filterDefinitionList = JSON.parseArray(filters, FilterDefinition.class);
return filterDefinitionList;
} else {
return null;
}
}
}
その後、我々はRouteDefinitionLocator、RouteDefinitionWriter両方のインターフェイスコンフィギュレーションファイル内の宣言を行って
package com.xian.cloud.config;
import com.xian.cloud.repository.GatewayRoutesRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* <Description> 动态更新路由
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 17:12
*/
@Configuration
@Slf4j
public class GatewayRoutesDefinitionConfig {
@Bean
RouteDefinitionLocator routeDefinitionLocator(){
return new GatewayRoutesRepository();
}
@Bean
@Primary
RouteDefinitionWriter routeDefinitionWriter(){
return new GatewayRoutesRepository();
}
}
リフレッシュルートイベント通知ゲートウェイを公開RefreshRoutesEventイベント。このイベントは、ゲートウェイイベントです。
package com.xian.cloud.event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 17:20
*/
@Component
@Slf4j
public class RefreshRouteService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
/**
* 刷新路由表
*/
public void refreshRoutes() {
publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
その後、我々はまだ手動トリガ・インタフェースあり、GatewayRoutesControllerを作成
package com.xian.cloud.controller;
import com.xian.cloud.event.RefreshRouteService;
import com.xian.cloud.model.RestResult;
import com.xian.cloud.model.RestResultBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 17:18
*/
@RestController
@RequestMapping("/gateway")
public class GatewayRoutesController {
@Autowired
private RefreshRouteService refreshRouteService;
@GetMapping("/refreshRoutes")
public RestResult refreshRoutes(){
refreshRouteService.refreshRoutes();
return RestResultBuilder.builder().success().build();
}
}
これまでのところ、すべてのコードは完了です。
サービス開始
実際には、非常に単純で直接的な文言があります。春の雲の戦闘に文言を再定義への参照。
クラスDynamicRouteServiceImplを高めるためにイベントを作成します
package com.xian.cloud.event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/09 10:40
*/
@Slf4j
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
@Qualifier("routeDefinitionRepositor")
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
/**
* 添加路由实体类
* @param definition
* @return
*/
public boolean add(RouteDefinition definition){
routeDefinitionWriter.save((Mono<RouteDefinition>) Mono.just(definition).subscribe());
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
/**
*
* @param definition 路由实体类
* @return
*/
public boolean update(RouteDefinition definition){
try {
routeDefinitionWriter.delete(Mono.just(definition.getId()));
}catch (Exception e){
log.error("update 失败。没有找到对应的路由ID :{}",definition.getId());
}
routeDefinitionWriter.save((Mono<RouteDefinition>) (Mono.just(definition)).subscribe());
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
/**
* serviceId
* @param id
* @return
*/
public boolean del(String id){
routeDefinitionWriter.delete(Mono.just(id));
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
コントローラを変更するには、3つのメソッドを追加します。
package com.xian.cloud.controller;
import com.xian.cloud.event.DynamicRouteServiceImpl;
import com.xian.cloud.event.RefreshRouteService;
import com.xian.cloud.model.RestResult;
import com.xian.cloud.model.RestResultBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.web.bind.annotation.*;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/11/08 17:18
*/
@RestController
@RequestMapping("/gateway")
public class GatewayRoutesController {
@Autowired
private RefreshRouteService refreshRouteService;
@Autowired
private DynamicRouteServiceImpl dynamicRouteService;
@GetMapping("/refreshRoutes")
public RestResult refreshRoutes(){
refreshRouteService.refreshRoutes();
return RestResultBuilder.builder().success().build();
}
/**
*
* @param definition
* @return
*/
@RequestMapping(value = "routes/add",method = RequestMethod.POST)
public RestResult add(@RequestBody RouteDefinition definition){
boolean flag = dynamicRouteService.add(definition);
if(flag){
return RestResultBuilder.builder().success().build();
}
return RestResultBuilder.builder().failure().build();
}
/**
*
* @param definition
* @return
*/
@RequestMapping(value = "routes/update",method = RequestMethod.POST)
public RestResult update(@RequestBody RouteDefinition definition){
boolean flag = dynamicRouteService.add(definition);
if(flag){
return RestResultBuilder.builder().success().build();
}
return RestResultBuilder.builder().failure().build();
}
/**
*
* @param serviceId
* @return
*/
@RequestMapping(value = "routes/del",method = RequestMethod.POST)
public RestResult update(@RequestParam("serviceId") String serviceId){
boolean flag = dynamicRouteService.del(serviceId);
if(flag){
return RestResultBuilder.builder().success().build();
}
return RestResultBuilder.builder().failure().build();
}
}
追加および削除。外部被ばくの3つのインタフェース。
これらは、動的リフレッシュルーティングゲートウェイです。
考えます
ダイナミックリフレッシュ操作やメンテナンスを容易にするために、サービス管理で私たちを満たすことができます。しかし、行うために使用されるこの全体ナコスの流通センターからです。そうすることのコストを考えてみましょう。ダイナミックなリフレッシュが本当にそうする必要はありません。コンフィギュレーションは、コンフィギュレーション・センターでリフレッシュすることができます。あなたは、全体のリフレッシュルートをトリガすることができます。あなた自身のオペレーションおよびメンテナンスセンタを構築する必要がある場合。これは、独自の管理システムはダイナミックルーティングを可能にしています。
撮影した参照春の雲公式文書
ナコスサーバアドレスhttp://47.99.209.72:8848/nacos
過去のアドレススプリングクラウド記事のアドレス
春クラウドゲートウェイサービスzuul 3つのダイナミックルーティング
スプリングクラウドalibabaのゲートウェイセンチネルzuul 4つの電流制限ヒューズ
春クラウドゲートウェイゲートウェイサービス2つのアサーション、フィルタ
春クラウドゲートウェイ3つのカスタムフィルタGatewayFilter
どのようにあなたはこの懸念パブリック番号を共有することができますように。
免責事項:この記事はCC 4.0 BY-SAの著作権契約書に従って、ブロガーオリジナル記事です、複製、元のソースのリンクと、この文を添付してください。公共の二次元コード番号を記入してください再版