微服务网关GateWay
一. 案例
1. 创建 gateway 模块
2. 导入依赖
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
gateway和web依赖存在冲突,所以需要将父模块中的 spring-boot-startet-web 依赖分别添加到需要使用的子模块中,不然启动会出现如下错误
3. 创建 application.yml 文件
server:
port: 7005
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
prefer-ip-address: true
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: integral-server # 自定义路由id,唯一
uri: http://127.0.0.1:8001
predicates: #路由条件,Predicate 接受一个输入参数,返回一个布尔值结果
- Path=/**
4. 创建启动类
package com.ddz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyGatewayServer {
public static void main(String[] args) {
SpringApplication.run(MyGatewayServer.class, args);
}
}
5. 在页面就可以通过 gateway 网关访问了
链接:http://localhost:7005/findOrderByUser?uid=1
二. 动态路由和添加访问路径
1. 添加依赖
<!-- eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 修改 application.yml 中配置
gateway:
routes:
- id: user-server # 自定义路由id,唯一
uri: lb://user-server
predicates: #路由条件,Predicate 接受一个输入参数,返回一个布尔值结果
- Path=/user/** # 访问url
filters: # 访问真实路径
-RewritePath=/user/(?<segment>/?.*), $\{segment}
真实路径替换 /user/(?/?.*), ${segment} 例如: localhost:8080/user/get 转换后 localhost:8080/get
不明白的可以参考博客
3. 在页面访问路径
链接:http://localhost:7005/user/findOrderByUser?uid=1
三. GateWay 过滤器
1. 在 filters 包下 创建 PowerFilter类
校验所有请求的请求头中是否包含“token”
2. 在页面访问
再去访问:http://localhost:7005/user/findOrderByUser?uid=1 就会被拦截
四. GateWay 限流
基于Filter的限流
SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂
RequestRateLimiterGatewayFilterFactory 实现。在过滤器工厂中是通过Redis和lua脚本结合的方式进行流量控制。
1.添加依赖
<!--监控依赖-->
<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>
2. 在 config 包下创建 LimitConfig 类
package com.ddz.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class LimitConfig {
/**
* 按照 Path 访问次数限流
*
* @return key
*/
@Bean
public KeyResolver pathKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest()
.getPath()
.toString()
);
}
// /**
// * 按照 Path 访问次数限流
// */
// @Bean
// public KeyResolver pathKeyResolver() {
// /* 内部类 */
// return new KeyResolver() {
// @Override
// public Mono<String> resolve(ServerWebExchange exchange) {
// System.out.println("---" + exchange.getRequest().getPath().toString());
// return Mono.just(exchange.getRequest().getPath().toString());
// }
// };
// }
// /**
// * 根据IP限流
// */
// @Bean
// public KeyResolver ipKeyResolver() {
// return exchange -> Mono.just(
// exchange.getRequest()
// .getRemoteAddress()
// .getHostName()
// );
// }
/**
* 根据token限流
*/
// @Bean
// public KeyResolver tokenKeyResolver() {
// return new KeyResolver() {
// @Override
// public Mono<String> resolve(ServerWebExchange exchange) {
// return Mono.just(exchange.getRequest().getQueryParams().getFirst("token"));
// }
// };
// }
}
3. 修改 application.yml 文件
filters:
- name: RequestRateLimiter #固定的
args:
key-resolver: '#{@pathKeyResolver}' # 用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: 3 # 令牌桶的总容量
redis:
host: 127.0.0.1
port: 6379
password: ddz123
database: 3
4. 启动 Redis 服务,并进入客户端输入指令开启监控
5. 在页面快速连续的访问
链接:http://localhost:7005/user/findOrderByUser?uid=1&token=1001