微服务网关 SpringCloud Gateway 实战

首先微服务是为了构建复杂系统而生的,如果并发所有系统都适合使用微服务架构,任何技术都是为了解决具体应用业务场景而生的,离开了业务场景谈技术都是耍流氓!可能你会说,我们做基础开发不做业务,基础开发面向的领域跟业务领域可能不同而已,即领域模型不同而已,其实都是使用编码解决不各自领域的问题,就好像是网络七层模型,大家处于不同层次而已。

使用微服务网关之前可以思考如下几个问题:
1、为什么要用微服务网关,如果不用行不行?
2、我们不用微服务是否也可以用微服务网关?

相信大家对Nginx并不陌生,微服务网关能做什么,简单说跟Nginx一样都能反向代理,也就是说可以做前后端分离。还有吗?当然。当你的项目还是初期的时候,你可能只需要用到做前后分离即可。当你应用庞大之后你需要对系统进行拆解,你可能会有商品服务、购物车服务、商品详情、支付服务、物流服务等等,而且你可能会有PC端、APP端、小程序等等,当业务部门精心准备一场购物盛宴的时候,你可能还会遇到洪水般的流量,你如何保障系统平稳运行,如丝般顺滑。不是说一个就能解决所有问题,而且以上这些问题网关都能起到至关重要的作用。看到这里上面问题的相信大家心里已有答案。

微服务网关:
zuul1.0 : netflix 公司开源的,基于 Serlvet ,与Spring Cloud 集成。优点:开发容易、编程模型简单。缺点:连接数限制、线程上下切换开销、延迟阻塞耗尽线程连接资源.适用于CPU密集型,例如计算视频编解码,图像处理,加解密,压缩解压等等
zuul2.0: 基于Netty实现异步非阻塞编程模型.优点:线程开销少、连接数易扩展 缺点:编程模型复杂,调试复杂 适用于IO密集型如,web服务器
kong: nginx+lua
SpringCloud Gateway: 基于Spring Boot 2.x, Spring WebFlux

......

市面的网关还有很多我们就不一一列举了,根据我的经验入门难度来排序:
zuul1.0

今天我们先来看一下SpringCloud Gateway
SpringCloud Gateway 通过匹配路由规则然后执行相应动作。

一、引入依赖

        
            org.springframework.boot
            spring-boot-starter-parent
            2.1.3.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-gateway
       

二、路由转发规则

路由转发规则定义说明:

id: 路由规则唯一识别
predicates: 谓词工厂,触发转发条件:After Before Between Cookie Header Host Method Path Query RemoteAddr Weight
uri:转发地址
filter: 路由过滤器允许以某种方式修改传入HTTP请求或输出HTTP响应。路由筛选器的作用域是特定路由。SpringCloudGateway包括许多内置的GatewayFilter工厂:
AddRequestHeader AddRequestParameter AddResponseHeader DedupeResponseHeader Hystrix PrefixPath PreserveHostHeader RequestRateLimiter Redis RateLimiter RedirectTo
order: 路由规则优先级

application.yaml

spring:
    cloud:
      gateway:
        routes:

SpringCloudGateway 路由配置规则很丰富,我们针对我们常用的场景进行举例:

根据路径(Path)匹配转发实现前后分离

假设我们的前端是NodeJs项目,我们通过ajax分别访问商品服务、订单服务。

  • 静态文件服务器:proxy.static.url
  • 商品后台API服务器:proxy.api.goods.url
  • 订单后台API服务器:proxy.api.order.url
    PS: 假设所有静态资源访问根路径 /,商品服务访问/api/goods/** ,订单服务访问/api/order/**
    针对这种场景我们进行如下配置即可实现:
spring:
    cloud:
      gateway:
        routes:
          - id: static
            predicates:
            - Path=/**
            uri: ${proxy.static.url} #静态资源服务器,如 html,js,css,img等
            order: 1000
         - id: api_goods
            predicates:
            - Path=/api/goods
            uri: ${proxy.api.goods.url} #商品 API 服务器
            order: 1000
        - id: api_order
            predicates:
            - Path=/api/order
            uri: ${proxy.api.order.url} #订单 API 服务器
            order: 1000

根据路径(Path)识别应用,并重定向到 / 。适用于遗留系统接入网关(遗留系统大多使用根路径:/)。 RewritePath 支持正则表达式,分组提取

spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org #后端应用服务
        predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo(?/?.*), $\{segment}

根据主机(Host)识别应用 适用于遗留系统接入网关但又想保留原始域名等,此种方式接入网关改造量最少也能保留原始域名是目前最优方案。

PS: 需要将应用原始域名CNAME到网关域名

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org #后端应用服务
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
        

网关跨域配置,支持复杂请求,如POST SSE websocket 等

由网关代为跨域,后端应用可以不做跨域处理

spring:
  cloud:
    gateway:
      routes:
      - id: spider_route
        uri: ws:${proxy.api.url}
        predicates:
        - Path=/**
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # 如果后端服务器也进行跨域支持,需要加上此项。作用是进行返回头去重
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*" #生产环境为了安全考虑请配置具体域名
            allowedMethods:
            - POST
            - GET
            - DELETE
            - PUT
           allowedHeaders: "*" #不配置此项可支持简单请求跨域如:GET、DELETE 如要兼容复杂请求如:POST SSE 请求此项必不可少
        

你可能感兴趣的:(微服务网关 SpringCloud Gateway 实战)