SpringCloud03

news2024/11/15 23:27:43

一、网关

网关:就是网络的关口,负责请求的路由,转发,身份校验。

在SpringCloud中网关的实现:

SpringCloud Gateway

由SpringCloud官方出品

基于WebFlux响应式编程

无需调优即可获得优异性能

(1)网关路由

配置路由规则

spring:
  cloud:
    gateway:
      routes: 
        - id: item # 路由规则id,自定义,唯一
          uri: lb://item-service # 路由目标微服务,lb代表负载均衡
          predicates: # 路由断言,判断请求是否符合规则,符合则路由到目标
            - Path=/items/** # 以请求路径做判断,以/items开头则符合
        - id: xx
          uri: lb://xx-service
          predicates:
            - Path=/xx/**

①快速入门:

创建一个新的模块,引入网关的依赖,编写启动类,配置路由规则。

②路由属性

网关路由对应的java类型是RouteDefinition,其中常见的属性有:

id:路由唯一标识

uri:路由目标地址

predicates:路由断言,判断请求是否符合当前路由

filters:路由过滤器,对请求或响应做特殊处理

路由断言: 

路由过滤器:

(2)网关登录校验

ctrl+H 查看该类的实现类

网关过滤器有两种,分别是:

GatewayFilter:路由过滤器作用于任意指定的路由,默认不生效,要配置到路由后生效。

GlobalFilter:全局过滤器,作用范围是所有路由,声明后自动生效。

①自定义全局过滤器

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        获取请求
        ServerHttpRequest request = exchange.getRequest();
        
        HttpHeaders headers = request.getHeaders();
        System.out.println("headers"+headers);
//        放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
//        过滤器执行顺序,值越小,优先级越高
        return 0;
    }
}

②自定义过滤器GatewayFilter

自定义GatewayFilter不是直接实现GatewayFilter,而是实现AbstractGatewayFilterFactory


@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {

    @Override
    public GatewayFilter apply(Object config) {
        return new OrderedGatewayFilter(new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println("print any filter running");
                return chain.filter(exchange);
            }
        },1);
    }
  }
}

③实现登录校验

@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    private final AuthProperties authProperties;
    private final JwtTool jwtTool;
    private final AntPathMatcher antPathMatcher=new AntPathMatcher();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        1.获取request
        ServerHttpRequest request = exchange.getRequest();
//        2.判断是否需要做登录拦截
        if (isExclude(request.getPath().toString())){
//            放行
            return chain.filter(exchange);
        }
//        3.获取token
        String token =null;
        List<String> headers = request.getHeaders().get("authorization");
        if (headers!=null&&!headers.isEmpty()){
            token=headers.get(0);
        }
//        4.校验并解析token
        Long userId=null;
        try{
            userId = jwtTool.parseToken(token);
        }catch(UnauthorizedException e){
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
//        TODO 5.传递用户信息
        System.out.println("userId"+userId);
//        6.放行
        return chain.filter(exchange);    }

    private boolean isExclude(String path) {
    for (String pathPattern :authProperties.getExcludePaths()){
        if (antPathMatcher.match(pathPattern,path)){
            return true;
        }
    }
    return false;
    }

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

④网关传递用户信息

一、在网关的登录校验过滤器中,把获取到的用户写入请求头

需求:修改gateway模块中的登录校验拦截器,在校验成功后保存用户到下游请求的请求头中。 提示:要修改转发到微服务的请求,需要用到ServerWebExchange类提供的API,示例如下:

//        5.传递用户信息
        String userInfo = userId.toString();
        ServerWebExchange swe = exchange.mutate().request(builder -> builder.header("userinfo", userInfo)).build();

从网关那里获取用户信息,通过过滤器做拦截,获取修改请求头,定义一个通用的拦截器,

二、在hm-common中编写SpringMVC拦截器,获取登录用户

需求:由于每个微服务都可能有获取登录用户的需求,因此我们直接在hm-common模块定义拦截器,这样微服务只需要引入依赖即可生效,无需重复编写。

@Component
public class UserInfoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//      获取用户登陆信息
        String userinfo = request.getHeader("userinfo");
//      判断是否获取了用户,如果有,存入ThreadLocal
if (StrUtil.isNotBlank(userinfo)){
    UserContext.setUser(Long.valueOf(userinfo));

}
//        放行
return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserContext.removeUser();
    }
}
@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInfoInterceptor());
    }
}

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.hmall.common.config.MyBatisConfig,\
  com.hmall.common.config.MvcConfig,\
  com.hmall.common.config.JsonConfig

⑤OpenFeign传递用户(微服务之间的相互调用)

微服务项目中的很多业务要多个微服务共同合作完成,而这个过程中也需要传递登录用户信息。

OpenFeign中提供了一个拦截器接口,所有由OpenFeign发起的请求都会先调用拦截器处理请求

    @Bean
    public RequestInterceptor userInfoRequestInterceptor(){
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                Long userId = UserContext.getUser();
                if (userId!=null){
                RequestTemplate userinfo = template.header("userinfo", userId.toString());}
            }
        };
    }

(3)配置管理

①配置共享

i.添加一些通用配置到Nacos中,包括:Jdbc、MybatisPlus、日志、Swagger、OpenFeign等配置

ii.拉取共享配置

基于NacosConfig拉取共享配置代替微服务的本地配置

引入依赖

<!--nacos配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--读取bootstrap文件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

新建bootstrap.yaml

spring:
  application:
    name: cart-service #微服务名称
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: 1.12.232.19:8848 #nacos地址
      config:
        file-extension: yaml #文件后缀名
        shared-configs:
          - data-id: shared-jdbc.yaml
          - data-id: shared-log.yaml
          - data-id: shared-swagger.yaml

②配置热更新

配置热更新:当修改配置文件中的配置时,微服务无需重启即可使配置生效。

前提条件:nacos中要有一个与微服务名有关的配置文件。

微服务中要以特定方式读取需要热更新的配置属性

@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {
    private Integer maxItems;
}

③动态路由

如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。

  • 创建ConfigService,目的是连接到Nacos

  • 添加配置监听器,编写配置变更的通知处理逻辑

在网关中引入依赖

<!--统一配置管理-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--加载bootstrap-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

然后在网关gatewayresources目录创建bootstrap.yaml文件,内容如下

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 192.168.150.101
      config:
        file-extension: yaml
        shared-configs:
          - dataId: shared-log.yaml # 共享日志配置

接着,修改gatewayresources目录下的application.yml,把之前的路由移除

server:
  port: 8080
hm:
  jwt:
    location: classpath:hmall.jks
    alias: hmall
    password: hmall123
    tokenTTL: 30m
  auth:
    excludePaths:
      - /search/**
      - /users/login
      - /items/**
      - /hi

然后,在gateway中定义配置监听器

接下来,我们直接在Nacos控制台添加路由,路由文件名为gateway-routes.json,类型为json

[
    {
        "id": "item",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"}
        }],
        "filters": [],
        "uri": "lb://item-service"
    },
    {
        "id": "cart",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/carts/**"}
        }],
        "filters": [],
        "uri": "lb://cart-service"
    },
    {
        "id": "user",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/users/**", "_genkey_1":"/addresses/**"}
        }],
        "filters": [],
        "uri": "lb://user-service"
    },
    {
        "id": "trade",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/orders/**"}
        }],
        "filters": [],
        "uri": "lb://trade-service"
    },
    {
        "id": "pay",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/pay-orders/**"}
        }],
        "filters": [],
        "uri": "lb://pay-service"
    }
]

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

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

相关文章

评估分类机器学习模型的指标

欢迎来到雲闪世界。一旦我们训练了一个监督机器学习模型来解决分类问题&#xff0c;如果这就是我们工作的结束&#xff0c;我们会很高兴&#xff0c;我们可以直接向他们输入新数据。我们希望它能正确地对所有内容进行分类。然而&#xff0c;实际上&#xff0c;模型做出的预测并…

Linux--应用层协议HTTP

HTTP协议 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最为广泛的一种网络协议&#xff0c;它基于TCP/IP通信协议来传送数据&#xff0c;规定了浏览器与服务器之间数据传输的规则&#xff0c;确保数据能够在网络源头…

C# Unity 面向对象补全计划 之 画UML类图(持续更新)

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列旨在通过补全学习之后&#xff0c;给出任意类图都能实现并做到逻辑上严丝合缝 学会这套规则&#xff0c;并看完面向对象补全计划文章之后&#xff0c;可以尝试…

Linux---进程(3)---进程状态

目录 进程排队 进程状态 运行状态 阻塞状态 挂起状态 Linux内核具体进程状态 浅度睡眠状态 运行状态 深度睡眠状态 暂停状态 可被追踪的暂停状态 终止状态 僵尸状态 进程排队 进程不是一直在运行的&#xff0c;进程放在了CPU上&#xff0c;也不是一直运行的。 进程…

C++|设计模式(七)|⭐️观察者模式与发布/订阅模式,你分得清楚吗

本文内容来源于B站&#xff1a; 【「观察者模式」与「发布/订阅模式」&#xff0c;你分得清楚吗&#xff1f;】 文章目录 观察者模式&#xff08;Observer Pattern&#xff09;的代码优化观察者模式 与 发布订阅模式 他们是一样的吗&#xff1f;发布订阅模式总结 我们想象这样一…

深度学习 —— 个人学习笔记8(层和块、参数管理、自定义层及读写文件)

声明 本文章为个人学习使用&#xff0c;版面观感若有不适请谅解&#xff0c;文中知识仅代表个人观点&#xff0c;若出现错误&#xff0c;欢迎各位批评指正。 十五、层和块 nn.Sequential()   nn.Sequential() 是一个序列容器&#xff0c;用于搭建神经网络的模块按照被传入构…

6-1 从全连接层到卷积

我们之前讨论的多层感知机十分适合处理表格数据&#xff0c;其中行对应样本&#xff0c;列对应特征。 对于表格数据&#xff0c;我们寻找的模式可能涉及特征之间的交互&#xff0c;但是我们不能预先假设任何与特征交互相关的先验结构。 此时&#xff0c;多层感知机可能是最好的…

程序员面试题------N皇后问题算法实现

N皇后问题是一个著名的计算机科学问题&#xff0c;它要求在NN的棋盘上放置N个皇后&#xff0c;使得它们之间不能相互攻击&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。这个问题可以看作是一个回溯算法问题&#xff0c;通过逐步尝试不同的放置位置&#xf…

手持气象设备:掌握天气的便捷伙伴

在这个快速变化的时代&#xff0c;手持气象设备成为了我们日常生活中重要的小帮手。它小巧轻便&#xff0c;易于携带&#xff0c;让我们随时随地都能掌握天气变化&#xff0c;为出行、户外活动提供准确参考。 手持气象设备内置了高精度传感器&#xff0c;能够迅速感知并显示当前…

PCB学习

教你怎么检查电路原理图_原理图检视主要内容-CSDN博客https://blog.csdn.net/chenhuanqiangnihao/article/details/113664734

继全球蓝屏后,微软 Azure 云服务因安全错误导致全球宕机

7月30日&#xff0c;微软Azure云服务全球宕机约8小时。该事件由一次DDoS攻击引起&#xff0c;成功触发系统保护机制&#xff0c;但这些防御机制中的实施错误反而进一步放大了影响&#xff0c;最终造成一次大宕机事件。据英国广播公司报道&#xff0c;此次中断持续了大约 10 个小…

5步教你学会古诗词生成AI绘画

本文由 ChatMoney团队出品 首先&#xff0c;打开时下最热门的两个AI工具&#xff0c;mj和chatgpt这两个都是我们在创作AI古诗词绘画中一定要用到的&#xff0c;这里我用的是chatmoneyAI系统 第一步&#xff1a;我们要先使用ChatGPT来生成我们所想要展示古诗的关键词。那么我们…

代码随想录算法训练营第二十一天| 39. 组合总和, 40.组合总和II, 131.分割回文串

今天是回溯算法学习的第二天&#xff0c;主要的学习内容包括&#xff1a;1.组合问题的重复使用 2.组合问题的去重 3.分割问题的处理方法。 39. 组合总和 题目链接&#xff1a;39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 这个组合问题的特点是&#xff0c;集合内的…

Java:基于TextRank算法的自动摘要(自动生成事件摘要)

TextRank 是一种用于文本摘要的自然语言处理算法。它的工作原理类似于 Google 搜索引擎的 PageRank 算法&#xff0c;即根据文本中每个单词出现的频率和被引用的次数来评估它的重要性。 所谓自动摘要&#xff0c;就是从文章中自动抽取关键句。何谓关键句&#xff1f;人类的理解…

最好用的复制粘贴软件pastemate功能简介

这应当是windows下最好用的复制粘贴软件&#xff0c;遥遥领先的复制粘贴软件。 效增PasteMate - 下载页面 windows下界面最优美&#xff0c;操作最方便的复制粘贴神器&#xff0c;学生党论文必备&#xff0c;效率神器 pastemate 1.搜索功能&#xff0c;能够按文本、图片、文件…

C# 构建观测者模式(或者为订阅者模型)

前言&#xff1a; 观测者模型的基本理念&#xff0c;就是&#xff0c;我有一个公共的事件&#xff0c;定义好他的事件的触发、数据接口。然后&#xff0c;通过增加订阅者&#xff08;实例&#xff09;来订阅这个事件的&#xff0c;或者说观察这个事件。如果事件发生&#xff0…

软件测试的挑战和压力

软件测试过程中可能会遇到很多挑战&#xff0c;比如&#xff1a; 1. 需求不明确或不稳定。如果需求文档不完整、不清晰或不一致&#xff0c;或者需求在开发过程中频繁变更&#xff0c;那么测试人员就很难设计和执行有效的测试用例&#xff0c;也很难判断测试结果是否符合预期。…

5年经验的软件测试人员,碰到这样的面试题居然会心虚......

我们这边最近的面试机会比较多&#xff0c;但是根据他们的反馈&#xff0c;结束后大部分都没音信了&#xff0c;因为现在企业面试问的非常多&#xff0c;范围非常广&#xff0c;而且开放性的问题很多&#xff0c;很多人即便面试前刷了成百上千道面试题&#xff0c;也很难碰到一…

C语言——指针数组

文章目录 &#x1f34a;自我介绍&#x1f34a;前言&#x1f34a;含义&#x1f34a;输出指针数组中的值&#x1f34a;指针数组工程的用法&#xff08;模拟linux的内核代码&#xff09; 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&…

实习中学到的一点计算机知识(MP4在企业微信打不开?)

我在实习中&#xff0c;常有同事向我反馈说我在微信发的视频格式打不开。这就导致我还要一帧帧的盯着某一个时刻来截图&#xff0c;今天查了一下资料尝试修改视频后缀来解决视频的播放问题。 在网上下载mp4的格式&#xff0c;在本地都能播放&#xff0c;怎么可能发上企业微信就…