GateWay网关笔记

GateWay网关笔记

1. Gateway网关简介

为微服务架构提供一种简单有效的统一的 API 路由管理方式。

API网关

API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统

  • 管理授权
  • 访问控制
  • 流量限制

REST API 接口服务就被 API 网关保护起来,对所有的调用者透明

隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

职能

  • 请求接入
    • 作为所有API接口服务请求的接入点
  • 业务聚合
    • 作为所有后端业务服务的聚合点
  • 中介策略
    • 实现安全、验证、路由、过滤、流量控制等策略
  • 统一管理
    • 对所有API服务和策略进行统一的管理

为什么需要网关

  • 身份认证和权限验证
  • 服务路由、负载均衡
  • 请求限流

在SpringCloud中网关的实现包括两种:

  • gateway
  • zuul

Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO。

从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。

GateWay的几个重要概念:

  • Route(路由):网关的基本构建块。
    • 组成:
      1. 一个ID
      2. 一个目标URI
      3. 一组断言
      4. 一组过滤器定义
    • 如果断言为真,则路由匹配
  • Predicate(断言):输入类型是一个ServerWebExcahnge。
    • 可用来匹配来自HTTP请求的任何内容,例如headers或参数
  • 过滤器(filter)
    • GateWay中的Filter分为两种类型的filter:
      • GateWay Filter
      • Global Filter
    • 过滤器Filter将会对请求和响应进行修改处理

2. GateWay入门

本步骤如下:

1.创建SpringBoot工程gateway,引入网关依赖

	   <!--网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--nacos服务发现依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

2. 编写启动类

package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient  //Nacos注册
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class,args);
    }
}

3. 编写基础配置和路由规则

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求      routes: # 网关路由配置
        - id: order-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求

4. 启动网关服务进行测试

启动nacos、启动user-service 同时注入到nacos中

在http://localhost:10010/user/1中即可访问user-service

3. GateWat路由断言工厂

名称说明示例
After是某个时问点后的请求- After=2037-01-20T17:42:47.789-07:0O[America/Denver]
Before是某个时问点之前的请求- Before=2031-04-13T15:14:47.433+08:0O[Asia/Shanghai]
Between是某两个时间点之前的请求-Between=2037-01-20T17:42:47.789-07:0O[America/Denver]. 2037-01-21T17:42:47.789-07:0o[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate,ch.p
Header请求必须包含某些header- Header=x-Request-ld,ld+
Host请求必须是访问某个host(域名)- Host=+.somehost.org.t.anotherhost.org
Method请求方式必须是指定方式-Method=GET,POS1
Path请求路径必须符合指定规则- Path-/red/{segment}./blue/*-
Query请求参数必须包含指定参数- Query=name, Jack或者-Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

4. 路由的过滤器配置

GateWayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

  • 请求
  • 响应

Spring提供了30+的路由过滤工厂

详见:

https://www.springcloud.cc/spring-cloud-greenwich.html#_gatewayfilter_factories

示例:给所有进入userservice的请求添加一个请求头

给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking asewome!

实现方式:

在gateway中修改application.yml文件,给userservice的路由添加过滤器:

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求      routes: # 网关路由配置
          filters:
            - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头
        - id: order-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求

这个配置则是:

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求      routes: # 网关路由配置
          filters:
            - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头
        - id: order-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
      default-filters: 
        - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头

5. Globalfilter全局过滤器

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,于GateWayFilter的作用一样

区别在于GateWayFilter通过配置定义,处理逻辑是固定的

而GlobalFilter的逻辑需要自己写代码实现

实现GlobalFilter的接口

exchange: 请求上下文,里面可以获取Request、Response等信息

chain 用来把请求委托给下一个过滤器

定义一个过滤器:

package com.example.gateway;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
//@Order(-1) //顺序注解 或接Ordered接口
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /*
        * 1. 获取请求参数*/
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> queryParams = request.getQueryParams();
//         2. 获取参数中的authorization参数\
        String authorization = queryParams.getFirst("authorization");
//         3. 判断参数值是否等于admin
        if("admin".equals(authorization)){
            //         4. 是则放行,从过滤器链里找下一个
            Mono<Void> filter = chain.filter(exchange);
            return filter;
        }
        //         5. 否则拦截、设置状态码
        else{
            exchange.getResponse().setStatusCode(HttpStatus.valueOf(401));
          return   exchange.getResponse().setComplete();
        }

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

6. 跨域问题

什么是跨域问题
跨域:域名不一致就是跨域,主要包括:

域名不同: www.taobao.com 和 www.taobao.org

域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决跨域问题
在gateway服务的application.yml文件中,添加下面的配置:

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值