简介:java系列技术共享(继续更新中…)
初衷:一起学习、一起前进、坚持不懈
假如文章内容有误与您的主意不一致,欢迎大家在评论区指正
期望这篇文章对你有所协助,欢迎点赞 保藏 ⭐留言
一、Gateway简介
Gateway官网
:spring.io/projects/sp…
Spirng Cloud 中网关的完成包含两种:
- gateway
- zuul
zuul是根据Servlet的完成,归于堵塞式编程,而Spring Cloud Gateway
则是根据Spring 5 中供给的WebFlux,归于呼应式编程的完成,具有更好的性能。
Spring Cloud Gateway是Spring官方根据Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构供给一种简单而有效的一致的API路由办理方法。Spring Cloud Gateway作为Spring Cloud生态系中的网关,方针是代替Netflix ZUUL
,其不仅供给一致的路由方法,而且根据Filter链的方法供给了网关根本的功用,例如:身份验证,权限效验,服务路由,负载均衡,恳求限流。
二、Spring Cloud Gateway入门事例
本篇文章将介绍Spring Cloud Alibaba系统下Spring Cloud Gateway的建立,服务注册中心和分布式装备中心运用Nacos
2.1 父工程依靠
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<!-- springCloud -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba是阿里巴巴集团针对服务开发所供给的一套处理方案 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.2 gateway网关建立
2.2.1 pom依靠
<dependencies>
<!-- nacos作为注册中心的依靠 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
2.2.2 yml装备
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务称号
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由装备
- id: consumer-server # 路由id,自定义,只需仅有即可
# uri: http://127.0.0.1:20087 # 路由的方针地址 http便是固定地址
uri: lb://consumer-server # 路由的方针地址 lb便是负载均衡,后面跟服务称号
predicates: # 路由断语,也便是判别恳求是否符合路由规矩的条件
- Path=/consumer/** # 这个是依照途径匹配,只需以/user/最初就符合要求
-
- id: provider-server
# uri: http://127.0.0.1:8081
uri: lb://provider-server
predicates:
- Path=/provider/**
-
路由id
: 路由的仅有标识 -
路由方针(uri)
: 路由的方针地址,http代表固定地址,lb代表根据服务名负载均衡 - `路由断语(predicates) : 判别路由的规矩
-
路由过滤器filters()
: 对恳求或呼应做处理
2.2.3 或许存在的问题
发动报错
***************************
APPLICATION FAILED TO START
***************************
Description:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
Action:
Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
Exception in thread "main" java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration]: Constructor threw exception; nested exception is org.springframework.cloud.gateway.support.MvcFoundOnClasspathException
产生原因
gateway的内部是经过netty+webflux完成的,webflux完成和springmvc装备依靠冲突。
处理方案:
- 去除父工程中的
spring-boot-starter-web
这个依靠 - 或许如下扫除
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
假如uri运用lb负载均衡装备,或许会报错如下:
发动正常,调用或许会出现,没有可用的服务等信息
There was an unexpected error (type=Service Unavailable, status=503).
增加如下依靠
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2.2.4 调用测验成功
未运用网关
运用网关10010端口调用
三、网关路由流程图
四、Nginx网关和GateWay网关的区别
-
Nignx是流量网关,GateWay是事务网关
-
流量网关相当于拜访的一个总入口,前端页面的一个容器,类似于防火。首要的功用有办理日志,流量监控,黑白名单,恳求的负载均衡,大局限流等。
-
而事务网关是针对具体的后端应用和服务,首要的功用是缓存策略、鉴权策略等
-
一般流量网关装备在前,事务网关装备在后
-
Nginx是C语言写的,GateWay是java语言写的
-
GateWay首要是路由、断语和过滤器,利用这些能够做流控
五、路由断语工厂
官网12种示例地址
: docs.spring.io/spring-clou…
六、过滤器工厂
6.1 GatewayFilter路由过滤器
官网示例地址
: docs.spring.io/spring-clou…
GatewayFilter是网关中供给的一种过滤器,能够对进入网关的恳求和微服务回来的呼应做处理.。
6.2 默认过滤器
要对所有的路由都生效,则能够将过滤器工厂写到defalut下
spring:
cloud:
gateway:
routes: # 网关路由装备
- id: consumer-server # 路由id,自定义,只需仅有即可
# .....
default-filters:
- AddRequestHeader=X-Request-red, blue
6.3 大局过滤器
大局过滤器,对所有路由生效。经过完成GlobalFilter接口创立
大局过滤器的效果是处理全部进入网关的恳求和微服务呼应,与GarewayFilter的效果相同
区别在于GatewayFilter经过装备定义,处理逻辑是固定的,而GlobalFilter的逻辑需求自己写代码完成,定义方法是完成GlobalFilter接口
示例
@Order(-1) //值越小,优先级越高
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public 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();
}
}
6.4 过滤器履行次序
- 大局过滤器与其他2类过滤器相比,永远是最终履行的,它的优先级只对其他大局过滤器起效果,
order 值越小,优先级越高,履行次序越靠前
- 路由过滤器和默认过滤器会依照order的值进行排序,这个值由 Spring 指定,
默认是依照声明次序从1递增。
- 当过滤器的order值相同时,会依照 defaultFilter > 路由过滤器 的次序履行
七、跨域问题
spring:
cloud:
gateway:
# 。。。
globalcors: # 大局的跨域处理
add-to-simple-url-handler-mapping: true # 处理options恳求被阻拦问题
corsConfigurations:
'[/**]':
allowedOrigins: # 答应哪些网站的跨域恳求
- "http://localhost:8090"
allowedMethods: # 答应的跨域ajax的恳求方法
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 答应在恳求中带着的头信息
allowCredentials: true # 是否答应带着cookie
maxAge: 360000 # 这次跨域检测的有效期