SpringCloud案例day05

news2024/9/20 20:29:03

SpringCloud Gateway网关

案例1:环境搭建

可以复制 Service-A9001 改成Gateway-C9009
》1:创建工程导入依赖

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

注意

SpringCloud Gateway使用的web框架为webflux,和SpringMVC不兼容,需要从工程的pom.xml中删除 web框架,在需要web框架的模块中添加

》2:配置启动类

package com.dev1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

》3:编写配置文件

server:
  port: 9009
spring:
  application:
    name: Gateway-C9009
  cloud:
    gateway:
      routes:
        - id: route1
          uri: http://127.0.0.1:9001
          predicates:
            - Path=/person/**
#        - id: route2
#          uri: http://127.0.0.1:9002
#          predicates:
#            - Path=/order-service/**

(1)id :我们自定义的路由 ID,保持唯一
(2)uri :目标服务地址
(3)predicates :路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默
认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
(4)filters :过滤规则,暂时没用

上面这段配置的意思是,配置了一个 id 为 persson-service的路由规则,当访问网关请求地址person 开头时,会自动转发到地址: http://127.0.0.1:9001/ 。

配置完成启动项目即可在浏览器访问进行测试,当我们访问地址 http://localhost:9009/person/find/2 时会展示页面展示如下

在这里插入图片描述

案例2:路由规则

在 Spring Cloud Gateway 中 Spring 利用Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件
匹配到对应的路由

#路由断言之后匹配
spring:
cloud:
 gateway:
  routes:
  - id: after_route
   uri: https://xxxx.com
    #路由断言之前匹配
   predicates:
   - After=xxxxx
#路由断言之前匹配
spring:
cloud:
 gateway:
  routes:
  - id: before_route
   uri: https://xxxxxx.com
   predicates:
   - Before=xxxxxxx
#路由断言之间
spring:
cloud:
 gateway:
  routes:
  - id: between_route
   uri: https://xxxx.com
   predicates:
   - Between=xxxx,xxxx
#路由断言Cookie匹配,此predicate匹配给定名称(chocolate)和正则表达式(ch.p)
spring:
cloud:
 gateway:
  routes:
  - id: cookie_route
   uri: https://xxxx.com
   predicates:
   - Cookie=chocolate, ch.p
#路由断言Header匹配,header名称匹配X-Request-Id,且正则表达式匹配\d+
spring:
cloud:
 gateway:
  routes:
  - id: header_route
   uri: https://xxxx.com
   predicates:
   - Header=X-Request-Id, \d+
#路由断言匹配Host匹配,匹配下面Host主机列表,**代表可变参数
spring:
cloud:
 gateway:
  routes:
  - id: host_route
   uri: https://xxxx.com
   predicates:
   - Host=**.somehost.org,**.anotherhost.org
#路由断言Method匹配,匹配的是请求的HTTP方法
spring:
cloud:
 gateway:
  routes:
  - id: method_route
   uri: https://xxxx.com
   predicates:
   - Method=GET
#路由断言匹配,{segment}为可变参数
spring:
cloud:
 gateway:
  routes:
  - id: host_route
   uri: https://xxxx.com
   predicates:
   - Path=/foo/{segment},/bar/{segment}
#路由断言Query匹配,将请求的参数param(baz)进行匹配,也可以进行regexp正则表达式匹配 (参数包含
foo,并且foo的值匹配ba.)
spring:
cloud:
 gateway:
  routes:
  - id: query_route
   uri: https://xxxx.com
   predicates:
   - Query=baz 或 Query=foo,ba.
   
#路由断言RemoteAddr匹配,将匹配192.168.1.1~192.168.1.254之间的ip地址,其中24为子网掩码位
数即255.255.255.0 
spring:
cloud:
 gateway:
  routes:
  - id: remoteaddr_route
   uri: https://example.org
   predicates:
   - RemoteAddr=192.168.1.1/24

案例3:动态路由

和zuul网关类似,在SpringCloud GateWay中也支持动态路由:即自动的从注册中心中获取服务列表并
访问。
(1)添加注册中心依赖
在工程的pom文件中添加注册中心的客户端依赖(这里以Eureka为例)

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

( 2)配置动态路由
修改 application.yml 配置文件,添加eureka注册中心的相关配置,并修改访问映射的URL为服务名称

server:
  port: 9009
spring:
  application:
    name: Gateway-C9009
  cloud:
    gateway:
      routes:
      - id: person-service
        uri: lb://Service-A9001
        predicates:
        - Path=/person/**
eureka:
  instance:
    prefer-ip-address: true #使用ip地址注册
    instance-id:  ${spring.cloud.client.ip-address}:${server.port} #向注册中心中注册服务id
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/,http://localhost:8000/eureka/

uri : uri以 lb: //开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称

测试

http://localhost:9009/person/find

案例3:重写转发路径

在这里插入图片描述

在SpringCloud Gateway中,修改Path为/person-service/**

# http://127.0.0.1:9009/person-service/person/find/1 转发到
# http://127.0.0.1:9001/person-service/person/find/1
但后者不存在,只有

# http://127.0.0.1:9001/person/find/1 可以访问

(1)修改配置文件
修改 application.yml ,将匹配路径改为 /person-service/**

重新启动网关,我们在浏览器访问

http://127.0.0.1:9009/person-service/person/find/1

会抛出404。这是由于路由转发规则默认转发到

http://127.0.0.1:9001/person-service/person/find/1

(2) 添加RewritePath重写转发路径
修改 application.yml ,添加重写规则。

server:
  port: 9009
spring:
  application:
    name: Gateway-C9009
  cloud:
    gateway:
      routes:
      - id: service-1 #编号唯一
        uri: lb://Service-A9001
        predicates:
        - Path=/person-service/**
        filters:
        - RewritePath=/person-service/(?<segment>.*), /$\{segment}

路径变化如下

http://127.0.0.1:9009/person-service/person/find/1 转发到
http://127.0.0.1:9001/person/find/1 可以访问

案例4:微服务名称转发

http://localhost:9009/service-a9001/person/find/1 转发到
http://127.0.0.1:9001/person/find/1 可以访问

配置如下

server:
  port: 9009
spring:
  application:
    name: Gateway-C9009
  cloud:
    gateway:
      routes:
      - id: service-1 #编号唯一
        uri: lb://Service-A9001
        predicates:
        - Path=/person-service/**
        filters:
        - RewritePath=/person-service/(?<segment>.*), /$\{segment}
      discovery:
        locator:
          lower-case-service-id: true
          enabled: true

案例5:全局过滤器搭建

》1:自定义一个全局过滤器,实现 globalfilter , ordered接口

@Component
public class LoginFilter implements GlobalFilter,Ordered {

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("执行了自定义的全局过滤器");
        return chain.filter(exchange); //继续向下执行
    }

    /**
     * 指定过滤器的执行顺序 , 返回值越小,执行优先级越高
     */
    public int getOrder() {
        return 0;
    }
}

