spring cloud gateway

在写之前,想写一下感受,之前有对接过springcloud的项目,有以下几个感受

1.我们请求所有接口,都是请求同一个端口,路径不同,都会加一个token来验证权限

我感觉是这么实现的,服务器对外访问只开放gateway项目端口,然后加一个token来全局filter

当然,我不是这个项目的设计师,这是凭空想象而已。

简介

This project provides an API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

该项目提供了一个在spring生态系统上构建的api网关,包括spring 5,spring boot2和project reactor.spring cloud gateway旨在提供一个简单有效的路由到apis并且提供跨领域的关注点如:安全,检测、指标和弹性。

术语
  • Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true.----Route是gateway中最基本块,如果所有predicate是true,那么route会被匹配

  • Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.通过java8提供的Predicate,我们可以匹配HttpRequest中的,headers或者parameters

  • Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.我们可以在发送给下游之前修改请求或者之后修改返回回来的响应。这里,我们用下面一张图来解释

    G52mV0.png

    ​ 从图中,我们需要注意到Filter中是支持请求前,和响应后的处理的

装配spring cloud gateway

pom

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
<!--暂时先注释 
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
-->
<!--spring cloud version :Hoxton.SR3-->

application.yml

management:
  endpoints:
    web:
      exposure:
        include: "*"
server:
  port: 10000
#spring: 此处注释改为java注入
#  cloud:
#    gateway:
#      routes:
#        - id: first
#          uri: http://localhost:9000
#          predicates:
#            - Path=/**
logging:
  level:
    org.springframework.cloud.gateway: debug

java注入

    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
      return builder.routes()
                .route(r->r.path("/**")
                      .uri("http://localhost:9000").id("first")
                ).build();
    }

测试

D:\gitclonepackage\cloud>curl http://localhost:10000/hello/huskyui
hello, huskyui Mon Apr 13 17:25:28 CST 2020
介绍predicate
java8中的predicate,就是filter里面的函数。这是一个比较直观的例子
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8,9));
list.stream().filter(t->t<5).forEach(System.out::println);
输出 1,2,3,4
PathRoutePredicateFactory
@Bean
public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
    return builder.routes()
        .route(r->r.path("/**")
        .uri("http://localhost:9000").id("first")
    ).build();
}      
放开了/**,也就是放开了所有http://localhost:9000所有路径
D:\gitclonepackage\cloud>curl http://localhost:10000/hello/huskyui
hello, huskyui Mon Apr 13 17:25:28 CST 2020
CookieRoutePredicateFactory
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
        return builder.routes()
                .route(r->r
                        .cookie("token","kee.e")
                        .uri("http://localhost:9000").id("first")
                ).build();
    }
D:\gitclonepackage\cloud>curl http://localhost:10000/hello/huskyui
{"timestamp":"2020-04-13T10:03:43.548+0000","path":"/hello/huskyui","status":404,"error":"Not Found","message":null,"requestId":"b330030a-1"}
D:\gitclonepackage\cloud>curl http://localhost:10000/hello/huskyui --cookie "token=keexe"
hello, huskyui Mon Apr 13 18:03:55 CST 2020
D:\gitclonepackage\cloud>curl http://localhost:10000/hello/huskyui --cookie "token=keeeee"
{"timestamp":"2020-04-13T10:09:09.207+0000","path":"/hello/huskyui","status":404,"error":"Not Found","message":null,"requestId":"23aba850-3"}
组合使用
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
        return builder.routes()
                .route(r->r
                        .method(HttpMethod.POST)
                        .and()
                        .path("/**")
                        .and()
                        .cookie("token","kee.e")
                        .uri("http://localhost:9000").id("first")
                ).build();
    }
D:\gitclonepackage\cloud>curl -X POST  http://localhost:10000/hello/huskyui --cookie "token=keeie"
hello, huskyui Mon Apr 13 18:13:54 CST 2020
自定义Predicate
// 我们先去看一下cookie判断的源码  CookieRoutePredicateFactory.java
	@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange exchange) {
				List<HttpCookie> cookies = exchange.getRequest().getCookies()
						.get(config.name);
				if (cookies == null) {
					return false;
				}
				for (HttpCookie cookie : cookies) {
					if (cookie.getValue().matches(config.regexp)) {
						return true;
					}
				}
				return false;
			}

			@Override
			public String toString() {
				return String.format("Cookie: name=%s regexp=%s", config.name,
						config.regexp);
			}
		};
	}
// 很好理解的代码,我们写一串header判断的
 @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.predicate(t -> {
                            List<String> values= t.getRequest().getHeaders().get("token");
                            if(values==null || values.isEmpty()){
                                return false;
                            }
                            return values.stream().anyMatch(value->value.equals("123456"));
                        })
                                .uri("lb://eureka-consumer").id("first")
                ).build();
    }
 D:\gitclonepackage\cloud>curl -X POST http://localhost:10000/hello/huskyui --header "token: 123456"
hello, huskyui Thu Apr 16 14:58:20 CST 2020

介绍filter

Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.

路由过滤器可以修改HTTP请求和HTTP响应,路由过滤器的作用域是特定的路由。spring cloud gateway有很多内置的网关过滤器的工厂。

使用PathRoutePredicateFactory和StripPrefixGatewayFilterFactory实现对特定项目访问
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/consumer/**")
                        .filters(f->f.stripPrefix(1))
                                .uri("lb://eureka-consumer").id("first")
                ).build();
    }
D:\gitclonepackage\cloud>curl -X POST http://localhost:10000/consumer/hello/huskyui
hello, huskyui Thu Apr 16 15:16:31 CST 2020
// 在访问的时候,由于stripPrefix是1,会去除/consumer这一层,真正的会转发成
    // lb://eureka-consumer/hello/huskyui
修改RequestBody中信息
        @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/producer/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(Map.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (serverWebExchange, s) -> {
                                    System.out.println(s);
                                    s.put("name","adios");
                                    return Mono.just(s);
                                }))
                        .uri("lb://eureka-producer").id("first")
                ).build();
    }
// 可以看到这个s的类型是Map.class,我修改的对应name的值,

POST http://localhost:10000/producer/hello
Content-Type: application/json

{
"name": "huskyui"
}


hello, adios Thu Apr 16 18:34:56 CST 2020
// 可以看到我修改对应的requestBody的值,在控制台也打印了初始RequestBody请求json(上面请求方式是通过idea里面内置的请求方式)

全局拦截器

The GlobalFilter interface has the same signature as GatewayFilter. These are special filters that are conditionally applied to all routes.

GlobalFilter接口具有与gatewayFilter相同的签名,这些是特殊过滤器,有条件地应用于所有路由。

后续

从现在开始,暂停更新spring cloud gateway相关博客,我先去学点别的了。学习这种并没有什么用。

参考

纯洁的微笑写的spring cloud文档

windmt写的文档

spring cloud gateway官方文档

github上spring cloud gateway提供的samples

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值