微服务-实现nacos的集群和Gateway网关的实现、认证校验、解决跨域
1. nacos的集群模式
1.1 分析
nacos在企业中的使用100%都是集群模式。需要掌握nacos集群的搭建

nacos的数据存放在derby本地磁盘中,nacos集群模式会导致数据库数据不一致,使用加一层思想,修改nacos的数据库,使用mysql数据库,保证数据的一致
模拟nacos在window中搭建集群。因为在2.0以后,nacos增加理论两个端口,偏移量为1000和1001,所以需要注意端口号
使用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、平板】要如何去调用这么多的微服务呢?
如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。
这样的架构,会存在着诸多的问题
- 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
- 认证复杂,每个服务都需要独立认证
- 存在跨域请求,在一定场景下处理相对复杂。

网关:所有微服务的入口点
作用:
- 路由转发
- 认证校验
- 跨域统一解决
- 黑白名单
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 链的方式提供了网关基本的功能,例如:安全,监控和限流。
- 优点
- 性能强劲:是第一代网关Zuul的1.6倍
- 功能强大:内置了很多实用的功能,例如转发、监控、限流等
- 设计优雅,容易扩展
- 缺点
- 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
- 不能将其部署在Tomcat、Jetty等Servlet容器里,只能达成jar包执行web.jar
- 需要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: 88spring:application:name: zmq-gateway#配置路由转发cloud:gateway:routes:- id: zmq-product #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成uri: http://localhost:8001 #表示路由真实转发的微服务的地址predicates:- Path=/product/**- id: zmq-orderuri: http://localhost:9001predicates:- Path=/order/**
- 配置端口号 88
- 微服务名称
- 配置路由转发
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: 88spring:application:name: zmq-gateway#配置路由转发cloud:gateway:routes:- id: zmq-product #路由id,没有实际意义。如果自己设置,就会通过UUID随机生成uri: lb://zmq-product #表示路由真实转发的微服务的地址predicates:- Path=/product/**- id: zmq-orderuri: lb://zmq-orderpredicates:- Path=/order/**#nacos的配置nacos:discovery:server-addr: localhost:8848register-enabled: false #是否注册到nacos上
将转发路径的地址进行解耦,使gateway微服务可以通过nacos组件从注册中心拉取【gateway可以只做拉取,而不注册到nacos上,在配置文件中设置即可】
register-enabled: false #是否注册到nacos上,默认为true,注册到nacos上,改为false后就可以实现只做拉取lb:loadblance
2.6 简洁版-自动定位模式
增强版虽然实现了转发地址的解耦,但是需要手动配置转发地址相关参数,若微服务过多,可以使用简洁版实现自动定位模式,减少工作量
实现步骤
1. 修改配置文件
- 删除关于转发路径的配置
- 添加开启gateway的定位功能的配置
server:port: 88spring: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 {@Autowiredprivate UrlVo urlVo;@Overridepublic 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));}//优先级,值越小优先级越高@Overridepublic int getOrder() {return 0;}
}
- 该过滤器类需要实现两个接口:GlobalFilter, Ordered,并重写接口的方法
- 重写fifter方法时
- 首先通过exchange获取request对象和response对象,便于后面调用
- 然后通过request的getPath方法,拦截获取请求路径,并将其转化为字符串,便于后面比较。
- 对获取的路径字符串进行截取,获取用于判断的字符串,如下图

