Spring Cloud -- GateWay

  1. 为什么需要网关

在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题,例如:
客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
认证复杂,每个微服务都有独立认证
存在跨域请求,在一定场景下处理相对复杂

提供统一的入口和统一的出口

  1. 网关对比

  • Zuul 1.x

Netflix开源的网关,基于Servlet框架构建,功能丰富,使用JAVA开发,易于二次开发 问题:即一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。

  • Zuul 2.x

Zuul2 采用了Netty实现异步非阻塞编程模型,每个 CPU 核一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。

  • GateWay

Spring公司为了替换Zuul而开发的网关服务,底层为Netty,将在下面具体介绍。

  • Nginx+lua

使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用,lua是一种脚本语言,可以来编写一些简单的逻辑, nginx支持lua脚本,性能很强,问题在于:无法融入到微服务架构中

  • Kong

基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。 问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。

带有Nginx的性能要远远高于zuul和gateway,但是nginx不支持微服务,所以一般使用zuul和gateway。gateway的性能要高于zuul,所以我们来学习gateway

  1. 官网地址

https://spring.io/projects/spring-cloud-gateway
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

  1. 特点

1.性能强劲:是Zuul的1.6倍

2. 功能强大:内置了很多实用的功能,例如转发、监控、限流等

3. 设计优雅,容易扩展

不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

  1. gateway工作流程图:

客户端向 Spring Cloud Gateway 发出请求。如果Gateway Handler Mapping确定请求与路由匹配,则将其发送到Gateway Web Handler 处理程序。此处理程序通过特定于请求的Fliter链运行请求。Fliter被虚线分隔的原因是Fliter可以在发送代理请求之前(pre)和之后(post)运行逻辑。执行所有pre过滤器逻辑。然后进行代理请求。发出代理请求后,将运行“post”过滤器逻辑。

  1. 过滤器作用

  • Filter在pre类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等。

  • Filter在post类型的过滤器可以做响应内容、响应头的修改、日志输出、流量监控等

  • 这两种类型的过滤器有着非常重要的作用

  1. 核心概念

  • Route(路由)

路由是构建网关的基础模块,它由ID,目标URI,包括一些列的断言和过滤器组成,如果断言为true则匹配该路由

  • Predicate(断言)

参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),请求与断言匹配则进行路由

  • Filter(过滤)

指的是Spring框架中GateWayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

  • 三个核心点连起来:

当用户发出请求到达GateWay,GateWay会通过一些匹配条件,定位到真正的服务节点,并在这个转发过程前后,进行一些及细化控制。其中Predicate就是我们匹配的条件,而Filter可以理解为一个拦截器,有了这两个点,再加上目标URI,就可以实现一个具体的路由了。

  1. spring boot和spring cloud的对应关系

  1. gateway项目搭建:

引入GateWay一定要删除spring-boot-starter-web依赖,否则会有冲突无法启动

  1. 父项目引入

<!--spring cloud Hoxton.SR5-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud-gateway-varsion}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
  1. 子项目

因为GateWay也需要注册进Nacos,所以也需要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>
  1. 配置yml

