1. 什么是Gateway
Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0 和 Project Reactor 等术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代 Netflflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。
优点:
l 性能强劲:是第一代网关Zuul的1.6倍
l 功能强大:内置了很多实用的功能,例如转发、监控、限流等
l 设计优雅,容易扩展
缺点:
l 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
l 不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
l 需要Spring Boot 2.0及以上的版本,才支持
2. Gateway--服务网关
大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。
这样的架构,会存在着诸多的问题:
l 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
l 认证复杂,每个服务都需要独立认证。
l 存在跨域请求,在一定场景下处理相对复杂。
上面的这些问题可以借助API网关来解决。
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服 务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等等。 添加上API网关之后,系统的架构图变成了如下所示:
3. 使用Gateway
单独创建GatewayMaven工程
【注:Gateway本质来说也是一个子服务模块】
【注:Gateway是和xw-serve、xw-comm服务模块同级】
在其pom文件加入依赖:
<!--加入gateway的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
【注:还有在工程中创建启动类】
3.1 进行Gateway配置
创建application.yml配置文件在其中配置子服务模块信息:
【注:可以是yml后缀的配置文件,因为用properties后缀的配置文件比较麻烦】
3.1.1 复杂配置设置:
server: port: 8851 spring: application: name: gateway #服务名称 # 配置子服务模块api #【注:可以配置多个子服务模块】 cloud: gateway: routes: - id: order # 路由的唯一标识,只要不重复都可以,如果不写默认会通过UUID产生,一般写成被路由的服务名称 uri: http://localhost:8082/ # 被路由的地址(去向子服务模块的地址+端口) order: 1 #表示优先级 数字越小优先级越高 predicates: #断言: 执行路由的判断条件 - Path=/product_serv/** filters: # 过滤器: 可以在请求前或请求后作一些手脚 - StripPrefix=1
3.1.2 简单配置设置及Gateway前后端跨域:
server: port: 8851 spring: application: name: gateway # 配置api cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOriginPatterns: "*" allowedHeaders: "*" allowedMethods: "*" allowCredentials: true # default-filters: # - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST discovery: locator: enabled: true
【注:使用Gateway本身不能跟web依赖共存】
【注:使用Gateway只需要其本身配置跨域信息即可,子服务模块不需要配置跨域信息】
【注:一切都以通过Gateway去访问子服务模块】
访问路径:ip地址:Gateway端口号/子服务模块微服务微服务名称/要访问的子服务路径
3.1 自定义Gateway全局拦截器
创建com.aaa包下config包下
AuthGlobalFilter
配置类:com -> aaa -> congif ->
AuthGlobalFilter
@Component public class AuthGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //获取请求头中的token值 ServerHttpRequest request = exchange.getRequest(); String token = request.getHeaders().getFirst("token"); //判断token是否为空 if (StringUtils.isEmpty(token)){ exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); }else { //不为空则校验token,校验通过将token存入Redis中 try { Claims claims = JwtUtils.parseJWT(token); return chain.filter(exchange); }catch (Exception e){ e.printStackTrace(); throw new RuntimeException("token非法"); } } } @Override public int getOrder() { return 0; } }
【注:此配置文件作为Gateway检测前端每次发起请求是否携带token】
【注:此配置文件后期可根据业务需求进行更改拦截条件】
4. 将heads注入容器获取token
注:【假如有需求需要使用到用户id或用户信息从token中解析取值】
该如何?
通过注入HTTPServletRequest 来获取request 对象:
@Resource private HttpServletRequest request;
String token = request.getHeader("token");//从请求头中获取token Claims claims = JwtUtils.parseJWT(token);//解析token // 将这个map转化为对象 List token1 = (List) claims.get("token"); Map o = (Map) token1.get(0); user user = BeanUtil.fillBeanWithMap(o, new user(), false);//将集合转换对象 int id = user.getId();//获取到了用户id
以上便是SpringCloud之Gateway中的内容,如有漏缺请在下方留言告知,我会及时补充
标签:网关,服务,SpringCloud,token,模块,Gateway,路由 From: https://www.cnblogs.com/9--1/p/17727890.html