All Projects → chenggangpro → Spring Cloud Gateway Plugin

chenggangpro / Spring Cloud Gateway Plugin

Licence: apache-2.0
Spring Cloud Gateway Extra Plugin

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Spring Cloud Gateway Plugin

Mall
mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现,采用Docker容器化部署。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。
Stars: ✭ 54,797 (+41412.88%)
Mutual labels:  spring-cloud
Spring Cloud Flycloud
🔥🔥🔥FlyClould 微服务实战项目框架,在该框架中,包括了用 Spring Cloud 构建微服务的一系列基本组件和框架,对于后台服务框架的搭建有很大的参考价值,大家可以参考甚至稍加修改可以直接应用于自己的实际的项目开发中,该项目没有采用Maven进行项目构建,Maven通过xml进行依赖管理,导致整个配置文件太过臃肿,另外灵活性也不是很强,所以我采用Gradle进行项目构建和依赖管理,在FlyTour项目中我们见证了Gradle的强大,通过简单的一些配置就可以轻松的实现组件化的功能。该项目共有11个Module工程。其中10个位微服务工程,这10个微服务工程构成了一个完整的微服务系统,微服务系统包含了8个基础服务,提供了一整套微服务治理功能,他们分别是配置中心module_c…
Stars: ✭ 1,514 (+1046.97%)
Mutual labels:  spring-cloud
Tlog
Lightweight distributed log label tracking framwork
Stars: ✭ 115 (-12.88%)
Mutual labels:  spring-cloud
Sample Spring Oauth2 Microservices
some examples that show basic and more advanced implementations of oauth2 authorization mechanism in spring-cloud microservices environment
Stars: ✭ 109 (-17.42%)
Mutual labels:  spring-cloud
Python Eureka Client
A eureka client written in python. Support registering your python component to Eureka Server, as well as calling remote services by pulling the the Eureka registry.
Stars: ✭ 111 (-15.91%)
Mutual labels:  spring-cloud
Spring Cloud Build
Common build concerns, shared plugin configuration, etc. for Spring Cloud modules
Stars: ✭ 114 (-13.64%)
Mutual labels:  spring-cloud
Spring Boot Admin
Admin UI for administration of spring boot applications
Stars: ✭ 10,415 (+7790.15%)
Mutual labels:  spring-cloud
Spring Cloud
SpringCloud微服务架构,提供快速上手脚手架,快速构建高可用注册中心,高可用配置中心,加入Hystrix断路器,gateway服务官网,权限认证、服务降级、限流,加入应用监控
Stars: ✭ 130 (-1.52%)
Mutual labels:  spring-cloud
Spring Cloud Example
Stars: ✭ 111 (-15.91%)
Mutual labels:  spring-cloud
Piggymetrics
Microservice Architecture with Spring Boot, Spring Cloud and Docker
Stars: ✭ 11,161 (+8355.3%)
Mutual labels:  spring-cloud
Spring Cloud Sleuth
Distributed tracing for spring cloud
Stars: ✭ 1,531 (+1059.85%)
Mutual labels:  spring-cloud
Id Generator
id-generator部署即使用的ID生成器, 支持HTTP、Dubbo、Spring Cloud方式.
Stars: ✭ 112 (-15.15%)
Mutual labels:  spring-cloud
Stock Price Viewer Microservices Part1
Spring Cloud services with 5 microservices - End to End Example
Stars: ✭ 115 (-12.88%)
Mutual labels:  spring-cloud
Spring Cloud Study
spring-cloud学习
Stars: ✭ 108 (-18.18%)
Mutual labels:  spring-cloud
Bytetcc Sample
Stars: ✭ 119 (-9.85%)
Mutual labels:  spring-cloud
Springboot Labs
一个涵盖六个专栏:Spring Boot 2.X、Spring Cloud、Spring Cloud Alibaba、Dubbo、分布式消息队列、分布式事务的仓库。希望胖友小手一抖,右上角来个 Star,感恩 1024
Stars: ✭ 12,804 (+9600%)
Mutual labels:  spring-cloud
Sample Spring Microservices Advanced
More advanced samples of spring boot and spring cloud microservices showing usage of such tools like api Swagger2 on Zuul, integraction with MongoDB, configuration server, testing with Spring Cloud Contract or Hoverfly
Stars: ✭ 112 (-15.15%)
Mutual labels:  spring-cloud
Xc Spring Cloud Alibaba
spring cloud alibaba(2.2.1最新版)+nacos+dubbo+gateWay+sentinel+rocketmq+(pgsql/mysql8.0的json支持)+ignite集成可用于docker分布式框架+分布式自动化任务+mybatis多数据源+seate+ shardingSphere分布式分库事务解决方案
Stars: ✭ 131 (-0.76%)
Mutual labels:  spring-cloud
Sample Spring Microservices Kubernetes
sample spring boot application that uses some features provided by spring cloud kubernetes, spring cloud ribbon and zuul proxy deployed on Kubernetes
Stars: ✭ 123 (-6.82%)
Mutual labels:  spring-cloud
Learning Path Spring Boot Microservices
Curated path for learning Spring Boot & Microservices based on published videos in TechPrimers
Stars: ✭ 116 (-12.12%)
Mutual labels:  spring-cloud

