美文网首页springcloudspring cloud gateway
springcloud gateway自定义路由

springcloud gateway自定义路由

作者: virtual灬zzZ | 来源:发表于2022-11-27 19:15 被阅读0次

    一般来说,定义路由只需要在配置文件yml中进行编写,或者使用配置类进行编写。

    yml例子:

    spring:
      cloud:
        gateway:
          routes: 
            - id: test
              uri: http://192.168.1.106:8000
              predicates:
                - Path=/cs/** 
              filters: # 网关过滤器
                - StripPrefix=1
    

    代码配置类:

    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class TestRoute {
    
        @Bean
        public RouteLocator routeLocatorBuilder(RouteLocatorBuilder builder) {
            return builder.routes()
                    .route("test",
                    p -> p.path("/cs/**")
                            .filters(f -> f.stripPrefix(1))
                            .uri("http://192.168.1.106:8000"))
                    //追加
                    //.route()
                    .build();
        }
    }
    

    spring cloud gateway访问微服务

    spring:
      application:
        name: gateway-server
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
        gateway:
          discovery:
            locator:
              enabled: true
    

    enabled=true,表明使用服务名进行调用,如http://localhost:9000/otherService/test,9000是gateway端口,otherService是其他微服务,test是其他微服务的接口。

    同时我们可以自己定制化,设置成false,再如上 自定义访问地址。

    访问地址注意事项

    在gateway中配置uri配置有三种方式,包括
    第一种:ws(websocket)方式: uri: ws://localhost:9000
    第二种:http方式: uri: http://localhost:8130/
    第三种:lb(注册中心中服务名字)方式: uri: lb://brilliance-consumer

    其中ws和http方式不容易出错,因为http格式比较固定,但是lb方式比较灵活自由。不考虑网关,只考虑服务时,服务名命名时比较自由,都能启动被访问,被注册到注册中心,但是如果提供给gateway使用时,就会对服务命名方式有特殊要求了。
    能被gateway的lb方式识别到的命名规则为:

    "[a-zA-Z]([a-zA-Z]|\\d|\\+|\\.|-)*:.*"
    

    这也意味着,java命名规范中可以使用的英文下划线("_")不能被识别,而我命名为:brilliance_consumer,刚好带下划线,改为brilliance-consumer后则可以正常通过网关访问自己项目。
    如果名字中有非“a-zA-Z:.”规则字符,则会报错,
    规则见包org.springframework.cloud.gateway.filter中的类RouteToRequestUrlFilter:

    动态路由

    gateway加载路由配置信息流程
    1 路由初始化

    无论是yml还是代码,这些配置最终都是被封装到RouteDefinition对象中。

    image

    一个RouteDefinition有个唯一的ID,如果不指定,就默认是UUID,多个RouteDefinition组成了gateway的路由系统。

    所有路由信息在系统启动时就被加载装配好了,并存到了内存里。我们从源码来看看。

    圆圈里就是装配yml文件的,它返回的是PropertiesRouteDefinitionLocator,该类继承了RouteDefinitionLocator,RouteDefinitionLocator就是路由的装载器,里面只有一个方法,就是获取路由信息的。该接口有多个实现类,分别对应不同方式配置的路由方式。

    通过这几个实现类,再结合上面的AutoConfiguration里面的Primary信息,就知道加载配置信息的顺序。

    PropertiesRouteDefinitionLocator-->|配置文件加载初始化| CompositeRouteDefinitionLocator RouteDefinitionRepository-->|存储器中加载初始化| CompositeRouteDefinitionLocator DiscoveryClientRouteDefinitionLocator-->|注册中心加载初始化| CompositeRouteDefinitionLocator

    这是第一顺序,就是从CachingRouteLocator中获取路由信息,我们可以打开该类进行验证。

    不管发起什么请求,必然会走上面的断点处。请求一次,走一次。这是将路由信息缓存到了Map中。配置信息一旦请求过一次,就会被缓存到上图的CachingRouteLocator类中,再次发起请求后,会直接从map中读取。

    如果想动态刷新配置信息,就需要发起一个RefreshRoutesEvent的事件,上图的cache会监听该事件,并重新拉取路由配置信息。

    通过下图,可以看到如果没有RouteDefinitionRepository的实例,则默认用InMemoryRouteDefinitionRepository。而做动态路由的关键就在这里。即通过自定义的RouteDefinitionRepository类,来提供路由配置信息。

    例如:

    在getRouteDefinitions方法返回你自定义的路由配置信息即可。这里可以用数据库、nosql等等任意你喜欢的方式来提供。而且配置信息修改后,发起一次RefreshRoutesEvent事件即可让配置生效。

    实现,采用consul配置中心

    ①:监听RefreshRoutesEvent事件,只要别的服务上线或者下线,都会触发该事件。

    @EventListener(RefreshRoutesEvent.class)
    

    ②:读取discoveryClient,即读取配置中心的服务,该类是通用类,配置中心如consul、eureka相关的类都会实现它。

     List<String> services = discoveryClient.getServices().stream().collect(Collectors.toList());
    

    ③ 引入RouteDefinitionWriter ,其实际是InMemoryRouteDefinitionRepository,提供了save和delete路由方法。

    routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
    
    routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
    

    参考:
    详解SpringCloud-gateway动态路由两种方式,以及路由加载过程

    Spring Cloud Gateway 多种思路实现动态路由

    相关文章

      网友评论

        本文标题:springcloud gateway自定义路由

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