微服务网关

1. 微服务网关概述

​ 不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:
就比如常见的电商系统
在这里插入图片描述
当客户去掉用多个微服务时存在很多问题,比如:

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性
  • 存在跨域请求,在一定场景下处理相对复杂
  • 认证复杂,每个服务都需要独立认证
  • 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并
    成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很
    难实施
  • 安全隐患,服务端暴露的接口增加,增加了服务受攻击面积

以上这些问题可以借助网关解决。

网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 网关这一层。
也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 网关来
做,这样既提高业务灵活性又不缺安全性,典型的架构图如图所示:
在这里插入图片描述

优点如下:

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

2. 微服务网关主要作用

1.安全,提供了统一访问入口,降低了服务器受攻击面积
2.提供了统一跨域解决方案
3.提供了统一日志操作,可以进行统一监控
4.提供了统一权限认证支持
5.提供了微服务功能,可以保护微服务,防止雪崩效应发生
6.微服务网关最主要功能是整合各个微服务功能,形成一套或者多套系统

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

3. gateway

实现微服务网关的技术有很多,

  • nginx Nginx (engine x) 是一个高性能的HTTP和 反向代理web 服务器,同时也提供
    了IMAP/POP3/SMTP服务
  • zuul ,Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。
  • spring-cloud-gateway, 是spring 出品的 基于spring 的网关项目,集成断路器,路
    径重写,性能比Zuul好。

我们使用gateway这个网关技术,无缝衔接到基于spring cloud的微服务开发中来。

4. 微服务网关搭建

我们开发的系统 有包括前台系统和后台系统,后台的系统给管理员使用。那么
也需要调用各种微服务,所以我们针对管理后台搭建一个网关微服务。分析如下:
在这里插入图片描述
pom.xml:

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring‐cloud‐starter‐gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring‐cloud‐starter‐netflix‐hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring‐cloud‐starter‐netflix‐eureka‐
client</artifactId>
        </dependency>

