美文网首页
java版spring cloud 多租户社交电子商务-Gate

java版spring cloud 多租户社交电子商务-Gate

作者: IT达人Q | 来源:发表于2019-07-11 09:21 被阅读0次

    电子商务平台源码请加企鹅求求:三伍三六二四柒二五玖。Spring Cloud Gateway官方教程讲的都是提前在配置文件中配置网关,实际项目中,Spring Cloud Gateway作为微服务的入口,需要尽量避免重启,所以我们需要在Spring Cloud Gateway运行时动态配置网关。

    Spring Cloud Gateway自带接口
    Spring Cloud Gateway在2018年6月份发布了2.0第一个release版本,官方文档并没有讲如何动态配置,翻看Spring Cloud Gateway源码,发现类org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint中提供了网关配置Restful接口,默认没有启用。在类org.springframework.cloud.gateway.config.GatewayAutoConfiguration中配置了GatewayControllerEndpoint

    @Configuration
    @ConditionalOnClass(Health.class)
    protected static class GatewayActuatorConfiguration {
    
        @Bean
        @ConditionalOnEnabledEndpoint
        public GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
                                                                List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
                                                                RouteLocator routeLocator) {
            return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
        }
    }
    

    存在org.springframework.boot.actuate.health.Health时启用,添加actuator依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    在gateway项目的application.yml中启用gateway api:

    开启actuator管理api,后面要关闭

    management:
      endpoints:
        web:
          exposure:
            include:
    

    编码方式
    不过这里我们不打算用自带的Restful接口,一来官方文档也没说新增网关参数怎么传,再者我们也不希望在网关暴露这些接口。参照org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint,我们自己编程来动态改变网关。

    直接上代码:

    import java.net.URI;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
    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.context.ApplicationEventPublisherAware;
    import org.springframework.stereotype.Service;
    import org.springframework.web.util.UriComponentsBuilder;
    
    import reactor.core.publisher.Mono;
    
    @Service
    public class TestGatewayService implements ApplicationEventPublisherAware {
    
        @Autowired
        private RouteDefinitionWriter     routeDefinitionWriter;
        private ApplicationEventPublisher publisher;
    
        public String save() {
            RouteDefinition definition = new RouteDefinition();
            PredicateDefinition predicate = new PredicateDefinition();
            Map<String, String> predicateParams = new HashMap<>(8);
    
            definition.setId("baiduRoute");
            predicate.setName("Path");
            predicateParams.put("pattern", "/baidu");
            predicateParams.put("pathPattern", "/baidu");
            predicate.setArgs(predicateParams);
            definition.setPredicates(Arrays.asList(predicate));
            URI uri = UriComponentsBuilder.fromHttpUrl("http://www.baidu.com").build().toUri();
            definition.setUri(uri);
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        }
    
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
            this.publisher = applicationEventPublisher;
        }
    }
    

    代码说明:

    1、predicate.setName("Path"); 设置predicat名称,这个名称不是乱起的,Spring会根据名称去查找对应的FilterFactory,目前支持的名称有:After、Before、Between、Cookie、Header、Host、Method、Path、Query、RemoteAddr。
    2、definition.setId("baiduRoute"); 设置definition的id,需要全局唯一,默认使用UUID。

    3、predicateParams.put("pattern", "/baidu"); 每个Route Predicate的参数不同,详情在官网文档查看对应的Route Predicate配置示例,然而官方文档也很坑,比如Path Route的- Path=/foo/{segment},把参数给省略了。还是得看源码,在包org.springframework.cloud.gateway.handler.predicate里有Spring Cloud Gateway所有的Predicate,打开对应的RoutePredicateFactory,内部类Config就是该Predicate支持的参数。

    4、routeDefinitionWriter.save(Mono.just(definition)).subscribe(); 默认的RouteDefinitionWriter实现类是org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository。注意最后一定要调用subscribe(),否则不执行。

    至此已编码动态配置了一个基本的网关。

    相关文章

      网友评论

          本文标题:java版spring cloud 多租户社交电子商务-Gate

          本文链接:https://www.haomeiwen.com/subject/ebalkctx.html