(1)Spring Cloud Gateway -- 基础入门
https://www.jianshu.com/p/0fe5b864ab53?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
(2)学习视频
https://www.bilibili.com/video/BV11i4y1F7eu?p=2&spm_id_from=pageDriver
用来管理服务通信的
zuul1.3是阻塞io、不支持长连接。。。
gateway基于spring boot2,基于spring5,spring5的新特性(reactor)都会使用,需要了解。
其中:spring5新特性
https://www.jianshu.com/p/cebc3cf0bec0
(jdk8新特性,响应式编程支持,函数式web框架)
1.服务网关是什么,是微服务的统一入口。【nginx也是一种网关】
解决前端不需要关心后台具体服务地址是什么、跨域问题、防火墙问题、系统负载均衡问题。
网关的作用
解决了:
1.多个微服务,统一入口
2.跨域问题
3.身份认证问题,jwt
4.重构问题,
5.防火墙问题。
好处:网关介于客户端和微服务之间
1.易于监控
2.易于认证
3.减少客户端和微服务之间的交互,降低复杂度。
作用
解决了什么问题
● 1.统一接入
● 2.协议适配
● 3.安全维护
● 4.流量管控
请求执行流程
发送过来是pre过滤器,返回是经过post过滤器
2.在gateway中配置uri配置有三种方式,包括
第一种:ws(websocket)方式: uri: ws://localhost:9000
第二种:http方式: uri: http://localhost:8130/
第三种:lb(注册中心中服务名字)方式: uri: lb://brilliance-consumer
lb=load balance,负载均衡去调用微服务,从注册中心去获取,叫动态路由!!!
能被gateway的lb方式识别到的命名规则为:
"a-zA-Z:."
这也意味着,java命名规范中可以使用的英文下划线("_")不能被识别,而我命名为:brilliance_consumer,刚好带下划线,改为brilliance-consumer后则可以正常通过网关访问自己项目。
lb通过eureka来使用:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
instance:
prefer-ip-address: true
微服务太多,不需要每个服务名都配置路由,而是开启自动发现。
spring:
application:
name: gateway-api
cloud:
gateway:
discovery:
locator:
enabled: true #配合注册中心实现网关服务发现
lower-case-service-id: true #将服务名改成小写
======================================================
12.过滤器(网关过滤器,全局过滤器)
● 网关过滤器:一般配置在单个路由上面。
● 全局过滤器:统一鉴权,对所有请求生效。
12.1,网关过滤器
12.2,全局过滤器
12.3,自定义过滤器
主要讲一下,自定义全局过滤器
12.3.1,注解和yml同时配置一个path,注解生效
(1)GatewayRoutesConfiguration里/product/**
(2)yml里routes,不能同时配置/product/**,否则yml里的不生效
12.3.2,接收参数getFirst("keyname")
过滤器,都是通过getFirst("keyname"),来获取参数的
@Component
public class RequestUserAndPathKeyResolver implements KeyResolver {
private static final List<HttpMessageReader<?>> messageReaders = HandlerStrategies
.withDefaults().messageReaders();
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(MD5Utils.md5Hex(exchange.getRequest().getHeaders().getFirst("Access-Token")
+ exchange.getRequest().getPath().pathWithinApplication().value(),"UTF-8"));
}
}
MultiValueMap。getFirst(“xxxxx”)
1.计数器算法:1分钟100个请求,有个技术,容易被恶意攻击。
2.漏桶算法:【队列机制实现】保护微服务,伤害自己。
3.令牌桶算法:【队列机制实现】保护自己,也保护微服务-------------ok
漏桶算法
1s100个请求到网关,漏桶出口,1s1个访问微服务,需要100s才能处理完,这样网关会堆积请求,可能会崩溃了。
高可用网关,网关也要做集群。
令牌桶算法
令牌桶算法实现:redis+lua脚本
redis虚拟机
redis desktop manager
lua脚本
参考官方文档,录得视频
RequestRateLimiter:
配置文件,pom文件,引入redis
(redis改为common-pool里的连接池了。,jedis有安全问题)
指定:RequestRateLimiter #限流过滤器
和三个参数:args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 1 # 令牌桶总容量
key-resolver: "#{@ipKeyResolver}" # 使用SpEL表达式按bean里方法名称,引用bean
gateway:
discovery:
locator:
enabled: true #配合注册中心实现网关服务发现
lower-case-service-id: true #将服务名改成小写
routes:
- id: user-provider
# uri: http://localhost:8010/ # 真正访问的URL
uri: lb://user-provider # 根据服务名,负载均衡从注册中心 拿服务
predicates:
- Path=/student/**,/api-gateway/** #Path 匹配请求参数中包含某段
filters:
- name: RequestRateLimiter #限流过滤器
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 1 # 令牌桶总容量
key-resolver: "#{@ipKeyResolver}" # 使用SpEL表达式按bean里方法名称,引用bean
redis:
timeout: 10000
host: 127.0.0.1
port: 6379
database: 1
lettuce:
pool:
max-active: 1024
max-wait: 10000
max-idle: 200
min-idle: 5
@Bean方法名,ipKeyResolver,就是SpEL表达式获取的bean的id
@Configuration
public class CustomResolver {
@Bean
public KeyResolver ipKeyResolver(){
System.out.println("##############ipKeyResolver########################");
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
}
RequestRateLimiter 里 只能有一个bean??
sentinel+gateway!!!!
sentinel是alibaba的限流组件。
限流分组。。。
https://github.com/alibaba/Sentinel/wiki/网关限流
高可用网关:Nginx+网关集群,可实现高可用网关
qq是4个9,一年53分钟不可用,4个9是拥有自动恢复能力的高可用。
一般3个9,就是高可用,就是8.76小时不可用。
一般2个9,就是基本可用,就是87.6小时不可用。
egb:
Mono ?
CustomRequestRateLimiterGatewayFilterFactory extends AbstractGatewayFilterFactory
RequestUserAndPathKeyResolver implements KeyResolver:ratelimit??
凌晨4点的麒麟