》2:访问测试

http://localhost:9009/service-a9001/person/find/1

案例6:鉴权中心

(1)自定义全局过滤器需要实现 GlobalFilter和Ordered接口。
(2)在 filter方法中完成过滤器的逻辑判断处理
(3)在 getOrder方法指定此过滤器的优先级,返回值越大级别越低
(4)ServerWebExchange 就相当于当前请求和响应的上下文,存放着重要的请求-响应属性、请求实例和响应实例等等。一个请求中的request,response都可以通过 ServerWebExchange 获取
(5)调用 chain.filter 继续向下游执行

/**
 * 自定义一个全局过滤器
 *      实现 globalfilter , ordered接口
 */
@Component
public class LoginFilter implements GlobalFilter,Ordered {

    /**
     * 执行过滤器中的业务逻辑
     *     对请求参数中的access-token进行判断
     *      如果存在此参数:代表已经认证成功
     *      如果不存在此参数 : 认证失败.
     *  ServerWebExchange : 相当于请求和响应的上下文(zuul中的RequestContext)
     */
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("执行了自定义的全局过滤器");
        //1.获取请求参数access-token
        String token = exchange.getRequest().getQueryParams().getFirst("access-token");
        //2.判断是否存在
        if(token == null) {
            //3.如果不存在 : 认证失败
            System.out.println("没有登录");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete(); //请求结束
        }
        //4.如果存在,继续执行
        return chain.filter(exchange); //继续向下执行
    }

    /**
     * 指定过滤器的执行顺序 , 返回值越小,执行优先级越高
     */
    public int getOrder() {
        return 0;
    }
}

