SpringGateway 结合服务注册发现机制, 实现服务自动注册网关

206 阅读1分钟

一、gateway的标准使用

我们在gateway服务配置中, 每新增一个服务, 我们需要手动增加一个route配置项

server:

  port: 8080

spring:

  application:

    name: app_name

  cloud:

    gateway:

      # 跨域处理

      globalcors:

        cors-configurations:

          '[/**]':

            allowed-origins: "*"

            allowed-headers: "*"

            allow-credentials: true

            allowed-methods:

              - GET

              - POST

              - DELETE

              - PUT

              - OPTION

              - PATCH

      # 路由转发

      routes:

        - id: exchange-admin-server

          uri: lb://rdc-exchange-admin${spring.profiles.active}-service

          predicates:

            - Path=/admin/api/v1/**

         - id: exchange-web-server

          uri: lb://rdc-exchange${spring.profiles.active}-service

          predicates:

            - Path=/api/v1/**

2. 结合Discovery的服务发现机制, 实现自动的服务路由转发代理注册

通过DiscoveryClient获取服务列表, 然后通过正则匹配出需要路由转发的服务, 然后使用 /service-id/** 的方式来做统一路由转发处理

@Slf4j

@Component

public class RouterAutoRegistry implements InitializingBean {

 

    @Resource

    private DiscoveryClient discoveryClient;

 

    @Resource

    private RouteDefinitionWriter routeDefinitionWriter;

 

    @Resource

    private ApplicationEventPublisher publisher;

 

    @Value("${server.pattern:rdc([\\s\\S]*?)service}")

    private String serverPattern;

 

    private static Map<String, RouteDefinition> definitions = new ConcurrentHashMap<>();

 

    @Scheduled(cron = "0/30 * * * * ? ")

    public void registryRouter() {

        log.info("refresh gateway routers");

 

        discoveryClient.getServices()

                .stream()

                .filter(x -> x.matches(serverPattern))

                .filter(x -> definitions.get(x) == null)

                .forEach(x -> {

                    RouteDefinition definition = new RouteDefinition();

                    definition.setId(x);

                    definition.setUri(URI.create("lb://" + x));

 

                    // 设置匹配断言 /serviceId/**

                    PredicateDefinition predicateDefinition = new PredicateDefinition();

                    predicateDefinition.setName("Path");

                    Map<String, String> predicateArgs = new HashMap<>(16);

                    predicateArgs.put("pattern", "/" + x + "/**");

                    predicateDefinition.setArgs(predicateArgs);

 

                    definition.setPredicates(Lists.newArrayList(predicateDefinition));

 

                    //设置过滤器  RewritePath: /serviceId/** -> /**

                    FilterDefinition filterDefinition = new FilterDefinition();

                    filterDefinition.setName("RewritePath");

                    Map<String, String> filterArgs = new HashMap<>(16);

                    filterArgs.put("regexp", "/" + x + "/(?<segment>.*)");

                    filterArgs.put("replacement", "/$\\{segment}");

                    filterDefinition.setArgs(filterArgs);

 

                    definition.setFilters(Lists.newArrayList(filterDefinition));

 

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

                    definitions.put(x, definition);

 

                    log.info("auto registry discovery server router: {} -> {}", x, definition);

                });

 

        publisher.publishEvent(new RefreshRoutesEvent(this));

 

    }

 

 

    @Override

    public void afterPropertiesSet() {

        registryRouter();

    }

}