赞
踩
目录
传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。那有了网关之后,能够起到怎样的改善呢?
网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务,所以,使用网关的好处在于:
(1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;
(2)降低函数间的耦合度。 一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性
(3)解放开发人员把精力专注于业务逻辑的实现。由网关统一实现服务路由(灰度与ABTest)、负载均衡、访问控制、流控熔断降级等非业务相关功能,而不需要每个服务 API 实现时都去考虑。
Gateway 本身是一个 Spring Boot 应用,它处理请求是逻辑是根据配置的路由对请求进行预处理和转发。
Gateway 有几个比较核心的概念:
- Route:一个 Route 由路由 ID,转发 URI,多个 Predicates 以及多个 Filters 构成。Gateway 上可以配置多个 Routes。处理请求时会按优先级排序,找到第一个满足所有 Predicates 的 Route;
- Predicate:表示路由的匹配条件,可以用来匹配请求的各种属性,如请求路径、方法、header 等。一个 Route 可以包含多个子 Predicates,多个子 Predicates 最终会合并成一个;
- Filter:过滤器包括了处理请求和响应的逻辑,可以分为 pre 和 post 两个阶段。多个 Filter 在 pre 阶段会按优先级高到低顺序执行,post 阶段则是反向执行。Gateway 包括两类 Filter。
- 全局 Filter:每种全局 Filter 全局只会有一个实例,会对所有的 Route 都生效。
- 路由 Filter:路由 Filter 是针对 Route 进行配置的,不同的 Route 可以使用不同的参数,因此会创建不同的实例。
1、创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖。
- <!--网关依赖-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
- <! --nacos服务发现依赖-->
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
2、编写路由配置即nacos地址
- server:
- port: 8089 # 网关端口
- spring:
- application:
- name: gateway # 服务名称
- cloud:
- nacos:
- server-addr: localhost:8848 # nacos地址
- gateway:
- routes: # 网关路由配置
- - id: user-service # 路由id,自定义,只要唯一即可
- # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
- uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
- predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
我们将符合 path 规则的一切请求,都代理到 uri 参数指定的地址。
本例中,我们将 /user/**
开头的请求,代理到lb://userservice
,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。
路由配置包括:
路由id:路由的唯一标示
路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
路由断言(predicates):判断路由的规则,
路由过滤器(filters):对请求或响应做处理
Spring提供了11种基本的Predicate工厂:
PredicateFactory的作用:
Path=/user/**是什么含义?
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:
Spring提供了31种不同的路由过滤器工厂。例如:
下面我们以AddRequestHeader 为例来讲解。
需求:给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!
只需要修改gateway服务的application.yml文件,添加路由过滤即可:
- spring:
- cloud:
- gateway:
- routes:
- - id: user-service
- uri: lb://userservice
- predicates:
- - Path=/user/**
- filters: # 过滤器
- - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
当前过滤器写在userservice路由下,因此仅仅对访问UserService的请求有效。
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:
- spring:
- cloud:
- gateway:
- routes:
- - id: user-service
- uri: lb://userservice
- predicates:
- - Path=/user/**
- default-filters: # 默认过滤项
- - AddRequestHeader=Truth, Itcast is freaking awesome!
过滤器的作用
① 对路由的请求或响应做加工处理,比如添加请求头
② 配置在路由下的过滤器只对当前路由的请求生效
需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:
参数中是否有authorization,
authorization参数值是否为admin
如果同时满足则放行,否则拦截
在gateway中定义一个过滤器:
- import org.springframework.cloud.gateway.filter.GatewayFilterChain;
- import org.springframework.cloud.gateway.filter.GlobalFilter;
- import org.springframework.core.annotation.Order;
- import org.springframework.http.HttpStatus;
- import org.springframework.stereotype.Component;
- import org.springframework.web.server.ServerWebExchange;
- import reactor.core.publisher.Mono;
-
- @Order(-1)
- @Component
- public class AuthorizeFilter implements GlobalFilter {
- @Override
- public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
- // 1.获取请求参数
- MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
- // 2.获取authorization参数
- String auth = params.getFirst("authorization");
- // 3.校验
- if ("admin".equals(auth)) {
- // 放行
- return chain.filter(exchange);
- }
- // 4.拦截
- // 4.1.禁止访问,设置状态码
- exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
- // 4.2.结束处理
- return exchange.getResponse().setComplete();
- }
- }
全局过滤器的作用:对所有路由都生效,并且可以自定义处理逻辑
请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。