测试

http://localhost:9009/service-a9001/person/find/1?access-token=abc
http://localhost:9009/service-a9001/person/find/1

案例7:网关限流(Filter)

SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂RequestRateLimiterGatewayFilterFactory 实现。在过滤器工厂中是通过Redis和lua脚本结合的方式进行流量控制。

》1:准备redis服务器
Redis-x64-4.0.2.3.zip
redisclient-客户端工具.zip

在这里插入图片描述

打开监控
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S8bV6Ayv-1668667456838)(index_files/0cd2f043-5763-4fd2-bfd7-40042988f566.png)]
》2:导入 redis的依赖
首先在工程的pom文件中引入gateway的起步依赖和redis的reactive依赖,代码如下:

  <!--监控依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--redis的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

》3:修改application.yml配置文件

server:
  port: 9009
spring:
  application:
    name: Gateway-C9009
  redis:
    host: localhost
    pool: 6379
    database: 0
  cloud:
    gateway:
      routes:
      - id: service-1 #编号唯一
        uri: lb://Service-A9001
        predicates:
        - Path=/person-service/**
        filters:
        - name: RequestRateLimiter
          args:
            # 使用SpEL从容器中获取对象
            key-resolver: '#{@pathKeyResolver}'
            # 令牌桶每秒填充平均速率
            redis-rate-limiter.replenishRate: 1
            # 令牌桶的上限
            redis-rate-limiter.burstCapacity: 3
        - RewritePath=/person-service/(?<segment>.*), /$\{segment}

在 application.yml 中添加了redis的信息,并配置了RequestRateLimiter的限流过滤器:
burstCapacity ,令牌桶总容量。
replenishRate ,令牌桶每秒填充平均速率。
key-resolver ,用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

》4: 配置KeyResolver
为了达到不同的限流效果和规则,可以通过实现 KeyResolver 接口,定义不同请求类型的限流键。

package com.dev1;

@Configuration
public class KeyResolverConfiguration {

    /**
     * 编写基于请求路径的限流规则
     * //abc
     * //基于请求ip 127.0.0.1
     * //基于参数
     */
    @Bean
    public KeyResolver pathKeyResolver() {
        //自定义的KeyResolver
        return new KeyResolver() {
            /**
             * ServerWebExchange :
             *      上下文参数
             */
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getPath().toString());
            }
        };
    }
}

测试的时候使用以下地址不停刷新

http://localhost:9009/person-service/person/find/1?access-token=abc

不要使用

http://localhost:9009/service-a9001/person/find/1?access-token=abc

》5:基于请求参数或者ip限流的配置

增加

package com.dev1;


@Configuration
public class KeyResolver2Configuration {

    /**
     * 基于请求参数的限流
     *  请求 abc ? userId=1
     */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest().getQueryParams().getFirst("userId")
                //exchange.getRequest().getHeaders().getFirst("X-Forwarded-For") 基于请求ip的限流
        );
    }
}

修改

key-resolver: '#{@userKeyResolver}'

在这里插入图片描述

大括号中就是我们的限流 Key,这边是IP,本地的就是localhost
timestamp: 存储的是当前时间的秒数,也就是System.currentTimeMillis() / 1000或者
Instant.now().getEpochSecond()
tokens: 存储的是当前这秒钟的对应的可用的令牌数量

Spring Cloud Gateway目前提供的限流还是相对比较简单的,在实际中我们的限流策略会有很多种情况,比如:
对不同接口的限流
被限流后的友好提示
这些可以通过自定义RedisRateLimiter来实现自己的限流策略,这里我们不做讨论

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汽车全景视频制作让企业营销传播无界长久