application.yml:

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      routes:
      ‐ id: goods
        uri: lb://goods
        predicates:
        ‐ Path=/goods/**
        filters:
        ‐ StripPrefix= 1
      ‐ id: system
        uri: lb://system
        predicates:
        ‐ Path=/system/**
        filters:
        ‐ StripPrefix= 1
server:
  port: 9101
eureka:
  client:
    service‐url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer‐ip‐address: true

官方手册:
https://cloud.spring.io/spring-cloud-gateway/spring-cloud-
gateway.html#_stripprefix_gatewayfilter_factory

5.微服务网关解决跨域问题

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

最终配置文件为:

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        - id: goods
          uri: lb://goods
          predicates:
            - Path=/goods/**
          filters:
            - StripPrefix= 1
            - name: RequestRateLimiter #请求数限流 名字不能随便写
              args:
                key-resolver: "#{@ipKeyResolver}"
                redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
                redis-rate-limiter.burstCapacity: 1 #令牌桶总容量
        - id: system
          uri: lb://system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix= 1
  redis:
    host: 192.168.211.132
server:
  port: 9101
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true

6.微服务网关过滤配置

在这里插入图片描述
路由过滤器允许以某种方式次改传入的HTTP请求或传出的HTTP响应,路径过滤器的范围为特定路径。
Spring Cloud Gateway包含许多内置的GatewayFilter工厂,如上图,根据请求路径到不同的微服务去,这块可以由Gateway的过滤功能实现。

7.1 Host路由

比如请求cloud.mall.com,可以将请求给http://localhost:18081服务器
配置如下:

      routes:
        - id: cloud_goods_route #唯一标识符
          uri: http://localhost:18081 #指定要路由的服务
          predicates: #断言,路由规则配置
            - Host=cloud.mall.com #用户请求的域名规则配置

配置Hosts:

127.0.0.1 cloud.mall.com

7.2 路径匹配过滤

将Host换成Path
比如:现在我们想所有以/brand开始的请求,都路由到http://localhost:18081
配置如下:

      routes:
        - id: cloud_goods_route #唯一标识符
          uri: http://localhost:18081 #指定要路由的服务
          predicates: #断言,路由规则配置
            - Path=/brand** 

7.3 PrefixPath过滤配置

比如:用户每次请求路径时,都可以给真实请求加一个统一前缀
例如

      routes:
        - id: cloud_goods_route #唯一标识符
          uri: http://localhost:18081 #指定要路由的服务
          predicates: #断言,路由规则配置
            - Path=/**
         filters:
         - PrefixPath=/brand 

7.4 StripPrefix 过滤配置

很多时候,用户的请求路径时/api/brand,而真实路径是/brand,这时候我们需要去掉/api才是真实的路径,此时使用StripPrefix 来实现路径的过滤操作.如下配置:

 routes:
        - id: cloud_goods_route #唯一标识符
          uri: http://localhost:18081 #指定要路由的服务
          predicates: #断言,路由规则配置
            - Path=/**
         filters:
         - StripPrefix=1 #回将路径中的第一个路径过滤掉

7.5 LoadBalancerClient路由过滤器(客户端负载均衡)

LoadBalancerClient会作用在url开头的路由,然后利用loadBalancerClient来获取服务实例,构造目标requestUrl,设置到GATEWAY_REQUEST_URL_ATTR属性中,供NettyRoutingFilter使用

	routes:
        - id: goods
         #lb:使用LoadBalancerClient实现负载均衡,后面goods是微服务名称[主要用于集群环境]
          uri: lb://goods
          predicates:
            - Path=/goods/**
          filters:

8. 网关限流

在这里插入图片描述
Nginx虽然可以限流,但是它的流量还是很大,第二层可以用网关进行限流.比如限制用户每秒只能访问3次,保护微服务,防止雪崩效应.

网关可以做很多的事情,比如:限流。当我们的系统被频繁的请求的时候,就有可能将系统压垮。为了解决这个问题,需要在每一个微服务中做限流操作.

8. 1 网关限流操作思路分析

在这里插入图片描述
网关限流主要有已下算法:

  • 1.令牌桶算法
  • 2.漏桶算法
  • 3.计数算法

8. 2令牌桶算法

令牌桶算法是比较常见的算法之一,大概描述如下:
1).所有的请求在处理前都需要拿到一个可用的令牌才会被处理
2).根据限流的大小,设置按照一定的速率网桶中添加令牌
3).桶设置最大的放置令牌限制,当桶满时,新添加的令牌就会被丢弃或者拒绝
4).请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务后,将令牌直接删除
5).令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流.
如下图:
在这里插入图片描述
步骤:
1.匀速生成令牌,存入到令牌桶中,redis用到
2.用户请求微服务,会先获取用户的IP,IP去令牌桶中拿一个令牌,再判断是否获取令牌,若拿到就放行进入后台系统,如果没有拿到,就丢弃请求

注意:令牌桶有最大限额和最小限额

这个算法的实现,有很多技术,Guaua是其中之一,redis客户端也有实现

8. 3网关限流代码实现

需求:每个ip地址1秒内只能发送1次请求,多出来的请求返回429错误。
代码实现:
(1)spring cloud gateway 默认使用redis的RateLimter限流算法来实现。所以我们要
使用首先需要引入redis的依赖

  <!‐‐redis‐‐>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐data‐redis‐reactive</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

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

   //定义一个KeyResolver
    @Bean
    public KeyResolver ipKeyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return
Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
//exchange.getRequest().getRemoteAddress().getHostName():需要使用的用户身份识别唯一标识IP
            }
        };
    }

(3)修改application.yml中配置项,指定限制流量的配置以及REDIS的配置,修改后最
终配置如下:

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        - id: goods
          uri: lb://goods
          predicates:
            - Path=/goods/**
          filters:
            - StripPrefix= 1
            - name: RequestRateLimiter #请求数限流 名字不能随便写
              args:
                key-resolver: "#{@ipKeyResolver}"
                redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
                redis-rate-limiter.burstCapacity: 1 #令牌桶总容量
        - id: system
          uri: lb://system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix= 1
  redis:
    host: 192.168.211.132
server:
  port: 9101
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值