SpringCloud-Gateway搭建保姆级教程
一、网关介绍
1、什么是网关?
使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤

2、⽹关可以⼲什么?
路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问过滤:对⽤户请求进⾏拦截、过滤(⽤户鉴权)、监控限流:限制⽤户的访问流量
3、常⽤的⽹关
NginxSpring Cloud Netflix zuulSpring Cloud Gateway
二、使⽤Nginx实现⽹关服务
Nginx通常被⽤作应⽤服务器⽹关,服务⽹关通常使⽤zuul或者gateway

三、使用Zuul实现网关服务
四、使用Gateway实现网关服务

1、搭建gateway服务器
创建SpringBoot应⽤,添加gateway依赖
2、配置路由规则
application.ymlserver:
port: 9999
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
# 配置api-service1路由规则
- id: api-service1
uri: 'http://localhost:8001'
predicates:
- Path=/product/**
# 配置api-service2路由规则
- id: api-service2
uri: 'http://localhost:8002'
predicates:
- Path=/order/**
五、Gateway⼯作原理
1、名词解释
Route: 路由是⽹关的基本组成部分,它是由id、⽬标uri、断⾔组成,如果断⾔为true,则匹配该路由,转向到当前路由的URIPredicate:断⾔,⽤户请求的匹配规则Filter:过滤器,⽤于对请求进⾏前置、后置处理(可以在⽹关实现对请求或相应的加⼯处理)
2、Gateway⼯作流程图

六、Predicate断⾔
SpringCloud Gateway提供了多种断⾔匹配的⽅式:
- After
- Before
- Between
- Cookie
- Header
- Host
- Method
- Path
- Query
- RemoteAddr
- Weight
1、Path
根据请求路径的正则匹配
spring:
application: null
name: gateway-server
cloud: null
gateway: null
routes:
- id: aaa
uri: 'http://localhost:8001'
predicates:
- Path=/product/**
- id: bbb
uri: 'http://localhost:8002'
predicates:
- Path=/order/**
2、Query
根据请求携带的参数匹配路由
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: aaa
uri: 'http://localhost:8001'
predicates:
# 如果请求url中带有name参数 ---> http://localhost:8001
- Query=name
- id: bbb
uri: 'http://localhost:8002'
predicates:
#如果请求url中带有pwd参数 ---> http://localhost:8002
- Query=pwd
3、Header
根据Header中携带的参数匹配
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: aaa
uri: 'http://localhost:8001'
predicates:
- Header=token
- id: bbb
uri: 'http://localhost:8002'
predicates:
- 'Header=aa,haha'
七、过滤器
1、Gateway内置⽹关过滤器
gateway⽹关可以对⽤户的请求和响应进⾏处理,gateway提供了多个内置的过滤器,不同的过滤器可以完成不同的请求或者响应的处理1. AddRequestHeader 在请求头中添加参数2. AddRequestParameter 添加请求参数3. AddResponseHeader4. The DedupeResponseHeader GatewayFilter Factory5. The Hystrix GatewayFilter Factory6. Spring Cloud CircuitBreaker GatewayFilter Factory7. The FallbackHeaders GatewayFilter Factory8. The MapRequestHeader GatewayFilter Factory9. The PrefixPath GatewayFilter Factory10. The PreserveHostHeader GatewayFilter Factory11. The RequestRateLimiter GatewayFilter Factory12. The RedirectTo GatewayFilter Factory13. The RemoveRequestHeader GatewayFilter Factory14. RemoveResponseHeader GatewayFilter Factory15. The RemoveRequestParameter GatewayFilter Factory16. The RewritePath GatewayFilter Factory17. RewriteLocationResponseHeader GatewayFilter Factory18. The RewriteResponseHeader GatewayFilter Factory19. The SaveSession GatewayFilter Factory20. The SecureHeaders GatewayFilter Factory21. The SetPath GatewayFilter Factory22. The SetRequestHeader GatewayFilter Factory23. The SetResponseHeader GatewayFilter Factory24. The SetStatus GatewayFilter Factory25. The StripPrefix GatewayFilter Factory26. The Retry GatewayFilter Factory27. The RequestSize GatewayFilter Factory28. The SetRequestHostHeader GatewayFilter Factory29. Modify a Request Body GatewayFilter Factory30. Modify a Response Body GatewayFilter Factory31. Default Filters
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: aaa
uri: 'http://localhost:8001'
predicates:
- Path=/red/aaa/product/**
filters:
- 'AddRequestHeader=token,wahahaawahaha'
- 'AddRequestParameter=username, ergou'
- SetStatus=404
- StripPrefix=2
2、⾃定义服务过滤器
2.1、创建⽹关过滤器 - 实现GatewayFilter
1、实现GatewayFilter, Ordered
public class MyFilter01 implements GatewayFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
System.out.println("---------------⾃定义过滤器");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}2、配置过滤器
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder){
System.out.println("-----------------------init");
RouteLocator routeLocator = builder.routes().route( r->
r.path("/product/**") // predicates
.filters(f->f.filters( new MyFilter01() )) //filters
.uri("http://localhost:8001") //uri
).build();
return routeLocator;
}
}
2.2、创建⽹关过滤器 - 继承AbstractNameValueGatewayFilterFactory
相当于扩展Gateway内置的⽹关过滤器
/**
* 创建⼀个类继承AbstractNameValueGatewayFilterFactory,类名必须以GatewayFilterFactory结尾,类名前⾯的部分即为当前⾃定义⽹关过滤器的 名字
* 添加@Component注解,注册到Spring容器
*/
@Component
public class MyFilterGatewayFilterFactory extends
AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
System.out.println("name:"+config.getName());
System.out.println("value:"+config.getValue());
//创建⾃定义⽹关过滤器并返回
GatewayFilter gatewayFilter = new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⾃定义⽹关过滤器");
return chain.filter(exchange);
}
};
return gatewayFilter;
}
}
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: bbb
uri: 'http://localhost:8002'
predicates:
- Path=/order/**
filters:
- 'MyFilter=aa,bb'
3、全局过滤器
上述我们讲到的过滤器,都是配置在某个路由/服务中,我们称之为 ⽹关服务过滤器 ,Gateway提供了内置的全局过滤器,会拦截过滤所有到达⽹关服务器的请求。内置的全局过滤器默认⽣效,⽆需开发者⼲预。根据业务的需求我们也可以⾃定义全局过滤器以实现对所有⽹关请求的拦截和处理。
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("----------------------------------------------MyGlobalFilter");
List<String> list = exchange.getRequest().getHeaders().get("token");
if (list != null && list.size()>0){
String token = list.get(0);
System.out.println("token:"+token);
return chain.filter(exchange);
} else{
//如果没有token,或者token过期
ServerHttpResponse response = exchange.getResponse();
//设置响应头
response.getHeaders().add("ContentType","application/json;charset=utf-8");
//设置状态码
response.setStatusCode(HttpStatus.UNAUTHORIZED);
// 封装响应数据
String str = "";
DataBuffer dataBuffer = response.bufferFactory().wrap(str.getBytes());
return response.writeWith(Mono.just(dataBuffer));
}
}
@Override
public int getOrder() {
return 0;
}
}
八、Gateway动态路由配置
如果在Gateway⽹关的路由配置中,直接将服务的ip port配置进去,将导致:1.如果服务的地址变更,必须要重新配置gateway的路由规则2.如果服务采⽤集群部署,则不能实现负载均衡

1、Gateway服务器添加eureka-server依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2、配置⽹关路由
application.ymlserver:
port: 9999
spring:
application:
name: gateway-server
main:
web-application-type: reactive
cloud:
gateway:
routes:
- id: aaa
uri: 'lb://api-service1'
predicates:
- Path=/product/**
- id: bbb
uri: 'lb://api-service2'
predicates:
- Path=/order/**
eureka:
client:
service-url:
defaultZone: 'http://localhost:8761/eureka'
九、⽹关限流
1、⽹关限流介绍
服务的统⼀访问使⽤过滤器实现鉴权使⽤⽹关实现限流:通过限制⽤户的请求进⼊到服务中,有效控制应⽤系统的QPS,达到保护系统的⽬的
2、⽹关限流的常⻅算法
2.1、计数器算法
就是通过记录在单位时间请求的数量,在这个时间周期内达到设置定值之后就拒绝后续请求的进⼊。缺点:如果⽤户请求频率不均匀,有导致短时间、⾼并发的⻛险
2.2、漏桶算法
就是通过控制“漏桶”流出的速率以限制到达服务的⽤户流量缺点:⽹关会承载⽐较⼤的压⼒
2.3、令牌桶算法
就是所有进⼊⽹关的请求必须从令牌桶中得到令牌才可以进⾏服务调⽤,我们可以通过控制令牌桶的容量、令牌的产⽣速率达到控制⽤户流量的⽬的

3、Gateway⽹关限流
Gateway是基于令牌桶算法,使⽤redis作为“桶”结合过滤器实现了⽹关限流。
1、添加依赖<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.9.0</version>
</dependency>2、配置keyResolver
@Configuration
public class AppConfig {
@Bean
public KeyResolver keyResolver() {
//http://localhost:9999/order/query?user=1
//使⽤请求中的user参数的值作为令牌桶的key
//return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
}
}3、配置服务的限流规则
server:
port: 9999
spring:
application:
name: gateway-server
main:
web-application-type: reactive
cloud:
gateway:
routes:
- id: aaa
uri: 'lb://api-service1'
predicates:
- Path=/product/**
- id: bbb
uri: 'lb://api-service2'
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #令牌桶每s的填充速度
redis-rate-limiter.burstCapacity: 2 #令牌桶容量
redis-rate-limiter.requestedTokens: 1 #每个请求消耗多少个令牌
key-resolver: '#{@keyResolver}' #令牌桶key生成
redis:
host: 47.96.11.185
port: 7001
password: qfedu123
database: 0
lettuce:
pool:
max-active: 10
max-wait: 1000
max-idle: 5
min-idle: 3
eureka:
client:
service-url:
defaultZone: 'http://localhost:8761/eureka'
SpringCloud-Gateway搭建保姆级教程的更多相关文章
- 强大博客搭建全过程(1)-hexo博客搭建保姆级教程
1. 前言 本人本来使用国内的开源项目solo搭建了博客,但感觉1核CPU2G内存的服务器,还是稍微有点重,包括服务器内还搭建了数据库.如果自己开发然后搭建,耗费时间又比较多,于是乎开始寻找轻量型的博 ...
- renren-fast-vue人人开源前端项目搭建保姆级教程
1.从gitee上clone项目 git clone https://gitee.com/renrenio/renren-fast-vue.git 2.准备好python环境 需要有Python2以上 ...
- 保姆级教程——Ubuntu16.04 Server下深度学习环境搭建:安装CUDA8.0,cuDNN6.0,Bazel0.5.4,源码编译安装TensorFlow1.4.0(GPU版)
写在前面 本文叙述了在Ubuntu16.04 Server下安装CUDA8.0,cuDNN6.0以及源码编译安装TensorFlow1.4.0(GPU版)的亲身经历,包括遇到的问题及解决办法,也有一些 ...
- 自建本地服务器,自建Web服务器——保姆级教程!
搭建本地服务器,Web服务器--保姆级教程! 本文首发于https://blog.chens.life/How-to-build-your-own-server.html. 先上图!大致思路就是如此. ...
- RocketMQ保姆级教程
大家好,我是三友~~ 上周花了一点时间从头到尾.从无到有地搭建了一套RocketMQ的环境,觉得还挺easy的,所以就写篇文章分享给大家. 整篇文章可以大致分为三个部分,第一部分属于一些核心概念和工作 ...
- Eclipse for C/C++ 开发环境部署保姆级教程
Eclipse for C/C++ 开发环境部署保姆级教程 工欲善其事,必先利其器. 对开发人员来说,顺手的开发工具必定事半功倍.自学编程的小白不知道该选择那个开发工具,Eclipse作为一个功能强大 ...
- 使用springcloud gateway搭建网关(分流,限流,熔断)
Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...
- 保姆级教程,带你认识大数据,从0到1搭建 Hadoop 集群
大数据简介,概念部分 概念部分,建议之前没有任何大数据相关知识的朋友阅读 大数据概论 什么是大数据 大数据(Big Data)是指无法在一定时间范围内用常规软件工具进行捕捉.管理和处理的数据集合,是需 ...
- 保姆级教程:用GPU云主机搭建AI大语言模型并用Flask封装成API,实现用户与模型对话
导读 在当今的人工智能时代,大型AI模型已成为获得人工智能应用程序的关键.但是,这些巨大的模型需要庞大的计算资源和存储空间,因此搭建这些模型并对它们进行交互需要强大的计算能力,这通常需要使用云计算服务 ...
- vue-cli环境搭建 (超详细保姆级教程)
一.使用之前,我们先来掌握3个东西是用来干什么的. npm: Nodejs下的包管理器. webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资 ...
随机推荐
- 2019年第十届蓝桥杯国赛C++A组
蓝桥杯历年国赛真题汇总:Here 最后编辑时间: 2021年5月27日 统一声明 如果不写默认带有常用头文件 如果不表明主函数默认表示在 void solve(){} 默认使用 using names ...
- 2019CCPC-江西省赛(重现赛)队伍题解
2019CCPC江西省赛(重现赛) 第一次组队(和队内dalao:hzf)参加比赛,这次比赛使用的是我的笔电,但因为我来的比较晚,没有提前磨合:比如我的64键位键盘导致hzf突然上手不习惯. Solv ...
- L2-008 最长对称子串 (回文子串 / DP / Manacher算法)
对给定的字符串,本题要求你输出最长对称子串的长度.例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11. 输入格式: 输入在一 ...
- 你以为这是MacOS ,其实这是我的 Linux 系统 Manjaro!
对于如何将你的 Manjaro 系统美化成 MacOS 你需要做以下几件事情: 1.安装 WhiteSur-Gtk-theme 主题. 2.安装 Plank 软件. 3.安装 vala-panel-a ...
- vue.draggable中文文档
http://www.itxst.com/vue-draggable/fiamvqam.html https://blog.csdn.net/a772116804/article/details/10 ...
- Java面试——数据库知识点
MySQL 1.建 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合.一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null). 超键:在关系中能唯一标识元组的属性 ...
- 05_二叉树的层次遍历II
二叉树的层序遍历 II 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 . (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 示例 1: 输入:root = [3,9,20 ...
- 如何与chatgpt共存
作为程序员,专注于创造性劳动,而把重复性劳动任务交给chatgpt,要成为 需求 和 chatgpt的桥梁. 人工智能比如chatgpt越来越强,提问能力是人类的天赋,提问能力更为重要.
- 在线P图工具(基于minipaint开发)
在浏览github过程中,发现一个超级实用的仓库,viliulsle开发的minipaint,类似于photoshop的网页版.基于webpack开发的,打包非常简单,故自己搭建了一套. 在线预览 在 ...
- mvn 编译异常:Fatal error compiling: 无效的标记: -parameters
错误信息: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin::compile (defaul ...