Spring Cloud Gateway简介

前言

Spring Cloud Gateway为Spring生态系统上的一个API网关组件,主要提供一种简单而有效的方式路由映射到指定的API,并为他们提供安全性、监控和限流等等。java

前提条件

1.在项目中包含Spring Cloud Gateway,在Maven项目中pom.xml中将groupId=org.springframework.cloudartifactId=spring-cloud-starter-gateway依赖进去,以下:web

<dependencies>	
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
		</dependency>
	</dependencies>

2.若是包含了spring-cloud-starter-gateway启动器,因为某种缘由,不但愿启动gateway,则能够在 application.properties配置文件中进行设置:正则表达式

spring.cloud.gateway.enabled=false

或在application.yml配置:spring

spring:
  cloud:
    gateway:
      enabled: false

3.Spring Cloud Gateway基于Spring Boot2.0,Spring WebFlux和Project Reactor构建;若是想深刻了解建议先了解它们。
4.须要了解的用到词汇
Route(路由):路由网关的基本构建模块,它是由ID、目标URl、断言集合和过滤器集合定义,若是集合断言为真,则匹配路由。
Predicate(断言):这是java 8的一个函数式接口predicate,能够用于lambda表达式和方法引用,输入类型是:Spring Framework ServerWebExchange,容许开发人员匹配来自HTTP请求的任何内容,例如请求头headers和参数paramers.
Filter(过滤器):这些是使用特定工厂构建的Spring Framework GatewayFilter实例,这里能够在发送下游请求以前或以后修改请求和响应。
5.必须知道Spring Cloud Gateway运行流程:
在这里插入图片描述解释:当客户端向spring cloud gateway发送请求,若是网关处理程序映射请求与路由匹配,就将其发送到指定的网关web处理程序服务,此处理程序服务运行并经过特定请求的过滤器以后发送请求,过滤器被虚线划分的缘由是过滤器能够在发送代理请求以前或以后执行逻辑,执行完前面指定"pre"类型的过滤器以后进行代理服务请求,在代理服务请求被执行以后,又执行指定"post"类型的过滤器的相关逻辑处理。安全

具体使用

1、路由断言(Route Predicate)使用
0.使用以前先说一下关于断言predicate的用法:
predicate是java 8中的新特性,java.util.function.Predicate的一个功能接口,可用作lambda表达式的赋值目标。Predicate接口表示采用单个输入并判断返回boolean值的操做;判断的条件可使用与或非(and,or,negate)等,经过一个断言predicate能够重复利用判断。用例:cookie

package com.demo.pakage;

import java.util.function.Predicate;

public class PredicateDemo {

	public static void main(String[] args) {

/* * 1.predicate test()方法 * * */		
		//predicate Sting
		Predicate<String> predicateStr=str->{
			return str.equals("String");			
		};
		//使用test()方法执行断言,输出true,false
		System.out.println(predicateStr.test("String"));
		System.out.println(predicateStr.test("string"));
		//Predicate integer
		Predicate<Integer> predicateInt=i->{
			return i>0;
		};
		//输出true,false
		System.out.println(predicateInt.test(5));
		System.out.println(predicateInt.test(-1));
/* * * 2.predicate add(),or(),negate()方法 * */		
	Predicate<String> predicate=s->{
		return s.equals("String");
	};
	//and()方法,输出true
	Predicate<String> predicateAnd=predicate.and(s->s.length()>5);
	System.out.println(predicateAnd.test("String"));
	//or()方法,输出true
	Predicate<String> predicateOr=predicate.or(s->s.length()==4);
	System.out.println(predicateOr.test("String"));
	//negate()方法,取反,输出false
	Predicate<String> predicateNegate=predicate.negate();
	System.out.println(predicateNegate.test("String"));
	}
}

