最全的Gateway统一网关快速入门
• 网关的作用• gateway 快速入门• 断言工厂• 过滤器工厂• 全局过滤器• 跨域问题
一:网关的作用 ?
网关功能:
1.身份认证和权限校验
2.服务路由、负载均衡
网关的技术实现 :
1.gateway:SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。
2.zuul:是基于Servlet的实现,属于阻塞式编程
二:gateway快速入门
搭建网关服务的步骤:
1.创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:因为Gateway也是一个服务,也需要注册到nacos中。也可以使用eureka中。
<!-- nacos服务注册发现依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--网关getway依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
2.编写路由配置及nacos地址:
server:port: 10010
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 #nacos地址gateway:routes:- id: user-service # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**
网关搭建步骤:
路由配置包括:
三:路由断言工厂Route Predicate Factory
网关路由可以配置的内容包括:
1. 路由 id :路由唯一标示2. uri :路由目的地,支持 lb 和 http 两种3. predicates :路由断言,判断请求是否符合要求,符合则转发到路由目的地4. filters :路由过滤器,处理请求或响应路由断言工厂:
1. 我们在配置文件中写的断言规则只是字符串,这些字符串会被 Predicate Factory 读取并处理,转变为路由判断的条件2. 例如 Path=/user/** 是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 类来处理的3. 像这样的断言工厂在 SpringCloudGateway 还有十几个Spring 提供了 11 种基本的 Predicate 工厂,具体见springcloud官网。
1.PredicateFactory的作用是什么?
读取用户定义的断言条件,对请求做出判断。
2.lPath=/user/**是什么含义?
路径是以/user开头的就认为是符合的。
四:路由过滤器 GatewayFilter
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。Spring提供了31种不同的路由过滤器工厂。例如:
实现方式:在gateway中修改application.yml文件,路由添加过滤器:
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 #nacos地址gateway:routes:- id: user-service # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**filters: # 过滤器- AddRequestHeader=Truth, is very good! # 添加请求头.Truth相当妤key,后面为值。
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 #nacos地址gateway:routes:- id: user-service # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**default-filters: # 默认过滤器,会对所有的路由请求都生效- AddRequestHeader=Truth, is very good! # 添加请求头。Truth相当妤key,后面为值。
对所有路由都生效的过滤器,并且可以自定义处理逻辑
五:全局过滤器 GlobalFilter
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。
例如下面案例:需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:
• 参数中是否有 authorization ,• authorization 参数值是否为 admin如果同时满足则放行,否则拦截
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1.获取请求参数MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();// 2.获取authorization参数String auth = params.getFirst("authorization");// 3.校验if ("admin".equals(auth)) {// 放行return chain.filter(exchange);}// 4.拦截// 4.1.禁止访问exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);// 4.2.结束处理return exchange.getResponse().setComplete();}
}
对所有路由都生效的过滤器,并且可以自定义处理逻辑,可以处理自己的逻辑
过滤器执行顺序:
1. 每一个过滤器都必须指定一个 int 类型的 order 值, order 值越小,优先级越高,执行顺序越靠前。2. GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值,由我们自己指定3. 路由过滤器和 defaultFilter 的 order 由 Spring 指定,默认是按照声明顺序从 1 递增。4. 当过滤器的 order 值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行。路由过滤器、defaultFilter 、全局过滤器的执行顺序?① order 值越小,优先级越高② 当 order 值一样时,顺序是 defaultFilter 最先,然后是局部的路由过滤器,最后是全局过滤器
六:跨域问题
跨域:域名不一致就是跨域,主要包括:
1. 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com2. 域名相同,端口不同: localhost:8080 和 localhost8081跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS
spring:cloud:gateway:globalcors: # 全局的跨域处理add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题corsConfigurations:'[/**]':allowedOrigins: # 允许哪些网站的跨域请求 - "http://localhost:8088"- "http://www.leyou.com"allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"allowedHeaders: "*" # 允许在请求中携带的头信息allowCredentials: true # 是否允许携带cookiemaxAge: 360000 # 这次跨域检测的有效期
CORS跨域要配置的参数包括哪几个?
1.允许哪些域名跨域2.允许哪些请求头3.允许哪些请求方式4.是否允许使用 cookie5.有效期是多久