微服务网关&网关限流

微服务网关Gateway

  • 1.微服务网关Gateway
    • 1.1 微服务网关概述
      • 微服务网关的优点
      • 实现微服务网关的技术:
    • 1.2 微服务网关微服务搭建
      • 步骤
    • 1.3 微服务网关跨域
    • 1.4 微服务网关过滤器
  • 2.网关限流
    • 2.1思路分析
    • 2.2令牌桶算法
    • 2.3令牌桶思路分析
    • 2.4限流代码思路

1.微服务网关Gateway

1.1 微服务网关概述

不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性
  • 存在跨域请求,在一定场景下处理相对复杂
  • 认证复杂,每个服务都需要独立认证
  • 难以重构

网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过网关这一层。这样安全、性能、监控可以交由网关来做。微服务网关&网关限流_第1张图片

微服务网关的优点

  • 安全 ,只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护。
  • 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。(日志的监控与分析)
  • 易于统一认证授权。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
  • 减少了客户端与各个微服务之间的交互次数。

总结:微服务网关就是一个系统,通过暴露该微服务网关系统,方便我们进行相关的鉴权,安全控制,日志统一处理,易于监控的相关功能。

实现微服务网关的技术:

  • nginx
  • Zuul ,Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。
  • spring-cloud-gateway, 是spring 出品的 基于spring 的网关项目,集成断路器,路径重写,性能比Zuul好。

gateway官网的地址
https://spring.io/projects/spring-cloud-gateway

1.2 微服务网关微服务搭建

步骤

  1. 创建gateway的maven工程
  2. 添加依赖
		<dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-gatewayartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
  1. 在启动类上添加注解
    @EnableEurekaClient
  2. 在resources下创建application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: after_route #要跳转的服务名
        uri: lb://goods #lb:在eureka上找到goods服务,然后通过后面的网址跳转
        predicates:
        ‐ Path=/goods/** #goods后面的请求全部通过
		filters:
		‐ StripPrefix= 1 #访问时将goods省略掉(如果不明白,就把这个写上就行)

1.3 微服务网关跨域

修改application.yml ,在spring.cloud.gateway节点添加配置:

globalcors:
  cors-configurations:
    '[/**]': # 匹配所有请求
      allowedOrigins: "*" #跨域处理 允许所有的域
      allowedMethods: # 支持的方法
        - GET
        - POST
        - PUT
        - DELETE

1.4 微服务网关过滤器

我们可以通过网关过滤器,实现一些逻辑的处理,比如ip黑白名单拦截、特定地址的拦截等。

/**
 * 获取用户ip
 */
@Component
public class IpFilter implements GlobalFilter, Ordered {
    //具体逻辑业务实现
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("经过第一个过滤器");
        //1.获取请求 2.获取远程地址 3.获取ip
        String ip = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName();
        System.out.println("ip:" + ip);
        //放行
        return chain.filter(exchange);
    }

    //当前过滤器级别
    @Override
    public int getOrder() {
        return 1;
    }
}

以上代码是获取用户请求的地址,并没有实现具体逻辑。

2.网关限流

限流:当我们的系统被频繁的请求的时候,就有可能将系统压垮。
所以为了解决这个问题,需要在每一个微服务中做限流操作。
但是如果有了网关,那么就可以在网关系统做限流,因为所有的请求都需要先通过网关系统才能路由到微服务中。

2.1思路分析

微服务网关&网关限流_第2张图片

2.2令牌桶算法

概述:

  1. 所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;
  2. 根据限流大小,设置按照一定的速率往桶里添加令牌;
  3. 桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;
  4. 请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;
  5. 令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流。

2.3令牌桶思路分析

微服务网关&网关限流_第3张图片

2.4限流代码思路

需求:每个ip地址1秒内只能发送1次请求,多出来的请求返回429错误。

  1. 添加依赖, gateway 默认使用redis的RateLimter限流算法来实现。

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redis-reactiveartifactId>
            <version>2.1.3.RELEASEversion>
        dependency>
  1. 定义KeyResolver

GatewayApplicatioin引导类中添加如下代码,KeyResolver用于计算某一个类型的限流的KEY也就是说,可以通过KeyResolver来指定限流的Key。

 //指定限流的key
    @Bean
    public KeyResolver keyResolver() {
        return exchange -> {
            //根据ip限流
            String ip = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName();
            return Mono.just(ip);
        };
    }
  1. 修改application.yml中配置项,指定限制流量的配置以及REDIS的配置
routes:
        - id: goods
          uri: lb://goods
          predicates:
            - Path=/goods/**
          filters:
            - StripPrefix= 1
            - name: RequestRateLimiter #请求数限流 名字不能随便写
              args:
                key-resolver: "#{@keyResolver}"
                redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
                redis-rate-limiter.burstCapacity: 1 #令牌桶总容量

以上是在原来的配置文件中修改,在predicates:下添加依赖。

  1. burstCapacity:令牌桶总容量。

  2. replenishRate:令牌桶每秒填充平均速率。

  3. key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

  4. 在配置文件中配置redis

redis:
    host: 192.168.200.128
    port: 6379

以上是针对每一条请求都做了限流,针对单独某一条ip做限流,需要在KeyResolver配置单独的ip。

你可能感兴趣的:(微服务,java,redis)