zuul1 low, zuul2 还没长大呢,不敢用。
gateway 基于netty, spring flux, reactor 异步非阻塞, 快呀。
与spring良好整合, spring社区的呢。官方推荐。
https://spring.io/projects/spring-cloud-gateway
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
特性
Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架.
1. 基于spring5.0 reactor, boot2.x
2. 能够转发所有请求的路由 反向代理
3. 路由支持断言和过滤器
4. 熔断
5. 服务发现 客户端
6. 简单断言和过滤器
7. 能限制请求
8. 根据路径转发
日志监控.. 流量控制.. 鉴权..
网关在微服务的哪个地方, nginx后面就是。
网关的三大核心对象
路由Route
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
route --> 根据规则将请求转发到对应的微服务。
断言Predicate
参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
可以设置对应的规则来设置断言。符合规则转发请求, 不符合可以做出对应处理。
过滤 filter
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
java web 中的过滤器, 过滤器链, 懂吧。
入门配置
pom
<!--新增gateway 需要排除web和actuator 2.2.1.RELEASE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
routes 下面可以配置多个路由路径。‘
使用yaml配置路由
# gateway --> 路由 断言 过滤器
server:
port: 9527
# 网关配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心获取动态路由的功能。利用微服务名进行路由。
routes:
- id: payment_routh1 # 路由的id 没有固定规则但是要求唯一 配合服务名称
# uri: http://localhost:8001 # 匹配后提供服务的路由地址
uri: lb://cloud-payment-service # 根据服务名进行路由
predicates:
- Path=/payment/get/** # 路径像匹配的进行断言~
使用bean的方式配置路由
package top.bitqian.springcloud.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 网关规则bean配置
* @author echo lovely
* @date 2020/12/12 16:53
*/
@Configuration
public class GatewayConfig {
// 可以配置多个bean, 根据规则跳转到不同的url
@Bean
public RouteLocator customerRouteLocator(RouteLocatorBuilder routeBuilder) {
RouteLocatorBuilder.Builder routes = routeBuilder.routes();
routes.route("adorable1",
r -> r.path("/team"). // localhost:9527/team
uri("https://github.com/team")). // to team
build();
return routes.build();
}
@Bean
public RouteLocator customerRouteLocator1(RouteLocatorBuilder routeBuilder) {
RouteLocatorBuilder.Builder routes = routeBuilder.routes();
routes.route("adorable2",
r -> r.path("/explore"). // localhost:9527/explore
uri("https://github.com/explore")). // to explore
build();
return routes.build();
}
}
断言配置
支持cookie, 请求头, 请求方法,请求参数, 请求时间…
可以本地使用curl来测试, 像linux curl localhost:8080
# gateway --> 路由 断言 过滤器
server:
port: 9527
# 网关配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心获取动态路由的功能。利用微服务名进行路由。
routes:
- id: payment_routh1 # 路由的id 没有固定规则但是要求唯一 配合服务名称
# uri: http://localhost:8001 # 匹配后提供服务的路由地址
uri: lb://cloud-payment-service # 根据服务名进行路由
predicates:
- Path=/payment/get/** # 路径像匹配的进行断言~
- id: payment_routh2 # 路由的id 没有固定规则但是要求唯一 配合服务名称
# uri: http://localhost:8001 # 匹配后提供服务的路由地址
uri: lb://cloud-payment-service
predicates:
- Path=/payment/lb/** # 路径像匹配的进行断言~
# 新增断言配置
# https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories
- After=2020-12-13T11:37:03.340+08:00[Asia/Shanghai] # 必须在这个时间之后
# - Cookie=username, adorable # 测试 curl --cookie "username=adorable" localhost:9527/payment/lb
# - Header=X-Request-Id, \d+ # 属性必须是整数 curl --header "X-Request-Id:99" localhost:9527/payment/lb
# - Query=age # curl localhost:9527/payment/lb?age=19
# - Host=**.adorable.cn,**.adorable.top # curl localhost:9527/payment/lb -H "host:bitqian.lovely.adorable.top"
# gateway 入驻eureka~
eureka:
instance:
hostname: cloud-gateway-service
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
支持自定义过滤器
package top.bitqian.springcloud.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
/**
* 网关自定义过滤器配置
* 官方有两种过滤器, 单一的和全局的。
* @author echo lovely
* @date 2020/12/13 14:37
*/
@Component
@Slf4j
public class MyGatewayFilter implements GlobalFilter, Ordered {
// global filter...
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("=======================gateway进来了======" + new Date());
// 获取到请求中的参数
String username = exchange.getRequest().getQueryParams().getFirst("username");
if (username == null) {
log.info("/(ㄒoㄒ)/~~ 用户名为空了,非法的用户名称......");
// 406 不被服务器接受的
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
// 返回mono
return exchange.getResponse().setComplete();
}
// 放行
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 数字越小, 越优先
return 0;
}
}
总之网关作为分布式,微服务架构 在安全,限流,日志记录方面具有强大的功能。