irpas技术客

面试常问系列之Gateway网关_NoviceZ_gateway面试题

大大的周 2341

API 网关的定义

网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。

API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

API 网关的职能 请求接入:作为所有API接口服务请求的接入点业务聚合:作为所有后端业务服务的聚合点中介策略:实现安全、验证、路由、过滤、流控等策略统一管理:对所有API服务和策略进行统一管理 使用Gateway的优势

Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。 Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。 比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。 比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。

Gateway的使用 调用流程分析

注意事项:

Predicate(断言)要先于Filter调用,断言为真才能进行路由匹配,而Filter过滤器又分为两种,局部过滤器Gateway Filter和全局过滤器Global Filter.在全局过滤器中可以设置全局过滤器的优先级别,所以两者的调用顺序是由设置的优先级别决定的.

配置格式:

spring: cloud: gateway: routes: - id: route01 #路由id,自己指定一个唯一值即可 uri: lb://sca-provider #用于获取指定服务名的服务列表 predicates: #断言(谓词):定义请求规则 #断言内容 filters: #网关过滤器,用于对谓词中的内容进行判断分析以及处理 #过滤器内容 几个重要概念

Route(路由):

这是网关的基本构建块.它由一个id,一个目标uri,一组断言和一组过滤器定义.如果断言为真,则路由匹配.

Predicate(断言):

输入类型是一个ServerwebExchange.我们可以使用它来匹配来自HTTP请求的任何内容,例如headers或参数.说白了Predicate就是事先定义了一组匹配规则,方便让请求过来找到对应的 Route 进行处理.

过滤器(filter):

Gateway中的Filter分为两种类型,分别是Gateway Filter和Global Filter.过滤器Filter将会对请求和响应进行修改处理.

综合使用进行匹配 添加测试方法 @GetMapping("/provider/name") public String name(String name){ return "my name is "+name; } 创建配置文件 server: port: 9000 spring: application: name: sca-gateway cloud: nacos: discovery: server-addr: localhost:8848 gateway: routes: #配置网关路由规则 - id: route01 #路由id,自己指定一个唯一值即可 #uri: http://localhost:8082/ #网关帮我们转发的url uri: lb://sca-provider #用于获取指定服务名的服务列表 predicates: #断言(谓词):定义请求规则 #- Path=/nacos/provider/echo/** #请求路径定义,此路径对应uri中的资源,多层目录 - Path=/nacos/provider/name - After=2021-08-23T15:00:00.545+08:00[Asia/Shanghai] - Header=X-Request-Id, \d+ #添加请求头信息 - Query=pageSize,\d+ #添加请求参数信息 filters: #网关过滤器,用于对谓词中的内容进行判断分析以及处理 - StripPrefix=1 #转发之前去掉path中的第一层路径,例如nacos - AddRequestParameter=name,zzll #自动添加请求参数 - AddRequestHeader=X-Request-Foo,Bar #自动添加请求头 discovery: locator: enabled: true #开启基于服务名获取服务实例的功能(基于服务名创建路由) #配置白名单 white: prefix: /nacos #path路径以nacos开头的才能进行下一步操作(白名单) 创建全局过滤器 package com.jt.config; import com.google.gson.Gson; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.HashMap; import java.util.Map; @Component//交给spring管理 public class AuthGatewayFilter implements GlobalFilter, Ordered { /** * @param exchange 基于此对象可以获取请求和响应对象 * @param chain 这个对象指向了一个过滤链(这个链中有多个过滤器) * @return */ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //1.获取请求对象 ServerHttpRequest request = exchange.getRequest(); //2.获取请求数据 String path = request.getURI().getPath(); System.out.println(path); String username = request.getQueryParams().getFirst("username"); System.out.println("pageSize="+request.getQueryParams().getFirst("pageSize")); //3.对请求数据进行处理 System.out.println("whitePrefix="+whitePrefix); if (!path.startsWith(whitePrefix)){//判断path路径是否以nacos开头,不是则返回一个JSON串 ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.BAD_GATEWAY); Map<String,Object> map = new HashMap<String, Object>(); map.put("message", "request failure"); map.put("status", 502); Gson gson = new Gson();//需先添加gson依赖 String jsonStr = gson.toJson(map);//将map对象转为JSON字符串 byte[] bytes = jsonStr.getBytes(); DataBuffer dataBuffer=response.bufferFactory().wrap(bytes); return response.writeWith(Mono.just(dataBuffer)); } //4.返回响应结果 return chain.filter(exchange); } public int getOrder() { return Ordered.HIGHEST_PRECEDENCE;//设置全局过滤器的优先级别为最高级,则先经过全局过滤器 } @Value("${white.prefix}")//获取配置文件中的白名单 private String whitePrefix; } 使用postman进行测试

成功案例:

?

失败案例:

如果将path路径的nacos改为其它,如sentinel,即

- Path=/sentinel/provider/name

重新启动后再次测试:


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #gateway面试题 #API #网关的定义网关的角色是作为一个 #架构用来保护增强和控制对于 #服务的访问