详细介绍:【springCloud】[Gateway]---Spring Cloud Gateway 实战教程:路由配置 + 负载均衡 + 断言过滤器,一篇搞定微服务网关
第一章:概述简介
【官网】
https://spring.io/projects/spring-cloud-gateway
【Gateway是什么 】
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor等技术。Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等
【总结】 能干嘛
底层是基于响应式编程的netty开发的、可以做反向代理、鉴权、流量控制、熔断、日志监控
【总结微服务架构中网关在哪里】
【SpringCloud Gateway与Zuul的区别】
第二章:三个核心
Route(路由)、Predicate(断言)、Filter(过滤)
【总结】:
路由:根据不同请求路径转发到指定服务
断言:校验请求头参数
过滤器:一层层过滤器处理鉴权、日志、限流
第三章:工作流程图
第四章:[路由]实战入门
创建2个项目。注册中心用nacos
project-test 用于编写接口
gataway-test 网关服务
两个项目都要引入 nacos依赖
<
!-- Nacos服务发现 -->
<dependency>
<groupId>com.alibaba.cloud<
/groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery<
/artifactId>
<
/dependency>
1、【接口服务】project-test
控制类
@RestController
public class TestController
{
// 定义一个测试接口
@GetMapping("/test/{message}")
public String test(@PathVariable String message) {
return "来自project-test8080 的响应: " + message;
}
}
配置yml文件
server:
port: 8080 # 服务端口
spring:
application:
name: project-test # 服务名称,网关将通过此名称发现服务
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos注册中心地址
namespace: public # 命名空间,默认为public
group: DEFAULT_GROUP # 服务分组,默认为DEFAULT_GROUP
2、【网关服务】gataway-test
server:
port: 9999 # 网关端口
spring:
application:
name: gateway-service # 网关服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos注册中心地址
namespace: public
group: DEFAULT_GROUP
gateway:
discovery:
locator:
enabled: true # 开启服务发现,允许通过服务名路由
lower-case-service-id: true # 服务名小写处理
routes:
# 配置路由到project-test服务(通过服务名)
- id: project-test-route # 路由唯一标识
uri: lb://project-test # lb表示负载均衡,project-test是服务名称
predicates:
- Path=/api/test/** # 断言:路径匹配规则
filters:
- RewritePath=/api/test/(?<segment>.*), /test/$\{segment} # 路径重写
3、【访问说明】
添加网关前 http://localhost:8080/api/test/hello
添加网关后 http://localhost:9999/api/test/hello
两个都能访问(添加网关的目的是为了不暴露接口地址)
4、【测试】
访问http://localhost:9999/api/test/hello时,网关会通过服务名路由到 project-test
输出:来自project-test 8080 的响应: hello
第五章:集群服务负载均衡
通过微服务名实现动态路由:
上面例子 project-test 启动多个服务,服务名一样,端口不一样
project-test 8080
project-test 8081
project-test 8082
此时:配置为 lb://project-test
lb,表示启用Gateway的负载均衡功能(默认是轮询)
1【测试】
访问5次 http://localhost:9999/api/test/hello时
1输出:来自project-test 8081 的响应: hello
2输出:来自project-test 8082 的响应: hello
3输出:来自project-test 8083 的响应: hello
4输出:来自project-test 8084 的响应: hello
5输出:来自project-test 8085 的响应: hello
第六章:[断言]Predicate
1【断言例子】
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
#- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
#- Cookie=username,zhangshuai #并且Cookie是username=zhangshuai才能访问
#- Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式
#- Host=**.atguigu.com
#- Method=GET
#- Query=username, \d+ #要有参数名称并且是正整数才能路由
2【全部断言规则表】
第七章:[过滤器]Filter
说明:全局过滤器内置了30多个过滤器。
过滤器只有2种,一种是业务执行前,一种是业务执行后。
1【自定义过滤器】
也可以自定义过滤器。需要实现 impiemerts GlobalFilter ,Ordered 这2个接口
案例:这个代码的意思是判断请求参数有没有带有username,没有就直接返回错误,有的话就放行
正确 localhost:9999/test?uname=z3
错误 localhost:9999/test?unamfdf=z3 直接报错。
@Component
@Slf4j
public class MyLogGateWayFilter
implements GlobalFilter,Ordered {
@Override
public Mono<
Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("*********come in MyLogGateWayFilter: "+new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("username");
if(StringUtils.isEmpty(username)){
log.info("*****用户名为Null 非法用户,(┬_┬)");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
//给人家一个回应
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
2【常用的内置过滤器】