gateway学习记录
目标是替代 Netflix Zuul。
相关概念:
① Route(路由):网关的基本构建模块,一个ID,一个url,一组断言和一组过滤器定义。
② Predicate(断言):由java8 提供的Predicate,输入类型是ServerWebExchange,用来请求HTTP的请求内容。
③ Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。
1、Gateway 的特征:
- 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 动态路由
- Predicates 和 Filters 作用于特定路由
- 集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- 易于编写的 Predicates 和 Filters
- 限流
- 路径重写
2、网关的作用:
-
全局性流量控制
-
日志统计
-
防止SQL注入
-
防止Web攻击
-
疲敝工具扫描
-
黑白IP名单
-
证书加密/解密处理
-
服务级别流量控制
-
服务降级与熔断
-
路由与负载均衡、灰度策略
-
服务过滤、聚合与发现
-
权限验证与用户等级策略
-
业务规则与参数校验
-
多级缓存策略
3、使用Gateway的yml配置
spring:
application:
name: gateway
# 注册中心
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
cloud:
nacos:
server-addr: localhost:8848
gateway:
discovery:
locator:
# 应用名称调用服务
enabled: true
lower-case-service-id: true
# 路由集合
routes:
- id: demo-file #file #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:19022 #匹配后提供服务的路由地址
predicates:
- Path=/file/** # 断言,路径相匹配的进行路由
filters:
- StripPrefix=1 # 在所有file请求路径的前面加上file
4、gateway网关的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-parent</artifactId>-->
<!-- <version>2.2.9.RELEASE</version>-->
<!-- <relativePath/>-->
<!-- </parent>-->
<parent>
<artifactId>demo</artifactId>
<groupId>springCloudDemo</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- redis -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis-reactive</artifactId>-->
<!-- </dependency>-->
<!--注册中心-->
<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-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意:pom文件中的jar包不能重复
5、gateway网关的启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
6、遇到问题
启动后发现,使用postman可以正常转发,但是前段无法转发报错如下
产生了跨域问题
7、解决办法
微服务项目是前后端分离,前后分离后采用了SpringCloud Getway网关技术,这样请求会经历三个流程:
1.前端请求 -----> 2.网关 -----> 3.后端接口
查询得知目前常用的跨域解决方案有三种:
(1) jsonp:
最早的解决方案,利用script标签可以跨域的原理实现
**缺点:**需要服务的支持,
只能发起get请求
(2)nginx反向代理:
思路是利用nginx把跨域反向代理为不跨域,支持各种请求方式
**缺点:**需要nginx进行额外配置,语义不清晰
(3)CORS:
**思路:**规范化的跨域请求方案,安全可靠
**优势:**在服务端进行控制是否允许跨域,靠自定义规则。支持各种请求方式。
**缺点:**会产生额外的请求
我们选择第三种办法。
引入问题:什么是CORS?
w3c的标准,跨域资源共享。一个请求的协议,域名,端口三者任意不同即为跨域。
写一个配置文件
@Configuration
public class GatewayConfig {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1、配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
我使用的SpringCloud版本是H版,SpringBoot是2.2.9