千家信息网

如何解决Spring Cloud 服务冲突问题

发表于:2025-12-06 作者:千家信息网编辑
千家信息网最后更新 2025年12月06日,本篇文章为大家展示了如何解决Spring Cloud 服务冲突问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、背景在我们开发微服务架构系统时,虽然说每个
千家信息网最后更新 2025年12月06日如何解决Spring Cloud 服务冲突问题

本篇文章为大家展示了如何解决Spring Cloud 服务冲突问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

一、背景

在我们开发微服务架构系统时,虽然说每个微服务都是孤立的可以单独开发,但实际上并非如此,要调试和测试你的服务不仅需要您的微服务启动和运行,还需要它的上下文服务、依赖的基础服务等都要运行;但如果你的系统服务数和依赖比较多呢,那就是一个比较棘手的问题!有没有办法能提高开发效率呢?

如上图所示,我们能不能用服务器把所有的服务都部署起来,然后开发只在本地运行自己所负责开发的服务,因为需要依赖其他服务所以本地启动的服务也需要注册到公共的注册中心里;

例子中业务服务B有3台实例注册到注册中心里

分别是:服务上的、开发A与开发B自己本机启动的

但是这样做又会出现新的问题:服务会冲突乱窜,意思就是开发A在debug自己的业务服务B服务的时候可能请求会跳转到其他人的实例上(服务器、开发B)

二、解决思路

解决这个服务乱窜问题有一个比较优雅的方式就是自定义负载均衡规则,主要实现以下目标:

  1. 普通用户访问服务器上的页面时,请求的所有路由只调用服务器上的实例

  2. 开发A访问时,请求的所有路由优先调用开发A本机启动的实例,如果没有则调用服务器上的实例

  3. 开发B访问时同上,请求的所有路由优先调用开发B本机启动的实例,如果没有则调用服务器上的实例

三、具体实现

要实现上面的目标有两个比较关键的问题需要解决

  1. 区分不同用户的服务实例

  2. 实现自定义负载均衡规则

3.1. 区分不同用户的服务实例

直接使用注册中心的元数据(metadata)来区分就可以了

主流的注册中心都带有元数据管理

以Nacos为例,只需要在配置文件下添加

spring: cloud: nacos: discovery: server-addr: localhost:8848 metadata: version: zlt

metadata下的version就是我添加的元数据key为version,value为zlt

启动服务后元数据就会注册上去,如下图

经过元数据区分后,目前是下面这个情况

  • 服务器的实例version为空

  • 开发人员自己本地启动的实例version为唯一标识(自己的名字)

3.2. 自定义负载均衡规则

首先在Spring Cloud微服务框架里实例的负载均衡是由Ribbon负责。

CustomIsolationRule详细类信息可查看:CustomIsolationRule.java

public class CustomIsolationRule extends RoundRobinRule { /** * 优先根据版本号取实例 */ @Override public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } String version = LbIsolationContextHolder.getVersion(); List targetList = null; List upList = lb.getReachableServers(); if (StrUtil.isNotEmpty(version)) { //取指定版本号的实例 targetList = upList.stream().filter( server -> version.equals( ((NacosServer) server).getMetadata().get(CommonConstant.METADATA_VERSION) ) ).collect(Collectors.toList()); } if (CollUtil.isEmpty(targetList)) { //只取无版本号的实例 targetList = upList.stream().filter( server -> { String metadataVersion = ((NacosServer) server).getMetadata().get(CommonConstant.METADATA_VERSION); return StrUtil.isEmpty(metadataVersion); } ).collect(Collectors.toList()); } if (CollUtil.isNotEmpty(targetList)) { return getServer(targetList); } return super.choose(lb, key); } /** * 随机取一个实例 */ private Server getServer(List upList) { int nextInt = RandomUtil.randomInt(upList.size()); return upList.get(nextInt); }}

集成轮询规则RoundRobinRule来实现,主要的逻辑为

  • 根据上游输入的版本号version,有值的话则取服务元信息中version值一样的实例

  • 上游的版本号version没值或者该版本号匹配不到任何服务,则只取服务元信息中version值为空的实例

并通过配置开关控制是否开启自定义负载规则

@Configuration@ConditionalOnProperty(value = "zlt.ribbon.isolation.enabled", havingValue = "true")@RibbonClients(defaultConfiguration = {RuleConfigure.class})public class LbIsolationConfig {}

四、总结

上面提到的区分服务实例和自定义负载规则为整个解决思路的核心点,基本实现了服务实例的隔离,剩下要做的就是上游的version怎样传递呢?,下面我提供两个思路

  • 开发人员自己启动前端工程,通过配置参数,统一在前端工程传递version

  • 通过postman调用接口的时候在header参数中添加

上述内容就是如何解决Spring Cloud 服务冲突问题,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

服务 实例 开发 服务器 问题 就是 版本 规则 数据 均衡 冲突 思路 用户 路由 本机 运行 配置 不同 业务 两个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 nacos自带数据库吗 数据库远程部署需要版本一致吗 华为服务器默认ipmi账号 软考数据库主键是什么 android监测服务器 非常和平且好玩的服务器 战术小队经常搜索不到服务器 怎么进服务器raid管理界面 网络安全信息安全承诺 oa软件开发高品质的选择 企业网络安全报道 支持网飞的代理服务器 计算机网络技术实践课题 武汉软件开发测算标准 网络安全视频背景 共建网络安全校园演讲稿 php查询数据库结果 怎么判断是不是服务器断网 固安cmmi软件开发认证 济南协裕网络技术有限公司介绍 定向士官计算机网络技术好就业吗 业务处理流程对软件开发的意义 河南中天浩然网络技术有限公司 宁夏企业党建软件开发公司 我国数据库发展起源于多少年代 二手服务器折价 浩如烟海的数据库 数据库怎么计算图书借阅时间 高中网络安全防护措施 共建网络安全校园演讲稿
0