当前位置:   article > 正文

微服务架构--之Gateway(网关)总结_网关 如何判断请求

网关 如何判断请求

网关处理流程图

在这里插入图片描述

1.Gateway--Pom文件 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>01-sca</artifactId>
  7. <groupId>com.jt</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>sca-gateway</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <!--添加gateway依赖:假如依赖下载不下来:
  18. 1)保证网络没有问题(手机网络,公司网络)
  19. 2)保证maven配置正确(maven软件,远程仓库)
  20. 3)本地库(本地库中尽量不要存在同一个资源的多个版本)
  21. -->
  22. <dependency>
  23. <groupId>org.springframework.cloud</groupId>
  24. <artifactId>spring-cloud-starter-gateway</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>com.alibaba.cloud</groupId>
  28. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  29. </dependency>
  30. <!--拓展:基于如下依赖中的API可以实现对象与json字符串之间转换-->
  31. <dependency>
  32. <groupId>com.google.code.gson</groupId>
  33. <artifactId>gson</artifactId>
  34. <version>2.8.5</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>com.alibaba.cloud</groupId>
  38. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  39. </dependency>
  40. <dependency>
  41. <groupId>com.alibaba.cloud</groupId>
  42. <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.springframework.boot</groupId>
  46. <artifactId>spring-boot-starter-actuator</artifactId>
  47. </dependency>
  48. </dependencies>
  49. </project>

2.核心配置文件

  1. server:
  2. port: 9000
  3. spring:
  4. application:
  5. name: sca-gateway
  6. cloud:
  7. nacos:
  8. discovery:
  9. server-addr: localhost:8848
  10. sentinel:
  11. transport:
  12. dashboard: localhost:8180
  13. #port: 8719
  14. eager: true #服务启动时会会向sentinel控制台发送心跳,为我们的应用创建菜单
  15. gateway: # API Gateway (负责API管理)
  16. discovery:
  17. locator:
  18. enabled: true #开启基于服务名获取服务实例的功能(基于服务名创建路由)
  19. routes: #网关路由配置
  20. - id: router01 #http://localhost:9000/nacos/provider/echo/hello
  21. #uri: http://localhost:8081
  22. uri: lb://sca-provider #lb表示负载均衡,底层默认使用ribbon实现
  23. predicates: #定义请求规则(请求需要按照此规则设计)
  24. - Path=/nacos/provider/echo/** #请求路径设计
  25. #- After=2021-08-23T13:59:59.789+08:00[Asia/Shanghai]
  26. #- Header=X-Request-Id, \d+ #\d+表示任何一个数字
  27. #- Method=GET
  28. #- Query=pageSize,\d+
  29. filters:
  30. - StripPrefix=1 #转发之前去掉path中第一层路径,例如nacos
  31. #- AddRequestHeader=X-Request-Foo, Bar
  32. #- AddRequestParameter=foo, hello
  33. #自己定义白名单路径
  34. white:
  35. prefix: /nacos
  36. # 假如希望调整负载均衡算法,可参考如下配置方式
  37. sca-provider: #这个名字为指定的服务名
  38. ribbon:
  39. #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
  40. NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  1. id,路由标识符,区别于其他 Route。
  2. uri,路由指向的目的地 uri,即客户端请求最终被转发到的微服务。
  3. predicate,断言(谓词)的作用是进行条件判断,只有断言都返回真,才会执行路由。
  4. filter,过滤器用于修改请求和响应信息。

3.断言(Predicate)分析 

3.1请求时间判断

此类型的断言根据时间做判断,主要有三个:

1) AfterRoutePredicateFactory:判断请求日期是否晚于指定日期
2) BeforeRoutePredicateFactory:判断请求日期是否早于指定日期
3) BetweenRoutePredicateFactory:判断请求日期是否在指定时间段内

-After=2020-12-31T23:59:59.789+08:00[Asia/Shanghai]

当且仅当请求时的时间After配置的时间时,才转发该请求,若请求时的时间不是After配置的时间时,则会返回404 not found。时间值可通过ZonedDateTime.now()获取.

 3.2请求头判断

判断请求Header是否具有给定名称且值与正则表达式匹配。例如:

-Header=X-Request-Id, \d+

3.3请求方式判断

MethodRoutePredicateFactory接收一个参数,判断请求类型是否跟指定的类型匹配。例如:

-Method=GET

3.4请求参数判断

接收两个参数,请求param和正则表达式, 判断请求参数是否具 有给定名称且值与正则表达式匹配。例如:

-Query=pageSize,\d+

4.过滤器(Filter)增强分析

过滤器(Filter)就是在请求传递过程中,对请求和响应做一个处理。Gateway 的Filter从作用范围可分为两种:GatewayFilter与GlobalFilter。其中: 

GatewayFilter:应用到单个路由或者一个分组的路由上。
GlobalFilter:应用到所有的路由上

局部过滤器实现(配置文件中的filters) 

基于AddRequestHeaderGatewayFilterFactory,为原始请求添加Header。 

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_header_route
  6. uri: https://example.org
  7. filters:
  8. - AddRequestHeader=X-Request-Foo, Bar

基于AddRequestParameterGatewayFilterFactory,为原始请求添加请求参数及值,  

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_parameter_route
  6. uri: https://example.org
  7. filters:
  8. - AddRequestParameter=foo, bar

 基于PrefixPathGatewayFilterFactory,为原始的请求路径添加一个前缀路径 

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: prefixpath_route
  6. uri: https://example.org
  7. filters:
  8. - PrefixPath=/mypath

 基于RequestSizeGatewayFilterFactory,设置允许接收最大请求包的大小 

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: request_size_route
  6. uri: http://localhost:8080/upload
  7. predicates:
  8. - Path=/upload
  9. filters:
  10. - name: RequestSize
  11. args:
  12. # 单位为字节
  13. maxSize: 5000000

 全局过滤器设计及实现 

 设置访问的黑白名单:

  1. package com.jt.config;
  2. import com.google.gson.Gson;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  5. import org.springframework.cloud.gateway.filter.GlobalFilter;
  6. import org.springframework.core.Ordered;
  7. import org.springframework.core.io.buffer.DataBuffer;
  8. import org.springframework.http.server.reactive.ServerHttpRequest;
  9. import org.springframework.http.server.reactive.ServerHttpResponse;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.server.ServerWebExchange;
  12. import reactor.core.publisher.Mono;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. /**
  16. * 自定义的全局过滤器,作用域所有路由
  17. */
  18. @Component
  19. public class AuthGatewayFilter implements GlobalFilter, Ordered {
  20. @Value("${white.prefix}")
  21. private String whitePrefix;
  22. /**你的业务可以写到这个filter方法内部
  23. * @param exchange 基于此对象可以获取请求和响应对象
  24. * @param chain 这个对象指向了一个过滤链(这个链中有多个过滤器)
  25. * */
  26. @Override
  27. public Mono<Void> filter(ServerWebExchange exchange,
  28. GatewayFilterChain chain) {
  29. //1.获取请求对象
  30. ServerHttpRequest request = exchange.getRequest();
  31. //2.获取请求数据
  32. String path = request.getURI().getPath();
  33. System.out.println("path="+path);
  34. //String username=request.getQueryParams().getFirst("username");
  35. //3.对请求数据进行处理
  36. //例如判定请求的path是否在我们允许的范围之内
  37. System.out.println("whitePrefix="+whitePrefix);
  38. if(!path.startsWith(whitePrefix)) {//判断路径的前缀
  39. //获取响应对象
  40. ServerHttpResponse response = exchange.getResponse();
  41. //设置响应状态码,这里的值为502
  42. //response.setStatusCode(HttpStatus.BAD_GATEWAY);
  43. //结束当前请求
  44. //return response.setComplete();//直接结束
  45. //假如希望响应一些具体内容到客户端
  46. //String content="request failure";
  47. //byte[] bytes=content.getBytes();
  48. Map<String,Object> map=new HashMap<>();
  49. map.put("message","request failure");
  50. map.put("status",502);
  51. //将map对象转换为json字符串?
  52. //String jsonStr="{\"message\":\"request failure\",\"status\":502}";
  53. Gson gson=new Gson();
  54. String jsonStr=gson.toJson(map);//将map对象转换json格式字符串.
  55. byte[] bytes=jsonStr.getBytes();
  56. DataBuffer dataBuffer=
  57. response.bufferFactory().wrap(bytes);
  58. return response.writeWith(Mono.just(dataBuffer));
  59. //Spring WebFlux,Mono是一个可以封装0个或1个元素的序列对象.
  60. }
  61. //4.返回响应结果
  62. return chain.filter(exchange);//将请求交给下一个过滤器进行处理
  63. }
  64. @Override
  65. public int getOrder() {
  66. return Ordered.HIGHEST_PRECEDENCE;
  67. }
  68. }

