gateway入门

(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点的麒麟

end