SpringCloudAlibaba基础分享(七)

95 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

image.png

上期讲到gateway网关的基础juejin.cn/post/710706… 今天讲动态网关

动态网关:任何配置都实现不用重启网关服务器都可以及时刷新网关配置。

基于数据库表结构设计

思路:

  • 当我们的网关服务启动的时候,从数据库加载网关配置
  • 数据库内容读取到网关内存

我们可以顺着思路,开发逻辑就是首先更新数据库,然后调用网关api更新。

  1. 更新数据库
  2. 调用网关api更新

loadRoute(gw)方法从数据库中读取到网关GateWayEntity对象后,判断routeType是否是网关路由,写入definition对象中,然后调用网关api更新。

public class GatewayService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher publisher;

    @Autowired

    private RouteDefinitionWriter routeDefinitionWriter;

    @Autowired

    private LijianbGatewayMapper lijianbGateway;



    @Override

    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {

        this.publisher = applicationEventPublisher;

    }



    public void initAllRoute() {

        // 从数据库查询配置的网关配置

        List<GateWayEntity> gateWayEntities = lijianbGateway.gateWayAll();

        for (GateWayEntity gw :

                gateWayEntities) {

            loadRoute(gw);

        }

    }



    public String loadRoute(GateWayEntity gateWayEntity) {

        RouteDefinition definition = new RouteDefinition();

        Map<String, String> predicateParams = new HashMap<>(8);

        PredicateDefinition predicate = new PredicateDefinition();

        FilterDefinition filterDefinition = new FilterDefinition();

        Map<String, String> filterParams = new HashMap<>(8);

        // 如果配置路由type为0的话 则从注册中心获取服务

        URI uri = null;

        if (gateWayEntity.getRouteType().equals("0")) {

            uri = uri = UriComponentsBuilder.fromUriString("lb://" + gateWayEntity.getRouteUrl() + "/").build().toUri();

        } else {

            uri = UriComponentsBuilder.fromHttpUrl(gateWayEntity.getRouteUrl()).build().toUri();

        }

        // 定义的路由唯一的id

        definition.setId(gateWayEntity.getRouteId());

        predicate.setName("Path");

        //路由转发地址

        predicateParams.put("pattern", gateWayEntity.getRoutePattern());

        predicate.setArgs(predicateParams);




        // 名称是固定的, 路径去前缀

        filterDefinition.setName("StripPrefix");

        filterParams.put("_genkey_0", "1");

        filterDefinition.setArgs(filterParams);

        definition.setPredicates(Arrays.asList(predicate));

        definition.setFilters(Arrays.asList(filterDefinition));

        definition.setUri(uri);

        routeDefinitionWriter.save(Mono.just(definition)).subscribe();

        this.publisher.publishEvent(new RefreshRoutesEvent(this));

        return "success";

    }

}

GateWay的词汇表有那些

路由:是网关基本的模块,分别为id、目标uri、一组谓词+过滤器一起组合而成,如果谓词匹配成功,则路由匹配成功。

谓词: 匹配Http请求参数

过滤器:对下游的服务器之前和之后实现处理。

  1. 匹配时间之后
  • id: lijianb

  uri: www.lijianb.com/

  ###匹配规则

  predicates:

    - After=2017-01-20T17:42:47.789-07:00[America/Denver]

此路由与 2017 年 1 月 20 日 17:42 MountainTime(Denver)之后的所有请求相匹配。

  1. 匹配对应的host
  • id: lijianb

  uri: www.lijianb.com/

  ###匹配规则

  predicates:

    - Host=lijianb.com     

访问 lijianb.com 转发到www.lijianb.com/

  1. 权重谓词
  • id: weight_high

  uri: www.lijianb.com/aaa

  predicates:

    - Weight=group1, 2

  • id: weight_low

  uri: www.lijianb.com

  predicates:

    - Weight=group1, 1

根据权重比例实现转发

  • id: weight_order

  uri: lb://lijianb-order

  predicates:

    - Weight=group1,2

  • id: weight_member

  uri: lb://lijianb-member

  predicates:

    - Weight=group1,1