5.限流设计及实现

网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们采用Sentinel组件来实现网关的限流。Sentinel支持对SpringCloud Gateway、Zuul等主流网关进行限流。参考网址如下:

https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel 

启动网关项目,检测sentinel控制台的网关菜单。
启动时,添加sentinel的jvm参数,通过此菜单可以让网关服务在sentinel控制台显示不一样的菜单,代码如下。

-Dcsp.sentinel.app.type=1  

在这里插入图片描述         基于请求属性限流

基于请求属性限流

在这里插入图片描述

        自定义API维度限流(重点)

新建api分组

在这里插入图片描述 

新建分组流控规则,如图所示:

在这里插入图片描述

定制流控网关返回值

  1. package com.jt.config;
  2. import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
  3. import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
  4. import com.alibaba.fastjson.JSON;
  5. import com.google.gson.Gson;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.http.server.reactive.ServerHttpResponse;
  8. import org.springframework.web.reactive.function.server.ServerResponse;
  9. import org.springframework.web.server.ServerWebExchange;
  10. import reactor.core.publisher.Mono;
  11. import java.util.HashMap;
  12. import java.util.Map;
  13. @Configuration
  14. public class GatewayConfig {
  15. public GatewayConfig(){
  16. GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
  17. @Override
  18. public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
  19. ServerHttpResponse response = serverWebExchange.getResponse();
  20. Map<String,Object> map=new HashMap<>();
  21. map.put("state",429);
  22. map.put("message","two many request");
  23. //String jsonStr= JSON.toJSONString(map);
  24. Gson gson = new Gson();
  25. String s = gson.toJson(map);
  26. return ServerResponse.ok().body(Mono.just(s), String.class);
  27. }
  28. });
  29. }
  30. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/301967
推荐阅读
相关标签