java B2B2C Springcloud仿淘寶電子商城系統- Gateway運行時動態配置網關

Spring Cloud Gateway官方教程講的都是提早在配置文件中配置網關,實際項目中,Spring Cloud Gateway做爲微服務的入口,須要儘可能避免重啓,因此咱們須要在Spring Cloud Gateway運行時動態配置網關。java

須要JAVA Spring Cloud大型企業分佈式微服務雲構建的B2B2C電子商務平臺源碼 一零三八七七四六二六react

Spring Cloud Gateway自帶接口web

Spring Cloud Gateway在2018年6月份發佈了2.0第一個release版本,官方文檔並無講如何動態配置,翻看Spring Cloud Gateway源碼,發現類org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint中提供了網關配置Restful接口,默認沒有啓用。在類org.springframework.cloud.gateway.config.GatewayAutoConfiguration中配置了GatewayControllerEndpointspring

@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:api

#開啓actuator管理api,後面要關閉bash

management:
  endpoints:
    web:
      exposure:
        include:
複製代碼

編碼方式app

不過這裏咱們不打算用自帶的Restful接口,一來官方文檔也沒說新增網關參數怎麼傳,再者咱們也不但願在網關暴露這些接口。參照org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint,咱們本身編程來動態改變網關。分佈式

直接上代碼:ide

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;
    }
}
複製代碼

代碼說明:

一、predicate.setName("Path"); 設置predicat名稱,這個名稱不是亂起的,Spring會根據名稱去查找對應的FilterFactory,目前支持的名稱有:After、Before、Between、Cookie、Header、Host、Method、Path、Query、RemoteAddr。

二、definition.setId("baiduRoute"); 設置definition的id,須要全局惟一,默認使用UUID。

三、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支持的參數。

四、routeDefinitionWriter.save(Mono.just(definition)).subscribe(); 默認的RouteDefinitionWriter實現類是org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository。注意最後必定要調用subscribe(),不然不執行。

至此已編碼動態配置了一個基本的網關。 java B2B2C Springcloud仿淘寶電子商城系統

相關文章
相關標籤/搜索