server:
  port: 9999
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true #开启注册中心路由功能
      routes:  # 路由
        - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
          uri: http://localhost:9001/nacos-provider # 匹配提供服务的路由地址
          predicates: # 断言
            - Path=/msb/** # 断言,路径相匹配进行路由

代码中也可以添加配置

@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        // 构建routes
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        // 具体的路由地址
        routes.route("path_msb",r -> r.path("/msb/**").uri("http://localhost:9001/nacos-provider")).build();
        // 返回所有的理由规则
        return routes.build();
    }
}

  1. 路由

  1. 自动路由

gateway自带负载均衡

gateway.discovery.locator.enabled: true , 开启自动路由功能

不配置具体的routes,自动路由时访问需要加serviceId

localhost:9999/ServiceID/xxx/

2. 手动负载均衡(更常用)

uri中加lb表示负载均衡

 routes: # 路由
    - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
      uri: lb://nacos-provider # 匹配提供服务的路由地址
      predicates: # 断言
        - Path=/msb/** 

routes中配置了以后,走routes中的配置,不走gateway.discovery.locator.enabled

  1. 断言Predicate

当满足条件后才会进行转发,如果是多个,那就是满足所有条件才会转发

断言种类

  1. After:匹配在指定日期时间之后发生的请求。

  1. Before:匹配在指定日期之前发生的请求。

  1. Between:需要指定两个日期参数,设定一个时间区间,匹配此时间区间内的请求。

  1. Cookie:需要指定两个参数,分别为name和regexp(正则表达式),也可以理解Key和Value,匹配具有给定名称且其值与正则表达式匹配的Cookie。

  1. Header:需要两个参数header和regexp(正则表达式),也可以理解为Key和Value,匹配请求携带信息。

  1. Host:匹配当前请求是否来自于设置的主机。

  1. Method:可以设置一个或多个参数,匹配HTTP请求,比如GET、POST

  1. Path:匹配指定路径下的请求,可以是多个,用逗号分隔

  1. Query:需要指定一个或者多个参数,一个必须参数和一个可选的正则表达式,匹配请求中是否包含第一个参数,如果有两个参数,则匹配请求中第一个参数的值是否符合正则表达式。

  1. RemoteAddr:匹配指定IP或IP段,符合条件转发。

  1. Weight:需要两个参数group和weight(int),实现了路由权重功能,按照路由权重选择同一个分组中的路由

具体用法:

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

  1. 过滤器Filter

路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器的范围是特定的路由。Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。

过滤器分为内置过滤器和自定义过滤器

内置Filter

  1. GateWay内置的Filter生命周期为两种:pre(业务逻辑之前)、post(业务逻辑之后)

  1. GateWay本身自带的Filter分为两种: GateWayFilter(单一)、GlobalFilter(全局)

  1. 单一的有32种,全局的有9种

  1. 官方网址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

自定义Filter(常用)

需要实现两个接口:GlobalFilter、 Ordered

@Component
@Slf4j
public class MyFilter implements Ordered, GlobalFilter {
    /**
     * @param exchange 可以拿到对应的request和response
     * @param chain 过滤器链
     * @return 是否放行
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        log.info("*************MyFilter:"+new Date());
        if(username == null){
            log.info("**********用户名为null,非法用户,请求被拒绝!");
            //如果username为空,返回状态码为406,不可接受的请求
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 加载过滤器的顺序
     * @return 整数,数字越小优先级越高
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/962.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重构·改善既有代码的设计.04之重构手法(下)完结

1. 前言 本文是代码重构系列的最后一篇啦。前面三篇《重构改善既有代码的设计.01之入门基础》、《重构改善既有代码的设计.02之代码的“坏味道”》、《重构改善既有代码的设计.03之重构手法&#xff08;上&#xff09;》介绍了基础入门&#xff0c;代码异味&#xff0c;还有部…

【Java】你真的懂封装吗?一文读懂封装-----建议收藏

博主简介&#xff1a;努力学习的预备程序媛一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: Java岛冒险记【从小白到大佬之路】 前言 write in the front: 如何理解封装&#xff1f; 试想&#xff1a;我们使用微波炉的时候&#xff0c;只用设置好时间&#xff0c;按下“开始”…

[C++]反向迭代器

目录 前言&#xff1a; 1 对反向迭代器的构造思想 2 实现反向迭代器 3 完整代码 前言&#xff1a; 本篇文章主要介绍了STL容器当中的反向迭代器&#xff0c;可能有朋友会说&#xff1a;“反向迭代器有什么好学的&#xff1f;不一样还是迭代器吗&#xff0c;我正向能写出来&…

【js逆向】hook大全

▒ 目录 ▒&#x1f6eb; 导读需求1️⃣ 普通函数2️⃣ 对象方法&#xff08;Class.prototype&#xff09;3️⃣ 对象属性&#xff08;Object.defineProperty&#xff09;4️⃣ Proxy5️⃣ 批量hook示例&#x1f6ec; 文章小结&#x1f4d6; 参考资料&#x1f6eb; 导读 需求 …

【面试题系列】K8S常见面试题

目录 序言 问题 1. 简单说一下k8s集群内外网络如何互通的吧 2.描述一下pod的创建过程 3. 描述一下k8s pod的终止过程 4.Kubernetes 中的自动伸缩有哪些方式&#xff1f; 5.Kubernetes 中的故障检测有哪些方式&#xff1f; 6.Kubernetes 中的资源调度有哪些方式&#xff…

如何优雅的用POI导入Excel文件

在企业级项目开发中&#xff0c;要经常涉及excel文件和程序之间导入导出的业务要求&#xff0c;那么今天来讲一讲excel文件导入的实现。java实现对excel的操作有很多种方式&#xff0c;例如EasyExcel等&#xff0c;今天我们使用的是POI技术实现excel文件的导入。POI技术简介1.P…

全连接神经网络

目录 1.全连接神经网络简介 2.MLP分类模型 2.1 数据准备与探索 2.2 搭建网络并可视化 2.3 使用未预处理的数据训练模型 2.4 使用预处理后的数据进行模型训练 3. MLP回归模型 3.1 数据准备 3.2 搭建回归预测网络 1.全连接神经网络简介 全连接神经网络(Multi-Layer Percep…

基于Vue3和element-plus实现一个完整的登录功能

先看一下最终要实现的效果:登录页面:注册页面:(1)引入element-plus组件库引入组件库的方式有好多种,在这里我就在main.js全局引入了.npm i element-plus -Smain.js中代码:import { createApp } from "vue"; //element-plus import ElementPlus from "element-pl…

双指针 -876. 链表的中间结点-leetcode

开始一个专栏&#xff0c;写自己的博客 双指针&#xff0c;也算是作为自己的笔记吧&#xff01; 双指针从广义上来说&#xff0c;是指用两个变量在线性结构上遍历而解决的问题。狭义上说&#xff0c; 对于数组&#xff0c;指两个变量在数组上相向移动解决的问题&#xff1b;对…

「SAP ABAP」OPEN SQL(四)【FROM语句】

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

女子举重问题

一、问题的描述 问题及要求 1、搜集各个级别世界女子举重比赛的实际数据。分别建立女子举重比赛总成绩的线性模型、幂函数模型、幂函数改进模型&#xff0c;并最终建立总冠军评选模型。 应用以上模型对最近举行的一届奥运会女子举重比赛总成绩进行排名&#xff0c;并对模型及…

【2023-03-10】JS逆向之美团滑块

提示&#xff1a;文章仅供参考&#xff0c;禁止用于非法途径 前言 目标网站:aHR0cHM6Ly9wYXNzcG9ydC5tZWl0dWFuLmNvbS9hY2NvdW50L3VuaXRpdmVsb2dpbg 页面分析 接口流程 1.https://passport.meituan.com/account/unitivelogin主页接口&#xff1a;需获取下面的参数&#xff0…

力扣刷题---初始链表1

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解初始数据结构链表的三个力扣题 1.移除链表元素. 2.反转…

Visual Studio Code 1.76 发布

欢迎使用 Visual Studio Code 2023 年 2 月版&#xff0c;其中一些亮点包括&#xff1a; 配置文件 - 活动配置文件徽章&#xff0c;通过命令面板快速切换配置文件。辅助功能改进 - 新的音频提示&#xff0c;改进的终端屏幕阅读器模式。可移动的 Explorer 视图- 将资源管理器放…

JavaWeb——Request(请求)和Response(响应)介绍

在写servlet时需要实现5个方法&#xff0c;在一个service方法里面有两个参数request和response。 浏览器向服务器发送请求会发送HTTP的请求数据——字符串&#xff0c;这些字符串会被Tomcat所解析&#xff0c;然后这些请求数据会被放到一个对象(request)里面保存。 相应的Tom…

有图解有案例,我终于把 Condition 的原理讲透彻了

哈喽大家好&#xff0c;我是阿Q&#xff01; 20张图图解ReentrantLock加锁解锁原理文章一发&#xff0c;便引发了大家激烈的讨论&#xff0c;更有小伙伴前来弹窗&#xff1a;平时加解锁都是直接使用Synchronized关键字来实现的&#xff0c;简单好用&#xff0c;为啥还要引用Re…

React面向组件编程(理解与使用+state+props+refs与事件处理)

1 基本理解与使用 函数式组件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…

开发板与ubantu文件传送

接下来的所以实验都通过下面这种方式发送APP文件到开发板运行 目录 1、在ubantu配置 ①在虚拟机上添加一个桥接模式的虚拟网卡 ②设定网卡 ③在网卡上配置静态地址 2、开发板设置 ①查看网卡 ②配置网卡静态ip 3、 测试 ①ping ②文件传送 传送报错情况 配置环境&#…

Java Web 实战 14 - 计算机网络之初识计算机网络

初识计算机网络一 . 网络发展史二 . 局域网 VS 广域网2.1 交换机与路由器2.2 集线器三 . 网络通信基础3.1 协议3.1.1 OSI 七层模型3.1.2 TCP / IP 五层模型3.2 交换机和路由器的区别3.3 封装和分用大家好 , 这篇文章给大家分享的是计算机网络的一些基础知识 , 我们会给大家分享…

钉钉,下沉进农田

在这个古老的产业里&#xff0c;数字化没有被放到更高的位置&#xff0c;但难点依旧存在。钉钉恰是基于它足够柔性的产品特性和普惠的服务模式&#xff0c;真正帮助农食产业中的人和企业解决着过去一直没有解决的问题&#xff0c;让这个产业中的人和环节都向数字化潮水迈进了一…