springcloud loadbalancer nacos无损发布

前言

  • 故事背景
    jenkins部署时总是会有几秒钟接口调用报错,观察日志是因为流量被下发到已下线的服务,重启脚本在停止应用之前先调用nacos注销实例api后再重启依然会短暂出现此问题。项目架构是springcloud alibaba,通过openfeign进行微服务之间调用,猜测是LoadBalancer缓存问题。
  • 依赖版本
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.1.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.6.3</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.1</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.1.1</version></dependency>
</dependencies>
  • loadbalancer配置
spring:cloud:loadbalancer:#需要引入Spring Retry依赖retry:enabled: true

springcloud loadbalancer缓存原理

  1. 启用启动首先装配Caffeine一级缓存,缓存应用实例,降低注册中心负载,提升性能
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    从上图可以看出,可以通过设置spring.cloud.loadbalancer.cache来关闭一级缓存,其值默认是开启的。

  2. feign初次从loadbalance获取应用实例会触发装配ServiceInstanceListSupplier逻辑
    在这里插入图片描述

在这里插入图片描述从一级缓存中获取应用实例:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

解决方案

通过上面的源码分析,根本原因是应用从nacos下线后,loadbalancer的一级缓存未移除下线实例,有以下解决办法:

  1. 重启脚本下线nacos实例后,等待一级缓存失效后(默认35s)再重启应用
  2. 禁用一级缓存(不建议)
  3. 监听nacos下线事件,手动移除实例

方案实现

  • 采用方案
    监听nacos下线事件,手动移除实例
  • 代码实现
    • 思路
      nacos订阅需要删除缓存的服务名(serviceName),下线应用主动调用nacos实例注销api后由nacos server触发自定义的订阅回调逻辑
    • nacos订阅源码分析
      在这里插入图片描述
      在这里插入图片描述从上图可以看出默认只会订阅当前服务名,这也是为什么以下代码在其他应用主动下线后没有触发回调的原因
      在这里插入图片描述
    • 编写指定服务nacos订阅与删除实例缓存逻辑
package com.chimelong.common.feign.listener;import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import lombok.SneakyThrows;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager;
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheProperties;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier;
import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;
import java.util.Arrays;/*** @description nacos应用监听* @date 2024/7/29*/
@Configuration
@ConditionalOnProperty(name = "spring.cloud.loadbalancer.cache.enabled", havingValue = "true")
@AutoConfigureAfter(LoadBalancerCacheProperties.class)
public class NacosInstanceListener implements InitializingBean {@Resourceprivate NacosServiceManager nacosServiceManager;@Resourceprivate NacosDiscoveryProperties properties;@Resourceprivate LoadBalancerCacheManager caffeineLoadBalancerCacheManager;@Override@SneakyThrowspublic void afterPropertiesSet() {NamingService namingService = nacosServiceManager.getNamingService(properties.getNacosProperties());namingService.subscribe("xxx-product-xxx", properties.getGroup(), Arrays.asList(properties.getClusterName()), event -> {if (event instanceof NamingEvent) {NamingEvent namingEvent = (NamingEvent) event;String svrName = namingEvent.getServiceName();Cache cache = caffeineLoadBalancerCacheManager.getCache(CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME);if (cache != null) {cache.evict(svrName);}System.out.println(event);}});}
}
  • 下线服务主动调用nacos注销实例接口,观察效果
    在这里插入图片描述
    在这里插入图片描述
    从上图可以看到,删除服务实例缓存回调成功触发,考虑到调用nacos api下线到上述代码被成功执行的耗时,应用重启脚本最好在调用nacos api成功后等待1秒左右再停止服务。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试笔记8.6

缓存 1.如何保证redis与数据库一致性 redis面试&#xff1a;如何保证缓存和数据库数据的一致性&#xff1f;_使用update更新数据,json缓存不更新-CSDN博客 如果先删除缓存&#xff0c;再删除数据库&#xff0c;数据不一致&#xff0c; 解决 删 1.先操作缓存但不删除缓存&…

C#使用NPOI进行Excel和Word文件处理(二)

文章目录 使用NPOI在C#中处理Excel和Word文件1. 什么是NPOI&#xff1f;2. 安装NPOI2.1 VisualStudio2019引入NPOI 3. 处理Excel文件读取Excel文件写入Excel文件 4. 处理Word文件读取Word文件写入Word文件 总结Github 地址链接参考例子 使用NPOI在C#中处理Excel和Word文件 在C…

linux maven仓库 删除未下载完成的包 lastUpdated文件

以下命令查找.lastUpdated文件所在目录&#xff0c;并删除所在目录(maven包的版本目录&#xff09;。 $ find ~/.m2/repository/ -regex ".*\.lastUpdated" | xargs dirname | xargs rm -rf查找未下载完成的文件 $ find ~/.m2/repository/ -regex ".*\.lastUp…

使用 docker 快速搭建独角数卡发卡网

docker版本的发卡程序搭建 项目1&#xff1a;https://github.com/assimon/dujiaoka 项目2&#xff08;基于项目1&#xff09;&#xff1a;https://github.com/Apocalypsor/dujiaoka-docker 一键安装脚本 curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/m…

系统化学习 H264视频编码(06)哥伦布编码解读

说明&#xff1a;我们参考黄金圈学习法&#xff08;什么是黄金圈法则?->模型 黄金圈法则&#xff0c;本文使用&#xff1a;why-what&#xff09;来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法&#xff0c;理论方面会更多地讲清楚 音视频中概念的…

