微服务组件 -- 网关

微服务组件:网关服务

一、网关

1、为什么需要网关

我们已经了解了微服务的各个基础组件,这些组件已经可以构建一个简单的微服务模型:

微服务架构模型

注册中心:Eurekaconsul,用于将各个微服务的信息注册,为了让其他的微服务知道这些信息。方便调用

服务调用:声明式调用组件OpenFeign,为了解决服务的集群调用,需要引入负载均衡组件Ribbon

容错保护:在服务运行时,可能会出现雪崩,服务器宕机等。为了使服务系统更加健壮,需要引入容错保护组件Hxstrix,实现线程隔离和熔断机制。

上面的系统架构设计并没有问题,但是在开发和维护时难度会更大。

  1. 客户端发出请求,前端会根据这些请求发送给后端。因此前端需要维护大量的服务请求地址。

  2. 为了保证服务的对外安全性,我们都会添加权限校验机制,大规模的微服务会使校验逻辑变得复杂。

为了解决这些常见的架构问题,API网关的概念应运而生。

2、网关的概念

网关统一服务入口,可方便实现对平台众多服务接口进行管控。

1
2
3
# 网关 =  路由转发 + 过滤器
路由转发:接收一切外界请求,转发到后端的微服务上去;
在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成

网关的定义类似于面向对象设计模式中的门面模式,它就像是整个微服务系统对客户端的门面。

1
2
3
# 门面模式(Facade)
也叫外观模式,通过定义一个一致的接口,用于屏蔽内部子系统的细节。
使得调用方只需跟这个接口发生调用,而无需关心内部细节。

二、GateWay实例

1、路由转发的实现

两个服务,商品服务和用户服务。

1
2
user       端口号  8881
product 端口号 8882
1
2
3
4
5
<!--引入gateway网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

编写配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
application:
name: gateway
cloud:
consul:
host: localhost
port: 8500
gateway:
routes:
- id: user_route # 指定路由唯一标识
uri: http://localhost:8881/ # 指定路由服务的地址
predicates:
- Path=/user/** # 指定路由规则

- id: product_route
uri: http://localhost:8882/
predicates:
- Path=/product/**
server:
port: 8880

访问http://localhost:8880/user/findOne?id=8

实现路由转发

这就是服务的路由转发。

2、集群服务的负载均衡

将用户服务复制一份

1
user 端口号 7999 8881   用户服务
1
2
3
4
5
6
7
8
9
@GetMapping("/user/findAllByFeign")
public Map<String, Object> findAll() throws InterruptedException {
log.info("通过使用OpenFeign组件调用服务");
//Map<String,Object> map = productClient.findAll();
Map<String,Object> map = new HashMap<>();
map.put("当前服务的端口号",port);
log.info("当前端口号是:" + port);
return map;
}

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
application:
name: getway
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
gateway:
routes:
- id: user_route # 指定路由唯一标识
uri: lb://user # 指定路由服务的地址
predicates:
- Path=/user/** # 指定路由规则


- id: product_route
uri: lb://product
predicates:
- Path=/product/**

server:
port: 8880

访问http://localhost:8880/user/findAllByFeign,会按照负载均衡算法来分配请求到哪个服务,默认的负载均衡算法是轮询。

端口号-7999

端口号-8881

三、过滤器

前面说过,网关有两个作用,路由转发和过滤器。

网关中的过滤器有什么用:权限校验、限流以及监控

https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/

1、使用predicate

1.1、服务上线时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
application:
name: getway
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
gateway:
routes:
- id: user_route # 指定路由唯一标识
uri: lb://user # 指定路由服务的地址
predicates:
- Path=/user/** # 指定路由规则
- After=2021-07-15T11:33:33.993+08:00[Asia/Shanghai] # 在这个时间之后服务上线

- id: product_route
uri: lb://product
predicates:
- Path=/product/**

server:
port: 8880

同样,也有服务下线的时间

1
2
3
- Before=2020-07-21T11:33:33.993+08:00[Asia/Shanghai]

- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
1.2、请求头
1
2
3
4
# 设置请求头  只有请求带有这个请求头,才能访问
predicates:
- Path=/user/** # 指定路由规则
- Header=head_Id,666

我们通过Postman来做试验,没有加请求头:

没有添加请求头

我们添加一个请求头:

添加请求头

1.3、添加cookie
1
2
3
4
predicates:
- Path=/user/** # 指定路由规则
- Header=head_Id,666
- Cookie=username,jiang

添加cookie

1.5、设置请求方法
1
2
3
4
5
predicates:
- Path=/user/** # 指定路由规则
- Header=head_Id,666
- Cookie=username,jiang
- Method=POST

设置请求方法

2、自定义过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

log.info("进入过滤器");
log.info("查看请求是否带有id参数");
List<String> list = exchange.getRequest().getQueryParams().get("id");
if(list != null){
log.info("带有参数,可以访问");
return chain.filter(exchange);
}

log.info("请求参数中 没有 id 拒绝访问");
return exchange.getResponse().setComplete();
}

@Override
public int getOrder() { //filter 数字越小filter越先执行
return -1; //-1 最先执行
}
}

请求中添加参数

添加参数

可以访问

image-20210715184338184


微服务组件 -- 网关
https://johnjoyjzw.github.io/2021/07/15/微服务组件-网关/
Author
John Joy
Posted on
July 15, 2021
Licensed under