WARNING

This Project Is Archives,Can't catch up the spring-cloud-version.But the code and the thought is much more useful for who want adapt spring-cloud-gateway to his own project

spring-cloud-gateway-plugin

Spring Cloud Gateway Extra Plugin

Build Status

Current Version

Gateway Version Plugin Version
Greenwich.SR1 2.1.SR1.3.RELEASE
Greenwich.SR2 2.1.SR2.2.RELEASE

More Detail See Wiki

This Plugin Support Below Features:

  • [x] Cache Request Body And Form Body
  • [x] Add Request Log Filter To Log Request And Response
  • [x] Add Read Json Response Body And Log Response Body
  • [x] Add Global Exception Handler With Json
  • [x] Add Custom Exception Handler
  • [x] Add Grey Route With Ribbon And Eureka
  • [x] Each Route Use different Hystrix CommandKey
  • [x] Support Dynamic Predicate With Existing Routes

How To Use This Feature

Note:
  • This Dependency Base Spring Cloud Gateway[Greenwich.SR1],Suggest To Update To This SpringCloud Version,Official Resolve Some Issues , Fix Some Bugs.
  • The SpringBoot Version need to update to [2.1.6.RELEASE],It fix reactor-netty issues
  • This Dependency Is Now In Maven Central.
  • The Feature To Read Request And Response Json Data Will Loss A Lot Of Performance,It Will Reduce The Gateway Traffic.