- 判断通过截取后的字符串是否在放行名单中,此时,需要在配置文件中添加需要放行的路径,并创建一个vo类,便于获取配置文件中的集合数据
-
配置文件
url:white:- /login- /register- /sendMsg -
UrlVo类
@Component @ConfigurationProperties(prefix="url") @Data @AllArgsConstructor @NoArgsConstructor public class UrlVo {private List<String> white; }- 因为需要用到
@Data等相关的注解,所以添加lombok依赖
<!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>@ConfigurationProperties注解:是SpringBoot提供的,用于将外部配置文件中的属性映射到Java类中,绑定到Java类的字段上。可以方便地将配置文件中的属性注入到应用程序中,从而实现配置的集中管理和解耦
prefix="XXX":意味着该类的字段会绑定到配置文件中以XXX为前缀的属性
- 因为需要用到
通过request获取头文件中的token,校验token是否为空,是否合法
如果合法,就放行。
封装返回的数据,需要转换为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种】
对之前的实现前后端分离项目中的前端项目做如下修改,便于测试
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; })
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 {@Beanpublic 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 #是否允许携带cookiemaxAge: 360000 #这次跨域检测的有效期

相关文章:
微服务-实现nacos的集群和Gateway网关的实现、认证校验、解决跨域
1. nacos的集群模式 1.1 分析 nacos在企业中的使用100%都是集群模式。需要掌握nacos集群的搭建 nacos的数据存放在derby本地磁盘中,nacos集群模式会导致数据库数据不一致,使用加一层思想,修改nacos的数据库,使用mysql数据库&…...
数据库中的约束,聚合函数以及联合查询
目录 数据库中的约束 not null unique default primary key foreign key 表的设计 聚合函数(查询) 分组 联表查询(多表查询) 内连接 外连接 左外连接 右外连接 自连接 子查询 合并查询 数据库中的约束 为了保证…...
【AI大模型】Ollama+OpenWebUI+llama3本地大模型
本地部署大模型 0.引言1.部署安装1.1部署工具1.2 概念介绍1.3 ollama安装后的基本使用1.4 大模型权重下载1.4.1 ollama在线下载1.4.2 huggingFace下载大模型权重及如何使用ollama进行调用 2.带有UI界面的使用3.参考 0.引言 (1)目的 本教程主要关于开源A…...
习题20240807
文章目录 题目 1: 泛型类题目 2: 泛型方法题目 3: 泛型接口题目 4: 泛型约束题目 5: 泛型集合题目6:题目7:题目8:题目9: 题目 1: 泛型类 编写一个泛型类 Box,它能够存储一个类型为 T 的值,并提供方法 SetI…...
src挖掘-记一次有趣的逻辑漏洞分享
漏洞挖掘-记一次有趣的逻辑漏洞挖掘 前言简述1、信息收集2、找功能点3、挖掘漏洞案例一:任意用户注册漏洞案例二-垂直越权导致管理员密码重置获得管理员后台权限漏洞总结 前言 此文章是小白的学习笔记,请不要利用文章内相关知识点进行非法渗透ÿ…...
【C++】STL | list (链表)详解及重要函数的实现
目录 前言 总代码 ListNode类框架的建立 (成员与模板) list类的框架 普通构造 与 empty_init(适合不同类型构造函数的小函数) list的迭代器 引子 operator、operator--(前置与后置) operator 与 operator! operator* 与 …...
警惕智能手机的“隐形眼”:如何保护我们的数字隐私堡垒
随着智能手机深入我们生活的方方面面,它变得无所不在,甚至无所不知。 但你是否意识到,你的手机可能正在悄无声息地“监听”你的一举一动? 从你的搜索习惯到日常对话,手机的个性化推荐系统正不断收集你的数据。 本文…...
人工智能算法工程师(高级)课程12-自然语言处理之NLP的语言模型-ELMo,transformer,BERT与代码详解
大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程12-自然语言处理之NLP的语言模型-ELMo,transformer,BERT与代码详解。本课程面向高级人工智能算法工程师,深入讲解自然语言处理(NLP)中的关键语言模型技术,包括了EMLo和transformer架构。此外,课程还详细…...
PicGo + gitee 免费搭建个人图床
目录 1 图床概念2 使用gitee和PicGo搭建图床流程2.1 下载安装PicGo工具 3 图片上传错误处理3.1 PicGo客户端提示404错误信息图片上传失败3.2 PicGo客户端提示400错误信息图片上传失败 1 图床概念 "图床"是一个网络术语,它指的是一种用于存储和托管图片…...
组合数的低复杂度运算
题源 题目 F. 预期中位数 每次测试的时间限制:3 秒 每次测试的内存限制:256 兆字节 Arul 有一个长度为 n 的二进制数组* a。 他将取该数组中所有长度为 k(k 为奇数)的子序列并找到它们的中位数。 所有这些值的总和是多少…...
小型并网式光伏气象站:光伏电站的智能守护者
小型并网式光伏气象站以其独特的功能和优势,成为了电站高效运行的智能守护者。小型并网式光伏气象站通过精准的数据采集与分析,为光伏电站的运维管理提供了强有力的支持。 小型并网式光伏气象站能够实时监测并记录光伏电站周围环境的多种气象参数&#x…...
JavaScript 中的回调函数(callback)
JavaScript 中的回调函数(callback) JavaScript 中的回调函数(callback)是一个传递给另一个函数作为参数的函数,并且这个传递的函数可以在其他函数内部被调用执行。回调函数是异步编程的一个核心概念,特别…...
计算机毕业设计hadoop+spark+hive漫画推荐系统 动漫视频推荐系统 漫画分析可视化大屏 漫画爬虫 漫画推荐系统 漫画爬虫 知识图谱 大数据
HadoopSparkHive漫画推荐系统详细开题报告 一、引言 随着互联网技术的飞速发展,动漫和漫画产业的数据量急剧增长。用户面临着海量漫画作品的选择难题,如何从这些数据中高效地提取有价值的信息,为用户推荐符合其喜好的漫画作品,成…...
解决pycharm日志总是弹出“无法运行Git,未安装Git”的问题
需求分析 我电脑中安装了git,但是打开pycharm,右下角总是弹出 无法运行Git,未安装Git的日志。 解决方法 首先打开pycharm,按照以下路径,依次点击。 file -----settings-----version control -----Git----Git path(选择自己下载…...
threejs 节点材质系统 绑定attribute
新的 节点材质系统 绑定属性及使用 非常方便 不必重复声明 以instances为例 import {instancedBufferAttribute,instancedDynamicBufferAttribute,} from "three/tsl";声明一个 InstancedBufferAttribute 使用 instancedBufferAttribute包装后就可以在shader中直接使…...
Rabbitmq的几种工作模式
工具类 public class RabbitMQConnection {public static Connection getConnection() throws Exception{//1.创建connectionFactoryConnectionFactory connectionFactory new ConnectionFactory();//2.配置HostconnectionFactory.setHost("127.0.0.1");//3.设置Po…...
如何在 Debian 上安装运行极狐GitLab Runner?【二】
极狐GitLab 是 GitLab 在中国的发行版,专门面向中国程序员和企业提供企业级一体化 DevOps 平台,用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规,而且所有的操作都是在一个平台上进行,省事省心省钱。可以一键安装极狐GitL…...
简单的docker学习 第13章 CI/CD与Jenkins(下)
第13章 CI/CD 与 Jenkins 13.13 自由风格的 CI 操作(最终架构) 前面的架构存在的问题是,若有多个目标服务器都需要使用该镜像,那么每个目标服务器都需要在本地构建镜像,形成系统资源浪费。若能够在 Jenkins 中将镜像相撞构建好并推送到 Har…...
基于STM32设计的智能鱼缸_带鱼儿数量视觉识别(华为云IOT)(202)
文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置【3】自动换水原理1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择【1】设备端开发【2】上位…...
立体连接模式下的传播与沟通:AI智能名片小程序的创新应用与深度剖析
摘要:在数字化浪潮的推动下,信息传播与沟通方式正经历着前所未有的变革。立体连接模式,作为这一变革的重要产物,通过整合物理空间、虚拟网络空间与社群心理空间的三维联动,实现了信息的深度传播与高效互动。AI智能名片…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...


