springcloud loadbalancer nacos无损发布

news2024/9/25 13:18:59

前言

  • 故事背景
    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.xxx.xxx.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 {

    @Resource
    private NacosServiceManager nacosServiceManager;

    @Resource
    private NacosDiscoveryProperties properties;

    @Resource
    private LoadBalancerCacheManager caffeineLoadBalancerCacheManager;

    @Override
    @SneakyThrows
    public 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.coloradmin.cn/o/1989130.html

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

相关文章

npm vs pnpm 之幽灵依赖

在之前的文章&#x1f4c4; 果断放弃npm切换到pnpm–节约磁盘空间&#xff08;256G硬盘救星&#xff09; 中有提及 npm 扁平化带来的幽灵&#x1f47b;依赖 问题&#xff0c;但没有特别展开&#xff0c;这段时间实际业务中遇到了该问题&#xff0c;特整理如下&#xff1a; ♨️…

Linux C 程序 【03】线程栈空间

1.开发背景 上一个篇章创建了线程&#xff0c;参考 FreeRTOS&#xff0c;每个线程都是有自己的内存空间&#xff0c;Linux上面也是一样的&#xff0c;这个篇章主要描述线程栈空间的设置。 2.开发需求 设计实验&#xff1a; 1&#xff09;创建线程&#xff0c;并配置线程内存大…

充电桩--直流充电桩方案详解

一、直流充电桩介绍 1、直流充电桩介绍 电动汽车市场数量的不断激增&#xff0c;为缓解消费者对其里程焦虑与充电焦虑&#xff0c;配置双向OBC可以实现快速充电&#xff0c;还可将电动汽车当作分布式储能站回馈电网帮助消峰填谷&#xff0c;通过DCFC为电动汽车高效充电&#…

【解决错误】ModuleNotFoundError: No module named ‘progress’

【解决错误】ModuleNotFoundError: No module named ‘progress’ 在Python编程中&#xff0c;遇到“ModuleNotFoundError: No module named ‘progress’”这类错误&#xff0c;通常意味着Python解释器在其环境中找不到名为‘progress’的模块。以下将深入探讨这一错误的产生…

HBM2、HBM2E、HBM3和HBM3E技术

HBM(High Bandwidth Memory)是一种高性能的内存技术,主要用于数据中心、超级计算机、高端服务器、图形处理器(GPU)和AI加速器等领域,因为它能够提供比传统DDR内存更高的带宽和更低的功耗。 HBM2、HBM2E、HBM3和HBM3E技术 HBM2 (High Bandwidth Memory 2) HBM2 是HBM技术…

深入JVM:类加载器和双亲委派模型

目录 1. 什么是类加载器2. 类加载器的类型3. 双亲委派模型4. 类装载的过程加载验证准备解析初始化使用卸载 1. 什么是类加载器 如果想要了解什么是类加载器就需要清楚一个Java文件是如何运行的。我们可以看下图&#xff1a; 首先要知道操作系统是不能直接运行Java文件的&#…

大模型Transformer架构详解

深度学习领域正在经历一场剧烈的变革&#xff0c;这得益于Transformer模型的诞生和迅速发展。 这些开创性的架构不仅重新定义了自然语言处理&#xff08;NLP&#xff09;的标准&#xff0c;还极大地拓宽了人工智能的多个领域。 凭借其独特的注意力机制和并行处理能力&#xf…

目录的读写

一、文件流和字符描述的转换 1.1、fileno 要求的是内存大小一致 fileno FILE* fp -> int fd fgets(,); int fileno(FILE *stream); 功能: 获得一个文件流指针中的文件描述符 参数: stream:文件流指针 返回值: 成功返回文件描述符 失败返回-1 如果没有特殊要求的&…

如何在Zoom中集成自己的app?一个简单的例子

一、注册zoom 账号、以便在zoom app maketplace创建app。 二、安装git、node.js、vscode开发环境&#xff08;略&#xff09;。 三、注册ngrok账号&#xff0c;获得一个免费的https静态域名。 四、配置zoom app(wxl)&#xff0c;设置上一步获得的https静态域名&#xff0c;验证…

2024 年 7 月区块链游戏研报:市场波动与数据分化的挑战与机遇

作者&#xff1a;Stella L (stellafootprint.network) 数据来源&#xff1a;Footprint Analytics 游戏研究页面 7 月份&#xff0c;加密货币市场波动显著&#xff0c;价格表现各异。比特币和 Solana 表现抢眼&#xff0c;与此同时&#xff0c;以太坊在美国市场推出现货以太坊…

8.3 字符串中等 306 Additive Number 423 Reconstruct Original Digits from English

306 Additive Number //累加数&#xff1a;除了前两个数&#xff0c;其余数都等于前两个加起来&#xff0c;至少包括三个数 //难点找到前两个数 //条件1&#xff1a;至少包括三个数–>确定前两个数字的最大长度 len n/3 看下方注意1 //条件2&#xff1a;遇到0默认归属于他…

Axure RP界面设计初探:基础操作与实用技巧

Axure RP是目前流行的设计精美的用户界面和交互软件。Axure RP提供了一组丰富的RP。 UI 控件&#xff0c;这些控件根据它们的应用领域进行分类。作为Axure的国产替代品&#xff0c;它可以在线协同工作&#xff0c;浏览器可以在不下载客户端的情况下立即打开和使用。如果以前用A…

护眼灯到底有没有用?一文曝光护眼灯的三大好处!

护眼台灯进入大众的视野&#xff0c;但种类多样&#xff0c;其质量也是参差不齐。不少人一直有着”护眼灯到底有没有用&#xff1f;“质疑&#xff0c;作为学生&#xff0c;课业多且繁重&#xff0c;再加上电子设备普遍普及&#xff0c;眼睛受承受的压力日渐增大。因此&#xf…

如何快速实现MODBUS TCP转Profinet——泗博网关EPN-330

泗博网关EPN-330可作为PROFINET从站&#xff0c;支持与西门子S7-200 SMART/300/400/1200/1500全系列PLC以及具有PROFINET主站的系统无缝对接&#xff0c;而Modbus TCP端&#xff0c;可以与Modbus TCP从站设备、主站PLC、DCS系统以及组态软件等进行数据交互。 通过EPN-330&…

【算法设计题】编写算法,统计带头节点的单链表L的实际元素个数,第5题(C/C++)

目录 第5题 统计带头节点的单链表L的实际元素个数 得分点&#xff08;必背&#xff09; 题解&#xff1a;统计带头节点的单链表L的实际元素个数 代码解答 详细解释 举例说明 &#x1f308; 嗨&#xff0c;我是命运之光&#xff01; &#x1f30c; 2024&#xff0c;每日百…

第二证券:沪指涨0.31%,电力、煤炭等板块拉升,卫星导航概念活跃

7日早盘&#xff0c;沪指盘中发力上扬&#xff0c;深证成指、创业板指震荡翻绿&#xff0c;场内超2700只个股飘绿。 到午间收盘&#xff0c;沪指涨0.31%报2876.17点&#xff0c;深证成指跌0.04%&#xff0c;创业板指跌0.16%&#xff0c;上证50指数涨0.34%&#xff0c;两市算计…

Leetcode每日刷题之字符串相加(C++)

在学习的同时也不要忘记适当练习&#xff0c;本题字符串相加主要在于字符串类型与整数类型的转化&#xff0c;要将字符串类型转化为整数类型计算后转化为字符串类型输出即可。 思路解析 根据题中给出的信息&#xff0c;我们不可以使用库函数计算大整数&#xff0c;也不能直接将…

代码随想录算法训练营第四天(二)|面试题 02.07. 链表相交 142.环形链表II

面试题 02.07. 链表相交 题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环…

视频号直播回放怎么下载?

一、如果是下载自己直播回放视频&#xff1a; 方法一&#xff1a;视频号助手 打开网址&#xff1a;视频号助手 登陆账号后。下面路径&#xff0c;先点击成回放&#xff0c; 后就可以在下面路径&#xff0c;下载全场回放 但是这种有个缺点&#xff0c;就是不能分段下载。这样…

C语言----计算开机时间

计算开机时间 实例说明 编程实现计算开机时间&#xff0c;要求在每次开始计算开机时间时都能接着上次记录的结果向下记录。 实现过程&#xff1a; 1. 在TC中创建一个C文件。 2. 引用头文件&#xff0c;代码如下: #include <stdio.h> 3. 定义结构体time&#xff0c;用来…