getway
网关作用–无网关
网关作用–有网关
网关作用–鉴权认证
网关应用–灰度发布
蓝绿发布
A/B Test
金丝雀发布/灰度发布
网关技术选型
openResty
zuul
gateway
gateway实战
gateway maven配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.muse</groupId>
<artifactId>gateway-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway-sample</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.0</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
yml配置文件
server:
port: 8088
spring:
cloud:
gateway:
routes:
- id: path_routeHeaderRoutePredicateFactory
uri: http://localhost:8080 #访问地址
predicates:
- Path=/gateway/** #路径匹配
filters:
- StripPrefix=1 #StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。如果我们设置StripPrefix=2时,当通过网关向/gateway/bar/foo发出请求时,对nameservice的请求将类似于/foo。
gateway架构原理
Predicate
before 匹配日期之前可以访问
#【指定时间规则匹配路由】
#在2023-01-01 00:00:00之前访问的请求,都会转到http://localhost:8080,即:http://localhost:8088/say会转发到http://localhost:8080/say
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://localhost:8080
predicates:
- Before=2025-01-01T00:00:00.000+08:00
after 匹配日期之后可以访问
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://localhost:8080
predicates:
- After=2021-01-01T00:00:00.000+08:00
cookie 必须含有指定cookie才能访问
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://localhost:8080
predicates:
- Cookie=chocolate, mic
header 需要包含头部信息才能访问
#【指定Header规则匹配路由】
#请求配置Header(key=X-Request-Id value=1) 请求http://localhost:8088/say会转发到http://localhost:8080/say
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://localhost:8080
predicates:
- Header=X-Request-Id, \d+
host指定的Host才能访问
#【指定Host规则匹配路由】
#请求配置Header(Host:www.muse.com) 请求http://localhost:8088/say会转发到http://localhost:8080/say
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://localhost:8080
predicates:
- Host=**.muse.com
method对应的请求方式才能访问
#【请求方法匹配路由】
# 请求POST http://localhost:8088/shout会转发http://localhost:8080/shout。请求GET http://localhost:8088/say 会报"404 Not Found"
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://localhost:8080 #访问地址
predicates:
- Method=POST
path 对应的path才能转发
spring:
cloud:
gateway:
routes:
- id: path_routeHeaderRoutePredicateFactory
uri: http://localhost:8080 #访问地址
predicates:
- Path=/gateway/** #路径匹配
filters:
- StripPrefix=1 #StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。如果我们设置StripPrefix=2时,当通过网关向/gateway/bar/foo发出请求时,对nameservice的请求将类似于/foo。
filter的类型和实现方式
routeFilterFactory实战
parameter 给匹配到的请求添加parameter
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://localhost:8080 #访问地址
predicates:
- Path=/**
filters:
- AddRequestParameter=teacher, muse
header往header添加信息
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: http://localhost:8080 #访问地址
predicates:
- Path=/**
filters:
- AddResponseHeader=X-Response-Teacher, Muse
rate-limit限流
#【添加限流过滤器】
spring:
cloud:
gateway:
routes:
- id: request_ratelimiter_route
uri: http://localhost:8080 #访问地址
predicates:
- Path=/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #令牌桶中令牌的填充速度,代表允许每秒执行的请求数
redis-rate-limiter.burstCapacity: 1 #令牌桶的容量,也就是令牌桶最多能够容纳的令牌数。表示每秒用户最大能够执行的请求数量
redis:
host: 127.0.0.1
port: 6379
retry 发生错误重试
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: http://localhost:8080
predicates:
- Path=/example/**
filters:
- name: Retry
args:
retries: 3 #请求重试次数,默认值是3
status: 500 #HTTP请求返回的状态码,针对指定状态码进行重试。
- StripPrefix=1
management
#【网关指标过滤器——GatewayMetricsFilter】
management:
endpoint:
gateway:
enabled: true
endpoints:
web:
exposure:
include: "*"
可以访问localhost:8088/actuator/metrics/gateway.requests查看请求信息
localhost:8088/actuator/metrics为所有配置项
自定义filter
#【请求路径匹配路由——配置自定义过滤器】
spring:
cloud:
gateway:
routes:
- id: define_filter
uri: http://localhost:8080 #访问地址
predicates:
- Path=/gateway/** #路径匹配
filters:
- name: GpDefine #自定义过滤器的名字,即:GpDefineGatewayFilterFactory
args:
name: Gp_Mic #GpConfig.getName这个值
- StripPrefix=1 #跳过前缀
gateway集成sentinel
关键代码
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolvers.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
// 注入一个全局限流过滤器SentinelGatewayFilter
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
// 注入限流异常处理器
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
// 初始化限流规则
@PostConstruct
public void doInit() {
initGatewayRules();
}
/** Route维度限流 */
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("gateway-nacos-provider").setCount(1).setIntervalSec(1);
rules.add(gatewayFlowRule);
GatewayRuleManager.loadRules(rules);
}
}