C语言典型例题28

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.5 输入一个华氏温度&#xff0c;要求输出摄氏温度。公式为C5/9(F-32)&#xff0c;要求输出要有文字说明&#xff0c;取两位小数 数学知识&#xff1a; &#xff08;1&#xff09;华氏温度与摄氏温度&#x…

E2000 RGMII0通讯异常问题总结

最近让新来小朋友做了一款E2000Q的板卡,使用了E2000Q上的两个RGMII资源,外接YT8521转出了电口。 但是他调试中遇到了一个比较奇怪的问题,两套YT8521的电路都一样,但是一路通一路不通。 也就是框图中MAC2(芯片RGMII0,系统对应eth1)那路网络不通,图中MAC3(芯片RGMII1,…

DITA发布PDF样式定制

- 1 - 概述 使用结构化写作/DITA写作&#xff0c;内容和样式是分离的。 编写的内容放在DITA文件中&#xff0c;样式是放在样式模板文件中。 而且针对不同的格式的输出&#xff08;如&#xff1a;PDF&#xff0c;MS Word&#xff09;&#xff0c;样式模板文件不同。 文档工程…

【优秀python案例】基于百度贴吧的数据采集与文本分析设计与实现

数据采集实现&#xff1a; 对百度贴吧帖子数据的采集。首先&#xff0c;使用requests库发送HTTP请求&#xff0c;通过设置请求头模拟浏览器访问&#xff0c;获取网页的HTML内容。然后&#xff0c;利用BeautifulSoup库对HTML内容进行解析&#xff0c;以便提取所需的信息。 在循…

c# .net core项目角色授权机制

前言 角色授权机制是确保应用程序安全性的重要组成部分&#xff0c;它允许开发者根据用户的角色来限制对应用程序中不同资源的访问。 基本概念&#xff1a; 角色授权基于用户角色的访问控制&#xff0c;即根据用户所属的角色来决定其能够访问的资源或执行的操作。在.NET Cor…

k8s—ingress应用

一、ingress和ingress-controller ingress对象&#xff1a; 指的是k8s中的⼀个api对象/资源对象&#xff0c;⼀般⽤yaml配置。作⽤是定义请求如何转发到service的规则&#xff0c;可以理解为配置模板。 ingress-controller&#xff1a; 具体实现反向代理及负载均衡的程序&…

鸿蒙第三方应用.hap打包、安装流程。

最近在华为手表上安装第三方应用&#xff08;源码打包构建应用&#xff0c;需要签名&#xff09;。网上看了教程&#xff0c;在此记录下。 准备工作&#xff1a;先安装DevEco Studio开发工具。 进入华为 appgallery connect网站&#xff08;注册、开发者实名认证&#xff09; …

【Material-UI】按钮组:按钮变体详解

文章目录 一、按钮变体概述1. 组件介绍2. 基本用法 二、按钮变体详细说明1. 轮廓按钮&#xff08;Outlined&#xff09;2. 文本按钮&#xff08;Text&#xff09;3. 填充按钮&#xff08;Contained&#xff09; 三、按钮变体的实际应用场景1. 界面设计2. 界面一致性3. 视觉层次…

面试笔记 8.5

面试常见: Jvm&#xff0c;高并发&#xff0c;多线程&#xff0c;数据库&#xff0c;redis&#xff0c;框架 1.N I/O有什么核心组件 Java NIO 基本原理以及三大核心组件_java nio核心组件有哪些-CSDN博客 Buffer 缓冲 Channel 一对一 Channel 读取数据 Selector对应线程…

双轮驱动产品持续商业成功

获取完整PPT见下图 更多有关华为研发管理/IPD、MBSE、PLM、ERP、MES、数据治理、数字样机等方面免费解决方案、资料获取&#xff0c;请见下图

前端(五):前端工程化

前端工程化是指在企业级的前端开发项目中&#xff0c;把前端开发所需的工具、技术、流程、经验等进行规范化、标准化。 一、环境准备 &#xff08;一&#xff09;环境准备 1、Vue-cli&#xff1a;是Vue官方提供的一个脚手架&#xff0c;用于快速生成一个Vue的项目模板。 2、…

myeclipse 2020 下载 安装 汉化

1&#xff0c;解压 myeclipse 2020 压缩包到当前目录下&#xff1a; 点击此处蓝色字体下载压缩包 提取码 k3x9 2&#xff0c;鼠标右键 点击 myeclipse 2020.exe 选择 以管理员身份运行 &#xff1a; 3&#xff0c;等待加载&#xff1a; 4&#xff0c;点击 Next &#xff1a; 5…

正则表达式测试工具

前言 正则表达式测试工具可供您输入正则表达式和测试文本&#xff0c;立即查看匹配结果. 下面是离线的HTML文件,同样可以提供相同的服务. 目录 使用说明 HTML代码 正则表达式的编写经验和方法 总结 使用说明 1.先将HTML代码存储成.html为后缀的文件; 2.然后用浏览器打开这个…

C++空指针(nullptr)

C空指针(nullptr) ​ 在C语言中我们把空指针定义成NULL&#xff0c;但是这在C中会有所问题&#xff0c;因为C对指针类型转换比较严格。下面让我来深入了解一下NULL与nullptr。 NULL实际就是一个宏&#xff0c;在C头文件(stddef.h)中&#xff0c;可以看到如下代码&#xff1a;…

【ML】transform 之 decoder 及其实现细节

【ML】transform 之 decoder 及其实现细节 1. decoder2. encoder 和decoder 之间是如何处理和传递讯息的&#xff1f;self-attention3. 查询&#xff08;Query&#xff09;、键&#xff08;Key&#xff09;、值&#xff08;Value&#xff09;是三个核心概念及其具体含义和计算方…