全景视频制作 全景VR视频&#xff0c;顾名思义就是能够使我们看到拍摄点周围360景致的视频。传统视频拍摄受限于镜头视角&#xff0c;所以我们只能看到镜头前方180内的景物。而全景VR视频能够看到周围360以及上下180各个角度的一切景物&#xff0c;用户能够更加多方位的观赏视频…

可观测性-Event-指标事件采样策略总结

文章目录前言采样的几种策略简单随机采样周期性完整采样基于条件的采样前言 在默认情况下&#xff0c;系统会采集所有追踪&#xff08;Tracing&#xff09;的数据。但是如果系统比较复杂&#xff0c;采集的端点比较多的时候&#xff0c;对存储压力比较大&#xff0c;这个时候我…

Educational Codeforces Round 135 (Rated for Div. 2)

A:思维 题意&#xff1a;箱子里有N个颜色的球&#xff08;用下标代表不同的颜色&#xff09;&#xff0c;每个颜色的球对应一定的数量&#xff0c;你会进行多次拿球的操作&#xff0c;当箱子里的球颜色一致时&#xff0c;你就不能再拿球了&#xff0c;问最后颜色一致的球是哪个…

免疫抑制作用的转录抑制分子

科研人员发现&#xff1a;社交失败导致了小鼠焦虑行为&#xff0c;进而抑制了化疗药物的治疗过程&#xff0c;加速了肿瘤的发展。在正常小鼠中&#xff0c;人为给予外源性糖皮质激素会使得 Tsc22d3(一个具有很强免疫抑制作用的转录抑制分子)在肿瘤浸润树突细胞(TIDC)的表达上调…

Q3营收同比翻三倍,踩猛“油门”零跑必将领跑?

近日&#xff0c;零跑汽车公布三季度财报。从财报成绩来看&#xff0c;有喜有忧。喜的是销量营收同比环比均出现大幅度增长&#xff0c;忧的是亏损同比扩大86.11%。 营收同比猛增398.5%&#xff0c;销量能否穿越迷雾&#xff1f; 详细来看&#xff0c;三季度零跑汽车销量3.56万…

【附源码】计算机毕业设计JAVA旅行指南网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…

HOOPS学习笔记

Hoops简介 HOOPS Visualize由一套集成的组件组成&#xff0c;可快速开发高性能设计、可视化和工程应用程序。HOOPS 3DF在每个组件中保持平台独立性&#xff0c;在Windows、Linux和Mac OS X上提供跨平台解决方案。 HOOPS Visualize包含如下组件&#xff1a; 1.HOOPS/3dGS - HO…

vue+express+mysql+elementUI实现前后端交互增删改查

简介&#xff1a;使用 Vue koa koa2-router mySql elementUI实现前后端交互 页面整体效果图&#xff1a; 编辑页面&#xff1a; 添加页面&#xff1a; 删除操作&#xff1a; 数据库客户端使用Navicat for mysql 当然你需要下载安装 在数据库新建 stuInfo 表和表结构 st…

Github点赞接近 100k 的Spring Boot学习教程+实战项目推荐

很明显的一个现象&#xff0c;除了一些老项目&#xff0c;现在 Java 后端项目基本都是基于 Spring Boot 进行开发&#xff0c;毕竟它这么好用以及天然微服务友好。不夸张的说&#xff0c;Spring Boot 是 Java 后端领域最最最重要的技术之一&#xff0c;熟练掌握它对于 Java 程序…

SpringBoot-快速入门

目录 SpringBoot 概念 Spring缺点 SpringBoot 功能 快速入门案例&#xff1a;需求 案例&#xff1a;实现步骤 示例 小结 快速构建SpringBoot工程 SpringBoot 概念 SpringBoot提供了一种快速使用Spring的方式基于约定优于配置的思想&#xff0c;可以让开发人员不必在配置…

QML地图Map中使用QPainterPath,并显示任意点经纬度位置

