目录
1.网关介绍
1.1含有问题
当前所有微服务的接口都是直接对外暴露的,可以直接通过外部访问,为了保证对外服务的安全性,服务端实现的微服务接口通常都带有一定的权限校验机制,由于使用了微服务,原本一个应用的多个模块拆分成了多个应用,我们不得不实现多次校验逻辑,当这套逻辑需要修改时,我们需要修改多个应用,加重开发人员的负担
针对以上问题,一个常用的解决方案是API网关
比如企业管理
外部人员去公司办理业务,公司需要先核实对方的身份再去进行办理. 最开始只有一个员工,这个员工核实之后直接办理即可.(单体架构)随着公司的发展,划分了多个部门,每个部门负责的事情不同,每个部门都需要先核实对方的身份再进行办理.(微服务架构)
这个流程存在一些问题:
1.办事效率低
2.增加了员工的工作流程
我们对此进行改进,设立前台,统一由前台来进行身份的校验,前台身份校验通过后,其他部门就设置信任,直接办理.
1.2什么是API网关
API网关(简称网关)也是一个服务,通常是后端服务的唯一入口.
它的定义类似设计模式中的Facade模式 (门面模式,也称外观模式).它就类似整个微服务架构的门面,所有的外部客户端访问,都需要经过它来进行调度和过滤.
网关核心功能:
权限控制:作为微服务的入口,对用户进行权限校验,如果校验失败则进行拦截
动态路由:一切请求先经过网关,网关不处理业务,而是根据某种规则,把请求转发到某个微服务
负载均衡:当路由的目标服务有多个时,还需要做负载均衡
限流:请求流量过高时,按照网关中配置微服务能够接受的流量进行放行,避免服务压力过大.
2.Spring Cloud Gateway
2.1什么是Spring Cloud Gateway
Spring Cloud Gateway是Spring Cloud的一个全新的API网关项目,基于Spring+SpringBoot等技术 开发,目的是为了替换掉Zuul.旨在为微服务架构提供一种简单而有效的途径来转发请求,并为他们提供横切关注点,比如:安全性,监控/指标和弹性.
在性能方面,根据官方提供的测试报告,SpringCloud Gateway的RPS(每秒请求数)是Zuul的1.6倍.
2.2快速上手
2.2.1创建网关项目
2.2.2引入网关依赖
<!--⽹关-->
<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>
<!--负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2.2.3添加Gateway的路由配置
创建application.yml文件,添加如下配置:
server:
port: 10030
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020
gateway:
metrics:
enabled: true
routes:
- id: order-service #路由规则id, 随便起, 不重复即可
uri: lb://product-service/ #目标服务地址
predicates: #路由条件
- Path=/order/**,/feign/**,/product/**
- After=2024-03-20T00:00:22.370856700+08:00[Asia/Shanghai]
配置字段说明:
- id:自定义路由ID,保持唯一
- uri:目标服务地址,支持普通URI及lb://应用注册服务名称.lb表示负载均衡,使用lb://方式表示从注册中心获取服务地址.
- predicates:路由条件,根据匹配结果决定是否执行该请求路由,上述代码中,我们把符合Path规则的一切请求,都代理到uri参数指定的地址.
2.2.4测试
启动API网关服务
1.通过网关服务访问product-service
url符合yml文件中配置的/product/**规则,
路由转发到product-service:http://product-service/product/1001
访问时,观察网关日志,可以看到网关服务从Nacos时获取服务列表
2.3Predicate
Predicate是Java 8提供的一个函数式编程接口,它回收一个参数并返回一个布尔值,用于条件过滤,请求参数的校验
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
//...
}
代码演示:
1.定义一个Predicate
class StringPredicate implements Predicate<String>{
@Override
public boolean test(String str) {
return str.isEmpty();
}
}
2.使用这个Predicate
public class PredictTest {
public static void main(String[] args) {
Predicate<String> predicate = new StringPredicate();
System.out.println(predicate.test(""));//true
System.out.println(predicate.test("666"));//false
}
}
2.3.1Predicate的其他写法
1.内置函数
public class PredictTest {
public static void main(String[] args) {
Predicate<String> predicate = new Predicate<String>(){
@Override
public boolean test(String s) {
return s.isEmpty();
}
};
System.out.println(predicate.test(""));
System.out.println(predicate.test("666"));
}
}
2.lambda写法
public class PredictTest {
public static void main(String[] args) {
Predicate<String> predicate = s -> s.isEmpty();
System.out.println(predicate.test(""));
System.out.println(predicate.test("bite666"));
}
}
Predicate<String>predicate =s ->s.isEmpty();
也可以写成 Predicate<String>isEmpty =String::isEmpty;
2.3.2Predicate的其他方法
- isEqual(Object targetRef):比较两个对象是否相等,参数可以为Null
- and(Predicate other):短路与操作,返回一个组成Predicate
- or(Predicate other):短路或操作,返回一个组成Predicate
- test(T t):传入一个Predicate参数,用来做判断
- negate():返回表示此Predicate逻辑否定的Predicate
2.4Route Predicate Factories
Route Predicate Factories(路由断言工厂,也称为路由谓词工厂,此处谓词表示一个函数),在Spring Cloud Gateway中,Predicate提供了路由规则的匹配机制.
我们在配置文件中写的断言规则只是字符串,这些字符串会被Route Predicate Factory读取并处理,转变为路由判断的条件.
比如前面章节配置的Path=/product/**,就是通过Path属性来匹配URL前缀是/product的 请求.
这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory来实现的.
Spring Cloud Gateway默认提供了很多Route Predicate Factory,这些Predicate会分别匹配HTTP请 求的不同属性,并且多个Predicate可以通过and逻辑进行组合.
2.4.1代码演示
1.添加Predicate规则
在application.yml中添加如下规则
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: b460e95c-d4b9-42a3-810f-cdf0051ce008
gateway:
metrics:
enabled: true
routes:
- id: order-service #路由规则id, 随便起, 不重复即可
uri: lb://product-service/ #目标服务地址
predicates: #路由条件
- Path=/product/**
- After=2025-01-01T00:00:00.000+08:00[Asia/Shanghai]
添加限制规则:请求时间为2025年1月1日后
2.测试
访问:http://127.0.0.1:10030/product/1001
3.修改时间为2024-01-01,再次访问
- After=2024-01-01T00:00:00.000+08:00[Asia/Shanghai]