七 统一网关Gateway

1、为什么需要网关

身份认证、权限校验;
服务路由、负载均衡;
请求限流。

2、网关的技术实现

gateway,zuul

Zuul 是基于Servlet实现的,属于阻塞式编程;
Spring Cloud Gateway 则是基于Spring5中提供的WebFlux实现的,属于响应式编程,具备更好的性能。

3、搭建Gateway网关

1、创建新的module,引入Spring Cloud Gateway依赖和nacos的服务发现依赖;

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

         <!--由于springcloud2020弃用了Ribbon,因此Alibaba在2021版本nacos中删除了Ribbon的jar包
            导致无法通过lb路由到指定微服务,出现了503情况。
            引入springcloud loadbalancer包来解决即可-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

2、resources目录下,新建application.yml文件

server:
  port: 10000 #端口号

spring:
  application:
    name: gateway-server #服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #nacos注册中心地址
    gateway:
      routes: #路由配置
        - id: order-server #路由id,自定义,唯一即可
          uri: lb://order-server #路由的目标服务,lb就是负载均衡,order-server是服务名称
          predicates: #路由断言,判断请求地址是否符合路由规则的条件
            - Path=/api/order/** #这个是按照路径匹配,只要以/api/order开头的请求地址就符合要求
          filters: #路由过滤器,处理请求或响应
            #路径重写 例如:localhost:10000/api/a,重写后:localhost:10000/a
            - RewritePath=/api/(?<segment>.*),/$\{segment}

3、创建启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApp {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApp.class, args);
    }
}

4、路由断言工厂Route Predicate Factory

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件。

例如Path=/user/**是按照路径匹配,这个规则是由:org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的,像这样的断言工厂在SpringCloudGateway还有十几个。

Spring提供了11种基本的Predicate工厂:

image

5、过滤器

1、路由过滤器 GatewayFilter

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

Spring提供了31种不同的路由过滤器工厂:

image

2、默认过滤器

如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:

image

3、全局过滤器 GlobalFilter

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

区别在于GatewayFilter是通过配置定义的,处理逻辑固定。而GlobalFilter的逻辑需要自己写代码实现。

定义方式是实现GlobalFilter接口:

//排序(注解,实现接口两种方式)
//@Order(-1)
@Component
public class GatewayFilter implements GlobalFilter, Ordered {

    /**
     *  处理当前请求 通过GatewayFilterChain将请求交给下一个过滤器处理
     *
     *  @param exchange 请求上下文,里面可以获取Request、Response等信息
     *  @param chain 用来把请求委托给下一个过滤器
     *  @return {@code Mono<Void>} 返回标示当前过滤器业务结束
     * */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取请求参数
        //exchange.getRequest().getHeaders().getFirst("authorization");
        //exchange.getRequest().getQueryParams().getFirst("key");

        //放行
        //chain.filter(exchange);

        //拦截
        //exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        //return exchange.getResponse().setComplete();
        return null;
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

4、过滤器执行顺序

请求进入网关会碰到三类过滤器:路由过滤器、DefaultFilter、GlobalFilter

请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前:

(1)GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

(2)路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增

(3)当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行

6、跨域处理

跨域:域名不一致就是跨域,主要包括:

域名不同: www.taobao.comwww.taobao.org
域名相同,端口不同:localhost:8080和localhost8081

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

解决方案:CORS

      globalcors: #全局跨域处理
        add-to-simple-url-handler-mapping: true #解决option请求被拦截问题
        cors-configurations:
          '[/**]':
            allowedOrigins: #允许哪些网站的跨域请求
              - "http://localhost:8090"
            allowedMethods: #允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" #允许在请求中携带的头信息
            allowCredentials: true #是否允许携带cookie
            maxAge: 360000 #这次跨域检测的有效期
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容