基于Nacos实现Spring Cloud Gateway实现动

作者: King斌 | 来源:发表于2020-06-24 17:28 被阅读0次

    Spring Cloud GateWay集成
    spring-cloud-starter-gateway:路由转发、请求过滤(权限校验、限流以及监控等)

    spring-boot-starter-webflux:反应式Web框架

    spring-boot-starter-actuator:监控系统健康

     <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency> 
     
    <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency></pre>
    
    

    动态路由

    DynamicRouteServiceImpl:提供动态路由的基础方法,可通过获取bean操作该类的方法。该类提供新增路由、更新路由、删除路由,然后实现发布的功能。

    
      @Service
     public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
    
           @Autowired
           private RouteDefinitionWriter routeDefinitionWriter;
      
           private ApplicationEventPublisher publisher;
       
       
           /**
            * 增加路由
            * @param definition
            * @return
           */
           public String add(RouteDefinition definition) {
                routeDefinitionWriter.save(Mono.just(definition)).subscribe();
                this.publisher.publishEvent(new RefreshRoutesEvent(this));
                return "success";
           }
     
           /**
             * 更新路由
             * @param definition
            * @return
            */
            public String update(RouteDefinition definition) {
                try {
                   this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
               } catch (Exception e) {
                   return "update fail,not find route  routeId: "+definition.getId();
              }
              try {
                 routeDefinitionWriter.save(Mono.just(definition)).subscribe();
                     this.publisher.publishEvent(new RefreshRoutesEvent(this));
                     return "success";
                 } catch (Exception e) {
                     return "update route  fail";
                 }
     
           }
            /**
              * 删除路由
              * @param id
              * @return
              */
           public String delete(String id) {
                 try {            
                       this.routeDefinitionWriter.delete(Mono.just(id));
                     return "delete success";
                 } catch (Exception e) {
                      e.printStackTrace();
                     return "delete fail";
                 }
               } 
             @Override
             public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
                 this.publisher = applicationEventPublisher;
             } 
        }
    

    RouteDefinition: 提供路由实体类,主要有predicates匹配来自用户的请求,filters服务路由

    @Validated
    public class RouteDefinition {
        @NotEmpty
        private String id = UUID.randomUUID().toString();
    
        @NotEmpty
        @Valid
        private List<PredicateDefinition> predicates = new ArrayList<>();
    
        @Valid
        private List<FilterDefinition> filters = new ArrayList<>();
    
        @NotNull
        private URI uri;
    
        private int order = 0;
    
        public RouteDefinition() {}
    
        public RouteDefinition(String text) {
            int eqIdx = text.indexOf("=");
            if (eqIdx <= 0) {
                throw new ValidationException("Unable to parse RouteDefinition text '" + text + "'" +
                        ", must be of the form name=value");
            }
    
            setId(text.substring(0, eqIdx));
    
            String[] args = tokenizeToStringArray(text.substring(eqIdx+1), ",");
    
            setUri(URI.create(args[0]));
    
            for (int i=1; i < args.length; i++) {
                this.predicates.add(new PredicateDefinition(args[i]));
            }
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public List<PredicateDefinition> getPredicates() {
            return predicates;
        }
    
        public void setPredicates(List<PredicateDefinition> predicates) {
            this.predicates = predicates;
        }
    
        public List<FilterDefinition> getFilters() {
            return filters;
        }
    
        public void setFilters(List<FilterDefinition> filters) {
            this.filters = filters;
        }
    
        public URI getUri() {
            return uri;
        }
    
        public void setUri(URI uri) {
            this.uri = uri;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            RouteDefinition routeDefinition = (RouteDefinition) o;
            return Objects.equals(id, routeDefinition.id) && Objects.equals(predicates, routeDefinition.predicates) && Objects.equals(order, routeDefinition.order) && Objects.equals(uri, routeDefinition.uri);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id, predicates, uri);
        }
    
        @Override
        public String toString() {
            return "RouteDefinition{" +
                    "id='" + id + '\'' +
                    ", predicates=" + predicates +
                    ", filters=" + filters +
                    ", uri=" + uri +
                    ", order=" + order +
                    '}';
        }
    }
    
    

    NacosGatewayProperties:自定义属性绑定值,可通过配置文件配置属性。

    @ConfigurationProperties(prefix="nacos", ignoreUnknownFields = true)
    @Configuration
    public class NacosGatewayProperties {
    
        private String address;
    
        private String dataId;
    
        private String groupId;
    
        private Long timeout;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getDataId() {
            return dataId;
        }
    
        public void setDataId(String dataId) {
            this.dataId = dataId;
        }
    
        public String getGroupId() {
            return groupId;
        }
    
        public void setGroupId(String groupId) {
            this.groupId = groupId;
        }
    
        public Long getTimeout() {
            return timeout;
        }
    
        public void setTimeout(Long timeout) {
            this.timeout = timeout;
        }    
    }
     
    

    DynamicRouteServiceImplByNacos: 实现runner,通过nacos下发动态路由配置

    @Component
    public class DynamicRouteServiceImplByNacos implements CommandLineRunner{
    
        @Autowired
        private DynamicRouteServiceImpl dynamicRouteService;
    
        @Autowired
        private NacosGatewayProperties nacosGatewayProperties;
    
        /**
         * 监听Nacos Server下发的动态路由配置
         * @param dataId
         * @param group
         */
        public void dynamicRouteByNacosListener (){
            try {
                ConfigService configService=NacosFactory.createConfigService(nacosGatewayProperties.getAddress());
                String content = configService.getConfig(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), nacosGatewayProperties.getTimeout());
                System.out.println(content);
                configService.addListener(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), new Listener()  {
                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        List<RouteDefinition> list = JsonUtils.toList(configInfo, RouteDefinition.class);
                        list.forEach(definition->{
                            dynamicRouteService.update(definition);
                        });
                    }
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }
                });
            } catch (NacosException e) {
               e.printStackTrace();
            }
        }
    
        @Override
        public void run(String... args) throws Exception {
            dynamicRouteByNacosListener();
    
        }
    
    }
    

    nacos属性文件定义

    [
      {
        "id": "desk-route",
        "order": 0,
        "predicates": [
          {
            "name": "Path",
            "args": {
              "pattern": "/blade-desk/**" }
          }
        ],
        "filters": [],
        "uri": "lb://blade-desk-me" },
      {
        "id": "example-route",
        "order": 0,
        "predicates": [{
          "name": "Path",
          "args": {
            "pattern": "/example" }
        }],
        "filters": [],
        "uri": "http://www.example.com" }
    ]
    

    相关文章

      网友评论

        本文标题:基于Nacos实现Spring Cloud Gateway实现动

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