Step
  • 1 . Include Dependency

    Spring Cloud Gateway

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--If you need to use grey route,you should add next dependency ,but grey route only can be used with eureka discover-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    Gateway Plugin

    <dependency>
        <groupId>pro.chenggang</groupId>
        <artifactId>spring-cloud-gateway-plugin</artifactId>
        <version>2.1.SR1.1.RELEASE</version>
    </dependency>
    
  • 2 . Add Enable Annotation To You Application

    @EnableGatewayPlugin
    public class SpringCloudGatewayPluginApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudGatewayPluginApplication.class, args);
        }
    
    }
    

    Note: If You User SpringBoot 2.1.0+,You should set allow-bean-definition-overriding to true

    spring:
      main:
        allow-bean-definition-overriding: true
    
  • 3 . Choose Plugin Feature To Use

    By use this annotation @EnableGatewayPlugin to enable the plugin,the plugin support switch to choose feature By default,the GatewayContext Filter is always into system

    spring:
      profiles:
        active: dev
      cloud:
        gateway:
          plugin:
            config:
              log-request: true
              read-request-data: true # this setting will read all request data
              read-response-data: true
              exception-json-handler: true
              enable-dynamic-route: true
            grey:
              enable: false
              grey-ribbon-rule: weight_response
    
  • 4 . Specific Setting To Enable Read Request Data

    spring:
      cloud:
        gateway:
          plugin:
            config:
              read-request-data-service-id-list:  #set specific serviceId from discover to read request Data
                - serviceId1
                - serviceId2
              read-request-data-path-list:        #set specific path to read request data
                - /service/path1/*
                - /service/path2/**
                - /service/path3  
    
  • 5 . User GatewayContext

    You Can Use GatewayContext To Get Cache JsonBody Or Form Body,Just Use

    GatewayContext gatewayContext = exchange.getAttribute(GatewayContext.CACHE_GATEWAY_CONTEXT);
    
  • 6 . The Deference Between GreyRibbonRule.DEFAULT And GreyRibbonRule.WeightResponse

    The Default GreyRibbonRule Just Use Round Rule As Base Ribbon Rule The WeightResponse GreyRibbonRule Use WeightResponse Rule As Base Ribbon Rule

  • 7 . The Grey Route

    • Setup Gateway Properties
    spring:
      cloud:
        gateway:
          plugin:
              grey:
                grey-rule-list:
                  - service-id: privider1
                    version: 2.0.0
                    operation: OR
                    rules:
                      - key: key1
                        value:
                          - value1
                          - value2
                          - value3
                      - key: key2
                        value:
                          - value4
                          - value5
                          - value6
                  - service-id: provider2
                    version: 2.0.0
                    operation: AND
                    rules:
                      - key: keya
                        value:
                          - value1a
                          - value2a
                          - value3a
                      - key: keyb
                        value:
                          - value4b
                          - value5b
                          - value6b
        
    
    • Set Up Service MetaInfo

      #proiver1
      eureka:
        instance:
          metadata-map:
            version: 2.0.0 
      
    • The Properties Active Rule Principle

      When Request URL Route To Provider1,When The Request JsonBody Or Form Data Contain The Key ->Key1 And Match Any Of The Value->[value1,value2,value3] The Route The Request To The Service Which Setup The MetaInfo With Specific Version Which Match The Gateway Grey Setup

  • 8 . How To Custom GlobalException Handler With Json

    In Order To Handle Other Exception,You Can Define Specific Bean Implements ExceptionHandlerStrategy By default,plugin supply DefaultExceptionHandlerStrategy In Case Of None Strategy Exist

    @Slf4j
    public class DefaultExceptionHandlerStrategy implements ExceptionHandlerStrategy {
    
        @Override
        public Class getHandleClass() {
            return Throwable.class;
        }
    
        @Override
        public ExceptionHandlerResult handleException(Throwable throwable) {
            ResponseResult<String> responseResult = new ResponseResult<>(SystemResponseInfo.GATEWAY_ERROR,throwable.getMessage());
            ExceptionHandlerResult result = new ExceptionHandlerResult(HttpStatus.INTERNAL_SERVER_ERROR, JSON.toJSONString(responseResult));
            log.debug("[DefaultExceptionHandlerStrategy]Handle Exception:{},Result:{}",throwable.getMessage(),result);
            log.error("[DefaultExceptionHandlerStrategy]Log Exception In Error Level,Exception Message:{}",throwable.getMessage());
            return result;
        }
    }
    

    Or You Can Use @ExceptionHandler just like below,

    The@ResponseStatus is optional,if you don't add @ResponseStatus,the default HttpStatus is HttpStatus.BAD_GATEWAY

    @Component
    public class DemoExceptionHandler {
    
        @ExceptionHandler({NotFoundException.class})
        @ResponseStatus(HttpStatus.NOT_FOUND)
        public Map handlerException(ServerWebExchange exchange,TimeoutException throwable){
            LinkedHashSet<URI> originalRequestUris = exchange.getAttributeOrDefault(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR,null);
            Map map = Maps.newHashMapWithExpectedSize(2);
            map.put("URI",originalRequestUris);
            map.put("ExceptionMessage",throwable.getClass().getSimpleName());
            return map;
        }
      
        @ExceptionHandler({ClientException.class, TimeoutException.class})
        @ResponseStatus(HttpStatus.BAD_GATEWAY)
        public Map handlerException(ServerWebExchange exchange,TimeoutException throwable){
              LinkedHashSet<URI> originalRequestUris = exchange.getAttributeOrDefault(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR,null);
              Map map = Maps.newHashMapWithExpectedSize(2);
              map.put("URI",originalRequestUris);
              map.put("ExceptionMessage",throwable.getClass().getSimpleName());
              return map;
        }
    }
    
  • 9 . How To Use Dynamic Predicate With Existing Routes

    • Define A Component Implements DynamicRouteProcessor,this processor process serverWebExchange for dynamic route predicate

    the DynamicRouteProcessor definition

    /**
     * Process ServerWebExchange for dynamic route predicate
     * @author chenggang
     * @date 2019/07/17
     */
    public interface DynamicRouteProcessor<T> {
    
        /**
         * preprocess action
         * @param exchange ServerWebExchange
         * @return process Result ,if result is Optional.empty(),then dynamic predicate not working
         */
        Optional<PreprocessResult<T>> preprocess(ServerWebExchange exchange);
    
        /**
         * process to unify config for predicate
         * @param preprocessResult pre process result
         * @param route current route
         * @return
         */
        Optional<DynamicRouteConfig> processConfig(PreprocessResult<T> preprocessResult, Route route);
    
        /**
         * target predicate bean 's class
         * @return RoutePredicateFactory Class
         */
        Optional<Class< ? extends AbstractRoutePredicateFactory>> targetPredicateBeanClass();
    }
    

    custom dynamic route processor

    @Component
    public class CustomDynamicRouteProcessor implements DynamicRouteProcessor {
    
        @Override
        public Optional<PreprocessResult> preprocess(ServerWebExchange exchange) {
            String route = exchange.getRequest().getHeaders().getFirst("route");
            if(StringUtils.isBlank(route)){
                return Optional.of(PreprocessResult.builder().result(false).build());
            }
            return Optional.of(PreprocessResult.builder().result(true).resultData(route).build());
        }
    
        @Override
        public Optional<DynamicRouteConfig> processConfig(PreprocessResult preprocessResult, Route route) {
            if(!preprocessResult.getResult()){
                return Optional.empty();
            }
            Object resultData = preprocessResult.getResultData();
            if(!(resultData instanceof String)){
                return Optional.empty();
            }
            String data = (String) resultData;
            DemoDynamicRoutePredicateFactory.Config config = DemoDynamicRoutePredicateFactory.Config.builder().header(data).route(route).build();
            return Optional.of(config);
        }
    
        @Override
        public Optional<Class<? extends AbstractRoutePredicateFactory>> targetPredicateBeanClass() {
            return Optional.of(DemoDynamicRoutePredicateFactory.class);
        }
    }
    
    

    Define a AbstractRoutePredicateFactory ,the Config Class Must Implements DynamicRouteConfig

    @Slf4j
    @Component
    public class DemoDynamicRoutePredicateFactory extends AbstractRoutePredicateFactory<DemoDynamicRoutePredicateFactory.Config> {
    
        public DemoDynamicRoutePredicateFactory() {
            super(Config.class);
        }
    
        @Override
        public Predicate<ServerWebExchange> apply(Config config) {
            return exchange -> {
                Route route = config.getRoute();
                if(Objects.isNull(route.getUri())){
                    log.debug("Route Uri Is NUll Return False,RouteID:{}",route.getId());
                    return false;
                }
                String routeUriHost = route.getUri().getHost();
                String headerData = config.getHeader();
                if(StringUtils.isBlank(routeUriHost) || StringUtils.isBlank(headerData)){
                    log.debug("Route Uri Host Or HeaderData Is Blank Return False,RouteID:{}",route.getId());
                    return false;
                }
                if(routeUriHost.equalsIgnoreCase(headerData)){
                    log.debug("Route Uri Host Matched Header Data Return True,RouteID:{}",route.getId());
                    route.getFilters();
                    return true;
                }
                log.debug("Route Uri Not Matched Return False,RouteID:{}",route.getId());
                return false;
            };
        }
    
        @Getter
        @Setter
        @Builder
        @ToString
        @AllArgsConstructor
        public static class Config implements DynamicRouteConfig {
    
            private Route route;
            private String header;
    
        }
    }
    

    This Feature Support dynamic predicate with existing routes,Fox example: You can according the custom header to match the loadbalance route,

    • More logical detail to see DynamicRoutePredicateHandlerMapping
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].