网关介绍

分布式架构存在的弊端

  • 每个业务都会需要鉴权,限流、权限校验,跨域等逻辑。如果每个业务都各自为战,自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。
  • 如果业务量比较简单的话,这种方式前端不会有什么问题。但随着业务量越来越复杂,比如淘宝等打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数量的瓶颈。想象一下打开一个APP,通过抓包发现涉及到了数百个微服务远程调用,这在移动端下会显得非常低效
  • 后期如果对微服务进行重构的话,也会变得非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变得越来越复杂,后期需要进行拆分成多个微服务,这个时候对外部提供的服务也需要拆分成多个,同时前端也需要改变

所谓的API网关,就是指系统的统一入口,他分装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权,监控路由转发等。添加上API网关后,系统的架构图变成了如下所示:
GateWay - 图1

Gateway介绍

网关作为流程的日寇,常用的功能包括路由转发,权限校验,限流等。
GateWay:是spring Cloud官方推出的第二代网关框架,提供更优秀的性能,具有更强大的功能。它是由WebFlux+Netty+Reactir实现的响应式API网关,它不能在传统的servlet容器中工作,也不能构建成war包。GateWay旨在为微服务架构提供一种简单并且有限的API路由管理方式,并基于Filter的方式提供网关的基本功能,例如说安全认证、监控、限流等。

核心概念

  • 路由: 路由是网关中最基础的部分,路由的信息包括一个ID,一个目的URI,一个断言工厂,一组Filter组成。如果断言为真,则说明请求的路由和配置的路由匹配
  • 断言: Java8中的断言函数,断言函数类型是spring5框架中的。断言函数允许开发者去定义匹配http/httpss中request的任何信息,比如请求头和参数等
  • Filter: 可以对请求和响应进行处理

工作原理

初体验

添加依赖

  1. <!--添加gateway的依赖-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-gateway</artifactId>
  5. </dependency>

修改yaml文件

  1. server:
  2. port: 8886
  3. spring:
  4. application:
  5. name: api-gateway
  6. cloud:
  7. # 配置相关的gateway配置
  8. # 配置路由规则
  9. gateway:
  10. routes:
  11. - id: order_route #路由的唯一标识,路由到order服务上
  12. uri: http://localhost:8010 #需要转发的地址
  13. #断言规则,用于路由规则匹配
  14. predicates:
  15. - Path=/order-serv/** #需要匹配的路径
  16. filters:
  17. - StripPrefix=1 # 转发之前,去掉第一层的内容

gateway整合nacos

引入nacos注册与发现的依赖

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

配置yaml文件

  1. server:
  2. port: 8886
  3. spring:
  4. application:
  5. name: api-gateway
  6. cloud:
  7. nacos: # 配置nacos发现的相关信息
  8. discovery:
  9. server-addr: 111.229.181.158:8847
  10. username: nacos
  11. password: nacos
  12. # 配置相关的gateway配置
  13. # 配置路由规则
  14. gateway:
  15. routes:
  16. - id: order_route #路由的唯一标识,路由到order服务上
  17. uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略
  18. #断言规则,用于路由规则匹配
  19. predicates:
  20. - Path=/order-serv/** #需要匹配的路径
  21. filters:
  22. - StripPrefix=1 # 转发之前,去掉第一层的内容

使用简写的配置,自动寻找服务器

  1. server:
  2. port: 8886
  3. spring:
  4. application:
  5. name: api-gateway
  6. cloud:
  7. nacos: # 配置nacos发现的相关信息
  8. discovery:
  9. server-addr: 111.229.181.158:8847
  10. username: nacos
  11. password: nacos
  12. # 配置相关的gateway配置
  13. # 配置路由规则
  14. gateway:
  15. discovery:
  16. locator:
  17. enabled: true #自动识别nacos的服务
  18. #routes:
  19. # - id: order_route #路由的唯一标识,路由到order服务上
  20. # uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略
  21. #断言规则,用于路由规则匹配
  22. # predicates:
  23. # - Path=/order-serv/** #需要匹配的路径
  24. # filters:
  25. # - StripPrefix=1 # 转发之前,去掉第一层的内容

内置路由断言工厂

当请求gateway的时候,使用断言对请求进行匹配,如果匹配成功就路由转发,请求失败就返回404

  • 基于DateTime类型的断言工厂

    • AfterRoutePreducateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
    • BeforeRoutePreducateFactory:接收一个日期参数,判断请求日期是否早于指定日期
    • BetweenRoutePreducateFactory:接收两个日期参数,判断请求日期是否在指定的时间段内
    • - After=
  • 基于远程地址的断言工厂
    RemoteAddrRoutePredicateFactory:接收一个IP地址端,判断请求主机地址是否在地址段中 - RemoteAddr=192.168.1.1/24
  • 基于cookie的断言工厂
    CookieRiytePreducateFactory:接收两个参数,cookie名字和一个正则表达式,判断请求
    -Cookie-chocloate, ch.
  • 基于header的断言工厂
    HeaderRiytePreducateFactory
  • 基于Host的断言工厂
  • 基于Method请求方法的断言工厂

自定义路由断言工厂

自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。在apply方法中可以通过exchange.getRequest()拿到ServeltHttpRequest对象,从而可以获取到请求的参数,请求方式、请求头等信息
注意:命名需要以RoutePredicateFactory结尾,并且使用@Component注解加入到组件中

局部(内置、自定义)过滤器

跟自定义的断言工厂形式差不多

全局过滤器

GateWay - 图2
局部过滤器是针对某个路由的,全局过滤器是针对所有路由请求的。
局部过滤器需要在路由中配置,全局路由器一旦定义了就会投入使用
自定义全局过滤器
需要实现GlobalFilter接口,并且注入到spring容器中

请求日志记录&跨域处理

React Netty访问日志需要设置:``
他必须通过Java系统属性,而不是Spring Boot配置的

GateWay的跨域请求

  1. server:
  2. port: 8886
  3. spring:
  4. application:
  5. name: api-gateway
  6. cloud:
  7. nacos: # 配置nacos发现的相关信息
  8. discovery:
  9. server-addr: 111.229.181.158:8847
  10. username: nacos
  11. password: nacos
  12. # 配置相关的gateway配置
  13. # 配置路由规则
  14. gateway:
  15. globalcors:
  16. # discovery:
  17. # locator:
  18. # enabled: true #自动识别nacos的服务
  19. routes:
  20. - id: order_route #路由的唯一标识,路由到order服务上
  21. uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略
  22. #断言规则,用于路由规则匹配
  23. predicates:
  24. - Path=/order-serv/** #需要匹配的路径
  25. filters:
  26. - StripPrefix=1 # 转发之前,去掉第一层的内容
  27. # 配置跨域的信息
  28. cors-configurations:
  29. '[/**]': # 允许跨域访问的资源
  30. allowedOrigins: "*" # 允许跨域的来源
  31. allowedMehtods:
  32. - GET
  33. - POST
  34. - DELETE
  35. - PUT
  36. - OPTION

整合sentinel流控降级

添加依赖

  1. <!--引入sentinel-gateway的依赖-->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
  5. </dependency>
  6. <!--引入sentinel的依赖-->
  7. <dependency>
  8. <groupId>com.alibaba.cloud</groupId>
  9. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  10. </dependency>

添加配置

  1. # 配置dashbaord的控制台
  2. sentinel:
  3. transport:
  4. dashboard: 111.229.181.158:8847

整合sentinel流控降级详细配置