springcloudAlibaba---微服务网关GateWay

网关

大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?
如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。
每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,会
很蛋疼,完全可以抽出来,放到一个统一的地方去做。
如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一
个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维
护,涉及到数百个域名,另一方面是连接数的瓶颈,想象一下你打开一个APP,通过抓包发现涉及到了数百个远程
调用,这在移动端下会显得非常低效。
后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,
随着业务变的越来越复杂,后期需要进行拆分成多个微服务,这个时候对外提供的服务也需要拆分成多个,同时需
要客户端配合你进行改造,非常蛋疼。
上面的这些问题可以借助API网关来解决。
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑
可以在这里实现,诸如认证、鉴权、监控、路由转发等等。
添加上API网关之后,系统的架构图变成了如下所示:
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑,可以在这里实现,诸如认证、鉴权、监控、路由转发等等。
在这里插入图片描述

什么是springcloud Gateway

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。

Spring Cloud Gateway 功能特征
基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
动态路由:能够匹配任何请求属性;
支持路径重写;
集成 Spring Cloud 服务发现功能(Nacos、Eruka);
可集成流控降级功能(Sentinel、Hystrix);
可以对路由指定易于编写的 Predicate(断言)和 Filter(过滤器);
1.1 核心概念
路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和
配置的路由匹配。
断言(predicates)
Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义
匹配Http request中的任何信息,比如请求头和参数等。
过滤器(Filter)
SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。
1.2 工作原理
执行流程大体如下:

  1. Gateway Client向Gateway Server发送请求
  2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
  3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping
  4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
  5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用
  6. 请求会一次经过PreFilter–微服务–PostFilter的方法,最终返回响应

springcloud Gateway快速开始

1.环境搭建
引入依赖

1 <!‐‐ gateway网关 ‐‐>
2 <dependency>
3 <groupId>org.springframework.cloud</groupId>
4 <artifactId>spring‐cloud‐starter‐gateway</artifactId>
5 </dependency>

2.编写yml文件

1 server:
2  port: 8888
3 spring:
图灵课堂
4  application:
5  name: api‐gateway
6  cloud:
7  gateway:
8  routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
9  ‐ id: product_route # 当前路由的标识, 要求唯一
10  uri: http://localhost:8081 # 请求要转发到的地址
11  order: 1 # 路由的优先级,数字越小级别越高
12  predicates: # 断言(就是路由转发要满足的条件)
13Path=/product‐serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
14  filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
15  ‐ StripPrefix=1 # 转发之前去掉1层路径.

集成Nacos
现在在配置文件中写死了转发路径的地址, 前面我们已经分析过地址写死带来的问题, 接下来我们从注册中心获取此地址。
1.引入依赖

1
2 <!‐‐ nacos服务注册与发现 ‐‐>
3 <dependency>
4 <groupId>com.alibaba.cloud</groupId>
5 <artifactId>spring‐cloud‐starter‐alibaba‐nacos‐discovery</artifactId>
6 </dependency>

编写yml配置文件

1 server:
2  port: 8888
3
4 spring:
5  application:
6  name: api‐gateway
7  cloud:
8  nacos:
9  discovery:
10  server‐addr: 127.0.0.1:8848
11  gateway:
12  discovery:
13  locator:
14  enabled: true

在这里插入图片描述

gateway整合sentinel流控降级

网关作为内部系统外的一层屏障, 对内起到一定的保护作用, 限流便是其中之一. 网关层的限流可以简单地针对不同路由进行限流, 也可针对业务的接口进行限流,或者根据接口的特征分组限流。

  1. 添加依赖
1 <dependency>
2 <groupId>com.alibaba.cloud</groupId>
3 <artifactId>spring‐cloud‐alibaba‐sentinel‐gateway</artifactId>
4 </dependency>
5
6 <dependency>
7 <groupId>com.alibaba.cloud</groupId>
8 <artifactId>spring‐cloud‐starter‐alibaba‐sentinel</artifactId>
9 </dependency>

2.添加配置

1  sentinel:
2  transport:
3  # 添加sentinel的控制台地址
4  dashboard: 127.0.0.1:8080
5

2.6.1 控制台实现方式:
Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自
定义 API 分组监控,管理网关规则和 API 分组配置。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
自定义异常方式:
1.通过yml
1 spring:cloud.sentinel.scg.fallback.mode = response
2 spring.cloud.sentinel.scg.fallback.response‐body = ‘{“code”:403,“mes”:“限流了”}’
2.通过GatewayCallbackManager

5 @Configuration
6 public class GatewayConfig {
    
    
7
8  @PostConstruct
9 public void init(){
    
    
10  BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
    
    
11  @Override
12 public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
    
    
13 return ServerResponse.status(HttpStatus.OK)
14 .contentType(MediaType.APPLICATION_JSON)
15 .body(BodyInserters.fromValue("降级了!"));
16 }
17 };
18
19  GatewayCallbackManager.setBlockHandler(blockRequestHandler);
20 }
21 }

猜你喜欢

转载自blog.csdn.net/wangjunlei666/article/details/129895193