微服务-实现nacos的集群和Gateway网关的实现、认证校验、解决跨域

news2024/9/23 23:33:59

1. nacos的集群模式

1.1 分析

nacos在企业中的使用100%都是集群模式。需要掌握nacos集群的搭建

在这里插入图片描述

  1. nacos的数据存放在derby本地磁盘中,nacos集群模式会导致数据库数据不一致,使用加一层思想,修改nacos的数据库,使用mysql数据库,保证数据的一致

  2. 模拟nacos在window中搭建集群。因为在2.0以后,nacos增加理论两个端口,偏移量为1000和1001,所以需要注意端口号

  3. 使用8850【9850,9851】

​ 8860【9860,9861】

​ 8870【9870,9871】

1.2 实现

1. 修改conf/application.properties文件

在这里插入图片描述

2.创建数据库nacos并导入sql语句

在这里插入图片描述

3. 修改cluster.conf.example文件

把该文件命名为cluster.conf并修改里面的内容

#it is ip
#example 注意:把虚拟机的ip关闭
ip:端口号
ip:端口号
ip:端口号

4. 修改bin文件中的startup.cmd配置文件为集群

在这里插入图片描述

nacos中的startup.cmd文件中默认情况下就为集群模式,若使用单机模式的话,就需要将其改为单机模式

5. 在设置中关闭VM网络

在这里插入图片描述

6. 启动三台nacos服务

在这里插入图片描述

7. 微服务连接

在这里插入图片描述

若是在虚拟机中实现,还需要配置nginx的conf文件,配置相应的ip和端口号,但现在是在windows下模拟,nginx支持tcp协议,而windows不支持tcp协议,所以在此通过步骤7模拟

2. Gateway网关

2.1 概述

大家都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端【pc、androud、ios、平板】要如何去调用这么多的微服务呢?

如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。

这样的架构,会存在着诸多的问题

  1. 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
  2. 认证复杂,每个服务都需要独立认证
  3. 存在跨域请求,在一定场景下处理相对复杂。

在这里插入图片描述

网关:所有微服务的入口点

作用:

  1. 路由转发
  2. 认证校验
  3. 跨域统一解决
  4. 黑白名单

2.2 常用的网关组件

  • nginx+lua

使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用 。lua是一种脚本语言,可以来编写一些简单的逻辑, nginx支持lua脚本

  • Kong

基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。 问题:

只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。

  • Zuul 1.0(慢 servlet 2.0)zuul2.0没出来

Netflix开源的网关,功能丰富,使用JAVA开发,易于二次开发 问题:缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如Nginx

  • Spring Cloud Gateway

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

注意:SpringCloud alibaba技术栈中并没有提供自己的网关,我们可以采用Spring Cloud

2.3 概述gateway网关

Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0 和 Project Reactor 等术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

  • 优点
  1. 性能强劲:是第一代网关Zuul的1.6倍
  2. 功能强大:内置了很多实用的功能,例如转发、监控、限流等
  3. 设计优雅,容易扩展
  • 缺点
  1. 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
  2. 不能将其部署在Tomcat、Jetty等Servlet容器里,只能达成jar包执行web.jar
  3. 需要springboot 2.0以及上的版本,才支持

gateway内置了服务器netty服务器,千万不要在使用tomcat作为服务器

2.4 使用gateway网关-转发地址写死

1. 创建网关微服务

在这里插入图片描述

2. 添加依赖

 <dependencies>
        <!--如果引入了gateway的依赖,不能再引用spring-boot-starter-web,否则会报错。因为web内置了tomcat服务器,而gateway内置netty服务器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

如果依赖中引入了gateway依赖,就不能再引入spring-boot-starter-web依赖,否则会报错。因为web内置了tomcat服务器,而gateway中内置了netty服务器

3. 创建yml配置文件,配置网关

server:
  port: 88
  