QML地图Map中提供了供绘制图形的组件&#xff0c;例如MapPolyline&#xff0c;MapCircle等&#xff0c;但是这些组件在绘制复杂轨迹时就显得功能不够全面&#xff0c;因此我将QPainterPath在Map中进行使用并进行绘制&#xff0c;并使用C和Qml中的函数进行相互调用计算获取点屏幕…

macOS 的「预览」有几种用法

如果要评选 macOS 最低调的 App &#xff0c;「预览」可能就会位列其中之一。「预览」和 macOS 结合异常紧密&#xff0c;甚至让人都会遗忘它还是个 App。毕竟大多数的时候&#xff0c;提到「预览」就会想到操作系统的一部分。而实际上&#xff0c;「预览」那「瘦小」的身躯之内…

Unity3D赛车游戏+脚本基础

前言 游戏对象实例化 Scenes游戏场景 GameObject游戏对象 Component组件 Component使用方法 预制体 Unity事件函数 Instantiate():实例化对象 什么是Time.deltaTime Transform的移动&#xff0c;旋转和缩放 实战:赛车游戏 运行演示 具体步骤 游戏打包流程 前言 …

智慧教育解决方案-最新全套文件

智慧教育解决方案-最新全套文件一、建设背景二、思路架构三、建设方案四、获取 - 智慧教育全套最新解决方案合集一、建设背景 目前数字化校园现状&#xff1a; 各自为政 分散建设 各个学校组成的业务系统、网站五花八门&#xff0c;形式多样。形式单一 功能简单 学校网站主要…

为什么同一表情‘‘.length==5但‘‘.length==4?本文带你深入理解 String Unicode UTF8 UTF16

背景 为什么同样是男人&#xff0c;但有的男人&#x1f9d4;‍♂️.length 5&#xff0c;有的男人&#x1f9d4;‍♂.length 4呢&#xff1f; 这二者都是JS中的字符串&#xff0c;要理解本质原因&#xff0c;你需要明白JS中字符串的本质&#xff0c;你需要理解 String Unic…

vlan trunk stp攻防

目录 一、VLAN、Trunk面临的安全风险 trunk干道攻击DTP攻击&#xff08;思科特有&#xff09; VLAN跳跃攻击 STP根桥攻击 二、攻击防护 一、VLAN、Trunk面临的安全风险 trunk干道攻击DTP攻击&#xff08;思科特有&#xff09; 在华为设备中trunk链路是手工指定的&#xf…

A-LEVEL Chemistry考点分析

A-LEVEL化学其实不是一门很难的科目&#xff0c;并没有太多的内容&#xff0c;虽说包含十几章的内容但其实每章都是相互关联&#xff0c;一通百通&#xff0c;掌握元素周期表的实质&#xff0c;基本上就没有什么问题了&#xff0c;重在理解&#xff01;知识点多而不碎&#xff…

如何一站式管理固定资产的全生命周期?

目前很多企业还在沿用之前传统的Excel表格来管理和盘点固定资产&#xff0c;不但加大了企业固定资产管理员的工作量&#xff0c;而且在实际的操作过程中容易出现错登记、漏盘点、无法查询操作履历等各种小插曲。而且随着企业固定资产数量、种类、分支机构以及人员的不断增加&am…

juc之常用4大并发工具类 (四)

CountDownLatch: 减少计数CyclicBarrier: 循环栅栏Semaphore: 信号量ExChanger: 交换器 文章目录1.CountDownLatch2.CyclicBarrier3.Semaphore4.Exchanger1.CountDownLatch CountDownLatch,俗称闭锁,作用是类似加强版的 Join,是让一组线程等待其他的线程完成工作以后才执行 就…

数仓开发之DWD层(四)

目录 十一&#xff1a;工具域优惠券领取事务事实表 11.1 主要任务&#xff1a; 11.2 思路分析&#xff1a; 11.3 图解&#xff1a; 十二&#xff1a;工具域优惠券使用&#xff08;下单&#xff09;事务事实表 12.1 主要任务&#xff1a; 12.2 思路分析&#xff1a; 12.3…