用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

it绿萝    -  云代码空间

——

java B2B2C Springcloud仿淘宝电子商城系统- Gateway运行时动态配置网关

2019-01-22|434阅||

摘要:Spring Cloud Gateway官方教程讲的都是提前在配置文件中配置网关,实际项目中,Spring Cloud Gateway作为微服务的入口,需要尽量避免重启,所以我们需要在Spring Cloud Gateway运行时动态配置网关。 需要JAVA Spring Clo

Spring Cloud Gateway官方教程讲的都是提前在配置文件中配置网关,实际项目中,Spring Cloud Gateway作为微服务的入口,需要尽量避免重启,所以我们需要在Spring Cloud Gateway运行时动态配置网关。
需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 yuncode.net
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 B2B2C Springcloud仿淘宝电子商城系统

顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: it绿萝
    • 等级: 高级设计师
    • 积分: 5730
    • 代码: 0 个
    • 文章: 192 篇
    • 随想: 0 条
    • 访问: 15 次
    • 关注

    人气代码

      最新提问

        站长推荐