spring:
  application:
    name: zmq-gateway
    #配置路由转发
  cloud:
    gateway:
      routes:
        - id: zmq-product  #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成
          uri: http://localhost:8001 #表示路由真实转发的微服务的地址
          predicates:
            - Path=/product/**

        - id: zmq-order
          uri: http://localhost:9001
          predicates:
            - Path=/order/**
  1. 配置端口号 88
  2. 微服务名称
  3. 配置路由转发

4. 在com.zmq包下创建主启动类

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

5. 测试

在这里插入图片描述

  • 若资源路径中的断言路径写错,报错如下图所示

在这里插入图片描述

  • 若资源路径中的后面路径写错,报错如下图所示

在这里插入图片描述

2.5 增强版—转发地址解耦

现在在配置文件中写死了转发路径的地址,前面我们已经分析过地址写死带来的问题,不符合前闭后开原则,接下来我们从注册中心获取此地址

思考:gateway网关它也是一个微服务,那么它也可以从注册中心拉取服务器清单列表

实现步骤

1. 引入nacos依赖

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

2. 修改配置文件

server:
  port: 88

spring:
  application:
    name: zmq-gateway
    #配置路由转发
  cloud:
    gateway:
      routes:
        - id: zmq-product  #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成
          uri: lb://zmq-product #表示路由真实转发的微服务的地址
          predicates:
            - Path=/product/**

        - id: zmq-order
          uri: lb://zmq-order
          predicates:
            - Path=/order/**
  #nacos的配置
    nacos:
      discovery:
        server-addr: localhost:8848
        register-enabled: false #是否注册到nacos上

将转发路径的地址进行解耦,使gateway微服务可以通过nacos组件从注册中心拉取【gateway可以只做拉取,而不注册到nacos上,在配置文件中设置即可】

register-enabled: false #是否注册到nacos上,默认为true,注册到nacos上,改为false后就可以实现只做拉取

lb:loadblance

2.6 简洁版-自动定位模式

增强版虽然实现了转发地址的解耦,但是需要手动配置转发地址相关参数,若微服务过多,可以使用简洁版实现自动定位模式,减少工作量

实现步骤

1. 修改配置文件

  • 删除关于转发路径的配置
  • 添加开启gateway的定位功能的配置
server:
  port: 88

spring:
  application:
    name: zmq-gateway

  #nacos的配置
    nacos:
      discovery:
        server-addr: localhost:8848
       # register-enabled: false #是否注册到nacos上
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启gateway的定位功能

2. 在访问资源时,需要在原本的路径上加上微服务的名称

在这里插入图片描述

3. Gateway用于认证校验

通过过滤器filter实现

实现步骤

1. 创建登录过滤器类

//在网关中定义的过滤器,只能在网关中使用
@Component
public class LoginFilter implements GlobalFilter, Ordered {
    @Autowired
    private UrlVo urlVo;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取request对象
        ServerHttpRequest request = exchange.getRequest();
        //获取response对象
        ServerHttpResponse response = exchange.getResponse();
        //获取上述两个对象是为了便于获取path和token
        //1.获取请求路径
        String path = request.getPath().toString();
        System.out.println(path);
        //对获取到的请求路径字符串进行截取,获取符合的地址路径【断言+资源路径】,便于后面比较判断是否放行
        path = path.substring(1);
        System.out.println(path);
        path=path.substring(path.indexOf("/"));//从第一个/的下标开始截取,indexOf,获取指定字符的索引
        System.out.println(path);
        //2.判断该路径是否属于放行路径——类似于白名单
        if(urlVo.getWhite().contains(path)){
            //放行
            return  chain.filter(exchange);
        }
        //3. 判断用户是否登录
        String token = request.getHeaders().getFirst("token");
        //4. 校验token是否为空,以及是否合法
        if(StringUtils.hasText(token)&&"admin".equals(token)){
            //放行
            return chain.filter(exchange);
        }
        //4.2 封装返回数据
        Map<String,Object> map=new HashMap<>();
        map.put("msg","未登录");
        map.put("code",501);
        //4.3 JSON转换
        byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
        // 4.4 调用bufferFactory方法,生成DataBuffer对象
        DataBuffer wrap = response.bufferFactory().wrap(bytes);
        //5. 调用Mono中的just方法,返回要写给前端的JSON数据
        return response.writeWith(Mono.just(wrap));
    }
    //优先级,值越小优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}
  1. 该过滤器类需要实现两个接口:GlobalFilter, Ordered,并重写接口的方法
  2. 重写fifter方法时
    • 首先通过exchange获取request对象和response对象,便于后面调用
    • 然后通过request的getPath方法,拦截获取请求路径,并将其转化为字符串,便于后面比较。
    • 对获取的路径字符串进行截取,获取用于判断的字符串,如下图

在这里插入图片描述

  1. 判断通过截取后的字符串是否在放行名单中,此时,需要在配置文件中添加需要放行的路径,并创建一个vo类,便于获取配置文件中的集合数据
  • 配置文件

    url:
      white:
        - /login
        - /register
        - /sendMsg
    
  • UrlVo类

    @Component
    @ConfigurationProperties(prefix="url")
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class UrlVo {
     private List<String> white;
    }
    
    1. 因为需要用到@Data等相关的注解,所以添加lombok依赖
     <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
    1. @ConfigurationProperties注解:是SpringBoot提供的,用于将外部配置文件中的属性映射到Java类中,绑定到Java类的字段上。可以方便地将配置文件中的属性注入到应用程序中,从而实现配置的集中管理和解耦

    prefix="XXX":意味着该类的字段会绑定到配置文件中以XXX为前缀的属性


  1. 通过request获取头文件中的token,校验token是否为空,是否合法

  2. 如果合法,就放行。

  3. 封装返回的数据,需要转换为JSON数据返回给前端,所以需要添加fastjson依赖

 <!--fastjosn-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.22</version>
        </dependency>
  • 测试

    在postman中进行测试,此时测试时需要带上token

    此时,该程序并没有连接关于用户登录的数据库,仅将token写死来测试

    • token不正确

    在这里插入图片描述

    • token正确

    在这里插入图片描述

测试时需要在原有的路径上面加上微服务的名称,因为使用的是自动定位模式

4. Gateway解决跨域问题【2种】

对之前的实现前后端分离项目中的前端项目做如下修改,便于测试

  1. main.js文件中,修改端口号为网关的端口号,并注释前置路由守卫,便于测试

    //a2.设置axios的基础路径
    axios.defaults.baseURL = 'http://localhost:88'
    //a3.将axios挂载到vue对象中
    Vue.prototype.$axios=axios;
    

    设置请求拦截器中将token写死——admin

    //设置请求拦截器——携带token令牌
    axios.interceptors.request.use(config=>{
      var token = sessionStorage.getItem("token");
      if(token){
        config.headers.token = "admin";
      }
      return config;
    })
    
  2. Home.vue文件中添加按钮,用于访问后端getById的路径

    在这里插入图片描述

实现getById方法

在这里插入图片描述

在不做跨域解决时,点击按钮,会报错,出现跨域问题

在这里插入图片描述

两种解决方法都是在gateway下解决

4.1 通过配置类

创建配置类,来解决跨域问题——在gateway微服务下

package com.zmq.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {
 
    @Bean
    public CorsWebFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许认证
        config.addAllowedOrigin("*"); // 允许任何源
        config.addAllowedHeader("*"); // 允许任何头
        config.addAllowedMethod("*"); // 允许任何方法
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}
  • 测试时,需要手动加上token——token值为admin

    在这里插入图片描述

4.2 通过配置文件

配置类和配置文件只能择其一

在配置文件中添加相关配置

cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启gateway的定位功能
      globalcors: #全局的跨域处理
        add-to-simple-url-handler-mapping: true #解决浏览器向服务器发options请求被拦截问题,这样网关就不拦截这个请求了
        cors-configurations:
          '[/**]': #拦截一切请求
            allowedOrigins: "*" #允许任意域的跨域请求
            allowedMethods: "*" #允许的跨域ajax的请求方式
            allowedHeaders: "*" #允许在请求中携带的头信息,这里是允许所有的请求头
            allowCredentials: true #是否允许携带cookie
            maxAge: 360000 #这次跨域检测的有效期

在这里插入图片描述

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

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

相关文章

kafka producer metrics

背景 做online Service埋点设计&#xff0c;塞了很多节点&#xff0c;采用了base64压缩&#xff0c;希望能监控当前消息的大小&#xff0c;防止超过threshold后无法正常发送。 kafka基本架构 producer metrics 官方文档 其中有两个参数用来表征在kafka的producer的client里&…

鸿蒙AI功能开发【hiai引擎框架-主体分割】 基础视觉服务

hiai引擎框架-主体分割 介绍 本示例展示了使用hiai引擎框架提供的主体分割能力。 本示例模拟了在应用里&#xff0c;选择一张图片&#xff0c;识别其图片中的显著性主体并展示出来主体的边界框的数据。 需要使用hiai引擎框架通用文字识别接口hms.ai.vision.subjectSegmenta…

加密软件有哪些常见的安全特性

1. 数据加密 核心功能&#xff1a;加密软件的核心在于对数据进行加密处理&#xff0c;通过复杂的加密算法&#xff08;如AES、RSA等&#xff09;将明文数据转换为密文&#xff0c;确保数据在存储和传输过程中的安全性。 透明加密&#xff1a;部分加密软件支持透明加密功能&am…

函数实例讲解(六)

文章目录 如何加密电话号码&#xff1f;&#xff08;SUBSTITUTE、REPLACE&#xff09;1、SUBSTITUTE2、REPLACE 用REPT函数做图表学生的考试成绩用A、B、C表示&#xff0c;如何找出哪个等级的学生最多呢&#xff1f;&#xff08;CHAR、CODE、MODE&#xff09;1、CHAR2、CODE3、…

【数据结构】顺序结构实现:特殊完全二叉树(堆)+堆排序

二叉树 一.二叉树的顺序结构二.堆的概念及结构三.堆的实现1.堆的结构2.堆的初始化、销毁、打印、判空3.堆中的值交换4.堆顶元素5.堆向上调整算法&#xff1a;实现小堆的插入6.堆向下调整算法&#xff1a;实现小堆的删除7.堆的创建1.堆向上调整算法&#xff1a;建堆建堆的时间复…

使用Go语言绘制折线统计图教程

使用Go语言绘制折线统计图教程 在本教程中&#xff0c;我们将学习如何使用Go语言及gg包绘制折线统计图&#xff0c;并将图表保存为PNG格式的图片。折线图适用于展示数据的变化趋势&#xff0c;并能直观地展示数据随时间或其他指标的变化。 安装gg包 首先&#xff0c;确保你已…

⌈ 传知代码 ⌋ 改进表情识别

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

Unity入门2——编辑器常用功能

点击文件夹&#xff0c;右键&#xff0c;选择showInExplorer可以在文件管理器中打开 选中多个图片素材&#xff0c;在Inspector里将Texture Type设置为Sprite(2D and UI)即可将图片素材用于UI 右键Hierachy面板的空白区&#xff0c;点击UI->Panel可以创建UI面板&#xf…

GPT-SoVITS-文本转语音(你的声音不再是唯一)

本文将要介绍GPT-SoVITS的安装和使用方法 首先感谢花儿不哭大佬带来的RVC声音克隆 花儿不哭&#xff1a; 花儿不哭的个人空间-花儿不哭个人主页-哔哩哔哩视频 (bilibili.com) GPT-SoVITS下载地址 GitHub - RVC-Boss/GPT-SoVITS: 1 min voice data can also be used to train a …

网络药理学:分子对接之pocasa/proteins.plus/Deepsite网站预测蛋白口袋

前言 配体的结合需要疏水作用&#xff0c;通常来说&#xff0c;疏水性空腔&#xff08;开口小、肚子大、能容纳一定体积的分子结构&#xff09;更有可能成为口袋。当我们复现网络药理学文章时可能经过前面的筛选&#xff0c;依旧有数个乃至数十个蛋白需要做分子对接验证。此时如…

算法——动态规划:基础

文章目录 一、基本介绍二、案例——斐波那契数列1. 基本介绍2. 递归实现3. 动态规划3.1 重叠子问题3.2 最优子结构3.3 无后效性3.4 性质的总结 4. 使用 动态规划 的思想实现4.1 自顶向下 的 递归4.2 自底向上 的 递推4.3 两种思路的简单比较 三、总结 一、基本介绍 动态规划&a…

python语言day4 函数 生成器yield、next关键字 装饰器

一、 函数 定义&#xff1a; def info(): print("执行info()函数") 直接调用方法和封装一个函数&#xff1a; 使用信息发送的功能为例 登录163网易免费邮-你的专业电子邮局 1&#xff09;开启POP3/SMTP服务&#xff0c;会得到对应的授权码&#xff0c;也就是登陆…

2024年旗舰骨传导耳机大对比:南卡、韶音和墨觉,哪款最值得购买?

作为专注于数码产品的博主&#xff0c;我对骨传导耳机的迅猛发展深有感触。这类耳机以其与众不同的技术和设计风格&#xff0c;成功捕捉了消费者的兴趣。它们独特的工作原理不仅保留了使用者对周围环境的感知&#xff0c;还能提供清晰的音乐播放和通话体验&#xff0c;特别适合…

第三方软件检测机构服务类型

在信息技术飞速发展的今天&#xff0c;软件产品的质量已成为企业竞争力的重要组成部分。卓码软件测评这家第三方软件检测机构致力于提供一流的软件测试服务&#xff0c;帮助企业确保其软件产品的可靠性和安全性。 一、项目验收测试&#xff1a;确保交付质量   项目验收测试是…

力扣-240.搜索二维矩阵(2)

刷力扣热题–第二十七天:240.搜索二维矩阵(2) 新手第二十七天 奋战敲代码&#xff0c;持之以恒&#xff0c;见证成长 1.题目简介 2.题目解答 这道题的想法就是,整体遍历,在遇到比target还大的,就停止这行的遍历,然后转过去继续遍历下一行,如果有一行的开头大于target,直接返回…

嘉盛平台的代理返佣机制:一份详细的说明书

在金融市场合作模式的多样性中&#xff0c;嘉盛平台的代理返佣机制无疑是一个引人注目的亮点。想了解更多关于嘉盛平台的代理返佣机制吗&#xff1f;本文将为您详细解答。嘉盛开户MT4平台开户链接 &#xff1a;https://application.jszhanghao.com/cn-meta/step/1?ibcodeFXAMM…

Windows--WSL2--Ubuntuon--Docker

编写目的&#xff1a; 在Windows上安装Docker&#xff0c;用Docker安装Gitlab、Jenkins等软件。 文章记录一下Windows上安装Docker的过程。 参考文档&#xff1a; 旧版 WSL 的手动安装步骤 | Microsoft Learn 下面用"参考文档"代替 目录 第一步&#xff1a;启…

RK3568平台开发系列讲解(文件系统篇)FLASH 均衡擦写(UBI)

🚀返回专栏总目录 文章目录 一、UBI均衡二、日志打印三、常见打印四、erase_worker四、ensure_wear_leveling五、wear_leveling_worker上层应用通过逻辑地址来访问存储设备,FTL把不同的逻辑地址映射到Nand Flash中的不同位置。 一、UBI均衡 Ubi擦写均衡在ubi驱动中c 处理,u…

66 函数精彩案例

1 编写函数&#xff0c;接收任意多个实数&#xff0c;返回一个元组&#xff0c;其中第一个元素为所有参数的平均值&#xff0c;其他元素为所有参数中大于平均值的实数。 def func(*parameter):avg sum(parameter) / len(parameter) # 平均值g [i for i in parameter if i &…

哈萨克语驾考学习软件求推荐?

哈语驾考APP专门为哈萨克族考驾照的学员提供了科目一科目四题库在线练习和模拟考试&#xff0c;是一款哈汉双语版本的驾考学习APP。软件内可同时切换哈萨克语题库和语言文字&#xff0c;有多种学习模式。题库同步车管所考题&#xff0c;通过率高。包含了科一、科四模拟考试、路…