1.经过配置applicaton.yml文件进行路由断言使用,predicate根据具体的请求规则,匹配具体的route去处理;Spring Cloud Gateway包含不少的内置路由断言(Route Predicate),这些断言能够去匹配HTTP请求的不一样属性如Cookie匹配、Header匹配、Host匹配、Method匹配、Path匹配、Query匹配、RemoteAddr匹配以及匹配路由断言以前或以后或之间的请求。以下图:
在这里插入图片描述app

具体yml配置文件格式以下:svg

spring:
  profiles:
    active: "与下面的某个id值相同"
---
#路由断言以后匹配
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://xxxx.com
        predicates:
        - After=xxxxx
#路由断言以前匹配
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://xxxxxx.com
        predicates:
        - Before=xxxxxxx
#路由断言之间
spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://xxxx.com
        predicates:
        - Between=xxxx,xxxx
#路由断言Cookie匹配,此predicate匹配给定名称(chocolate)和正则表达式(ch.p)
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://xxxx.com
        predicates:
        - Cookie=chocolate, ch.p
#路由断言Header匹配,header名称匹配X-Request-Id,且正则表达式匹配\d+
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://xxxx.com
        predicates:
        - Header=X-Request-Id, \d+
  #路由断言匹配Host匹配,匹配下面Host主机列表,**表明可变参数
  spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://xxxx.com
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
#路由断言Method匹配,匹配的是请求的HTTP方法
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://xxxx.com
        predicates:
        - Method=GET
#路由断言匹配,{segment}为可变参数
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://xxxx.com
        predicates:
        - Path=/foo/{segment},/bar/{segment}
 #能够经过java方法获取{segname}:
#Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
#String segment = uriVariables.get("segment");

#路由断言Query匹配,将请求的参数param(baz)进行匹配,也能够进行regexp正则表达式匹配 (参数包含foo,而且foo的值匹配ba.)
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://xxxx.com
        predicates:
        - Query=baz 或 Query=foo,ba.
#路由断言RemoteAddr匹配,将匹配192.168.1.1~192.168.1.254之间的ip地址,其中24为子网掩码位数即255.255.255.0 
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

2、Gateway Filter过滤器的使用(网关的重点)
上面的Router Predicate路由断言就决定了请求由哪个路由处理,在路由处理以前,须要通过"pre"类型的Filter路由过滤器处理,处理完返回响应以后,又能够由"post"类型的路由过滤器处理。Gateway路由过滤器容许修改传入的HTTP请求和返回的HTTP响应,过滤器能够限定做用在某些特定请求路径上;在"pre"类型的过滤器能够作参数校验、权限校验、流量监控、日志输出、协议转换等;在"post"类型的过滤器能够作响应内容、响应头的修改,日志的输出,流量监控等。所以filter能够分两种类型:"pre"类型和"post"类型。从做用范围又能够分为针对单个路由的filter和针对全部路由的global filter。
Spring Cloud Gateway包含不少内置的GatewayFilter工厂,以下图:
在这里插入图片描述1.列举其中一个Gateway Filter例子:RewritePath GatewayFilter Factory(重写路径,zuul是没有的功能)函数

spring:
		profiles:
			action: rewritepath_route
	---
	spring:
		cloud:
			gateway:
				routes:
				- id: rewritepath_route
				  uri: http://www.baidu.com
				  predicate: 
				  - Path=/foo/**
				  filters:
				  - RewritePath=/foo/(?<segment>.*),/$\{segment}
		profiles: rewritepath_route

上面的配置中,全部的/foo/**开始的路径都会命中配置的router,并执行过滤器的逻辑,在本案例中配置了RewritePath过滤器工厂,此工厂将/foo/(?.*)重写为{segment},而后转发到https://blog.csdn.net/{segment},{segment}为参数值。post

2.自定义过滤器 能够实现本身定义的过滤器,在本身定义的过滤器类中须要实现GatewayFilter接口,主要重写其抽象方法filter(ServerWebExchange,GatewayFilterChain);和实现Ordered接口,重写getOrder()返回该过滤器的优先顺序order;也能够不实现Ordered接口,在启动类调用该过滤器的时候使用注解@Order(-1)来设置优先顺序。 待续。。。。