网关介绍
服务网关搭建
1). pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2). application.yml
spring:
application:
name: sysgateway # 应用在eureka中注册的名称
cloud:
gateway:
routes:
- id: goods # 路由的名称
uri: lb://goods # 负载均衡 LoadBalance 加载的负载均衡,
predicates:
- Path=/goods/** # 拦截路径
filters:
- StripPrefix= 1 # 路由后去除第一个前缀
- id: system
uri: lb://system
predicates:
- Path=/system/**
filters:
- StripPrefix= 1
server:
port: 9101 # 服务端口号
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka # 注册为eureka的客户端
instance:
prefer-ip-address: true # 使用ip地址进行服务的注册
3). 引导类
@SpringBootApplication
@EnableEurekaClient
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class,args);
}
}
2.3 服务网关中跨域的解决
spring:
application:
name: sysgateway # 应用在eureka中注册的名称
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]': # 匹配所有的请求
allowedOrigins: "*" # 跨域处理,允许所有的域进行跨域
allowedMethods: # 允许支持跨域的方法
- GET
- POST
- PUT
- DELETE
2.4 网关自定义过滤器
如何来自定义网关过滤器?
定义一个过滤器 , 实现两个接口: GlobalFilter , Ordered
通过网关访问资源的时候,在网关内定义全局过滤器,所有的请求都会经过过滤器
自定义过滤器 :
@Component
public class IpFilter implements GlobalFilter, Ordered {
//具体业务逻辑
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取客户端的访问ip
System.out.println("经过了第一个过滤器");
ServerHttpRequest request = exchange.getRequest();
InetSocketAddress remoteAddress = request.getRemoteAddress();
System.out.println("ip:"+remoteAddress.getHostName());
//放行
return chain.filter(exchange);
}
//过滤器的执行优先级,返回值越小,执行优先级越高
@Override
public int getOrder() {
return 1;
}
}
2.5 网关限流
2.5.1 限流
1). 什么是限流
限制流量 ;
2). 为什么要限流
为了保证后端微服务的安全 ;
2.5.2 令牌桶算法
Guava , Redis
2.5.3 网关限流
在SpringCloud Gateway 中默认已经集成了Redis , 来实现网关限流 , 操作步骤如下 :
1). pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
2). 配置一个bean
在引导类中声明bean , KeyResolver ; 指定redis中的key (基于什么来限流) ;
@Bean
public KeyResolver ipKeyResolver(){
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
//基于IP地址来实现限流 ; 每一个IP, 每一秒, 只能请求多少次 ;
return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
};
}
3). application.yml
spring:
application:
name: sysgateway # 应用在eureka中注册的名称
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]': # 匹配所有的请求
allowedOrigins: "*" # 跨域处理,允许所有的域进行跨域
allowedMethods: # 允许支持跨域的方法
- GET
- POST
- PUT
- DELETE
routes:
- id: goods # 路由的名称
uri: lb://goods # 负载均衡 LoadBalance 加载的负载均衡,
predicates:
- Path=/goods/** # 拦截路径 所有/goods/开头的请求路由到goods微服务中
filters:
- StripPrefix= 1 # 路由后去除第一个前缀
- name: RequestRateLimiter #请求数限流 名字不能随便写
args:
key-resolver: "#{@ipKeyResolver}" # 通过ip进行限流
redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: 1 #令牌桶总容量
- id: system
uri: lb://system
predicates:
- Path=/system/**
filters:
- StripPrefix= 1
redis:
host: 192.168.200.128
port: 6379