【微服务】springboot整合redis哨兵集群使用详解

news/2024/7/7 14:00:52/文章来源:https://blog.csdn.net/zhangcongyi420/article/details/131881510

目录

一、前言

二、环境准备

三、安装redis

3.1 前置准备

3.1.1 下载安装包

3.1.2 准备依赖环境

3.1.3 上传并解压包

3.2 执行安装

四、搭建redis主从集群

4.1 环境准备

4.2 搭建过程

4.2.1 创建实例文件目录

4.2.2 修改redis.conf配置文件

4.2.3 拷贝配置文件

4.2.4 修改配置文件端口信息

4.2.5 修改声明的IP地址

4.2.6 启动redis实例

4.2.7 开启主从关系

五、搭建redis哨兵集群

5.1 添加哨兵配置文件

5.1.1 在三个目录下添加配置文件

5.1.2 拷贝配置文件

5.2 启动哨兵集群

5.3 故障模拟

5.3.1 哨兵控制台日志

5.4 故障恢复

5.4.1 哨兵控制台日志

六、springboot整合redis哨兵集群

6.1 前置准备

6.1.1 搭建一个springboot工程

6.1.2 引入核心依赖

6.2 核心代码

6.2.1 哨兵配置类

6.2.2 redistemplate配置类

6.2.3 添加测试接口

6.2.4 接口正常效果测试

6.2.5 接口异常效果测试一

6.2.6 重新恢复之前的master节点

6.2.7 接口异常效果测试二

七、写在文末


一、前言

对于大多数开发的同学来说,redis再熟悉不过了,基本上来说,在一个微服务项目中,redis几乎成了标配,经验来看,redis大多数作为缓存来使用,而且使用起来学习成本可以说很低了。通常来说,为了确保redis的高可用性,生产环境夏一般会使用集群模式,这个需要结合项目自身的情况选择,比如你的项目主要是为了应对高并发读,主从集群即可满足,而如果你的项目不仅读写频繁,而且需要存储的缓存数量也很大,可能cluster集群模式更适合你。本篇将以redis的哨兵集群为例,从搭建到与springboot的整合做详细的说明。

二、环境准备

基于centos7的虚拟机,或云服务器一台(至少一台)。

三、安装redis

3.1 前置准备

3.1.1 下载安装包

选择合适的版本进行下载,下载地址:Index of /releases/1604emgaMTkzMDcyNTg1NC4xNjY3ODkyODY2ga_8BKGRQKRPV*MTY4NzMxMzg1OC43LjEuMTY4NzMxMzg4NS4zMy4wLjA.

3.1.2 准备依赖环境

执行命令:yum install -y gcc tcl

3.1.3 上传并解压包

tar -zxvf redis-6.2.11

cd redis-6.2.11

3.2 执行安装

进入到解压后的主目录,执行下面的命令

make && make install

看到下面的效果,说明安装成功

四、搭建redis主从集群

4.1 环境准备

我们知道,哨兵集群的目的是为了监控主从集群中的master节点的状态,一旦master节点挂掉了,可以迅速选出一个新的主节点,从而坐到自动故障切换,所以需要先搭建一个主从集群,规划如下

机器地址端口角色
192.168.9.1317001master
192.168.9.1317002slave
192.168.9.1317003slave

4.2 搭建过程

4.2.1 创建实例文件目录

在主目录下创建3个文件夹,分别为7001,7002,7003,文件名称可以自定,这里是为了方便区分多个实例,通过端口号的形式命名;

mkdir 7001 7002 7003

4.2.2 修改redis.conf配置文件

备份一下原始的redis主目录中的redis.conf文件没然后编辑redis.conf文件,修改下面两行配置

bind 0.0.0.0protected-mode no  #本地测试验证吗,暂时关掉包含模式

4.2.3 拷贝配置文件

从redis的主目录中拷贝redis.conf文件分别到7001,7002,7003中

cp  redis.conf ./7001

cp  redis.conf ./7002

cp  redis.conf ./7003

4.2.4 修改配置文件端口信息

由于这里是单机,为了区分多个实例,以端口来区分,分别进入到3个目录下,将端口号修分别修改为 7001,7002,7003,主要修改里面的端口号,依次修改为7001,7002,7003,其他的配置暂时不做修改;

也可以通过下面的命令进行批量修改

sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \//usr/local/redis/7001\//g' slave1/redis.conf
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \//usr/local/redis/7002\//g' slave2/redis.conf
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \//usr/local/redis/7003\//g' slave3/redis.conf

4.2.5 修改声明的IP地址

虚拟机本身存在多个IP,为了避免将来混乱,需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:

replica-announce-ip 当前IP

仍然可以使用批量修改的方式进行编辑

sed -i '1a replica-announce-ip 120.26.108.145' 7001/redis.conf
sed -i '1a replica-announce-ip 120.26.108.145' 7002/redis.conf
sed -i '1a replica-announce-ip 120.26.108.145' 7003/redis.conf

4.2.6 启动redis实例

上面的配置就完成了,在主目录下执行下面的命令依次启动3个redis实例,我这里使用的是后台启动,也可以直接前台启动,去掉nohup即可;

nohup redis-server /usr/local/redis/7001/redis.conf &
nohup redis-server /usr/local/redis/7002/redis.conf &
nohup redis-server /usr/local/redis/7003/redis.conf &

通过ps查看进程,可以看到3个实例都已经起来了

4.2.7 开启主从关系

上面启动了3个实例,但是他们之间还并没有形成主从关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。

有临时和永久两种模式:

  • 修改配置文件(永久生效),在redis.conf中添加一行配置: slaveof <masterip> <masterport>;
  • 使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效): slaveof <masterip> <masterport>;

这里为了演示看出效果,我们采用第二种方式进行说明,在任意的shelli窗口,执行redis-cli命令连接7002,执行下面的命令:

redis-cli -p 7002

然后通过命令:info repliaction可以检查当前实例的身份

在另一个窗口连接7003这个实例客户端,使用相同的方式操作即可,到这里,一主两从的主从集群就搭建好了,当然也可以验证下效果,比如在从节点的命令行中,set一个key,可以看到下面的效果;

五、搭建redis哨兵集群

基于上述已经搭建好的主从集群模式下,开始搭建哨兵集群,关于哨兵集群的原理相关的知识,有兴趣的同学可以参考相关的资料,网上比较丰富;

5.1 添加哨兵配置文件

5.1.1 在三个目录下添加配置文件

在7001,7002,7003三个目录下,分别添加一个 sentinel.conf的文件,以7001目录的该配置为例,将下面的配置拷贝进去

port 27001
bind 0.0.0.0 #云服务测试的时候建议这样配置
sentinel announce-ip #"你的IP"
sentinel monitor mymaster #你的IP 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/usr/local/redis/7001"

关于上述配置算是极简版的,对各项内容简单说明一下:

  • port 27001:是当前sentinel实例的端口

  • sentinel monitor mymaster IP 7001 2:指定主节点信息

  • mymaster:主节点名称,自定义,任意写

  • IP 7001:主节点的ip和端口

  • 2:选举master时的quorum值

5.1.2 拷贝配置文件

然后将7001目录下的该配置文件依次拷贝到其他3个目录下,拷贝过去之后,注意修改下面两个地方,即端口号和dir的位置,本次哨兵的三个端口为:27001,27002,27003;

5.2 启动哨兵集群

在当前主目录下依次执行下面的3行命令,启动3个哨兵

redis-sentinel 7001/sentinel.conf
redis-sentinel 7002/sentinel.conf
redis-sentinel 7003/sentinel.conf

3个哨兵启动后效果依次如下,可以看到各自监听的端口;

 

5.3 故障模拟

下面将主节点7001的redis实例对应的进程kill掉,然后看看哨兵控制台的日志信息变化如何 

5.3.1 哨兵控制台日志

kill掉7001的实例之后,通过控制台日志,可以捕获到sentinel的关键日志信息,但是每个sentinel的日志信息稍有差异,从上到小,分别为监控的7001~7003的三个redis实例的sentinel日志信息;

关于里面的日志内容,有兴趣的同学可以参阅相关的资料进行深入的学习和解读,这些日志的输出其实也就是redis哨兵集群进行master节点选举的完整流程;

5.4 故障恢复

通过上述的命令再次开启7001的实例;

5.4.1 哨兵控制台日志

再次启动7001的实例后,不难发现,此时被sentinel集群监控到了,但是此时只能作为一个slave的角色加入到集群中,如下展示了三个sentinel实例监控时的日志信息,从上到下,分别为监控的7001~7003的三个redis实例的sentinel日志信息;

如果我们再次使用redis-cli命令登录到7002的客户端,使用info命令查看一下,可以看到此时的7002已经成为master节点,这个与sentinel中输出的日志信息也是吻合的;

六、springboot整合redis哨兵集群

搭建完成了哨兵集群后,接下来演示下如何在微服务中整合使用。

6.1 前置准备

6.1.1 搭建一个springboot工程

完整的工程目录如下

6.1.2 引入核心依赖

引入必须的jar,其他的可以根据自身情况引入

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency></dependencies>

6.2 核心代码

6.2.1 哨兵配置类

添加一个哨兵配置类,用于配置哨兵相关的信息

package com.congge.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;import java.util.HashSet;
import java.util.List;
import java.util.Set;@Configuration
@EnableAutoConfiguration
public class RedisSentinelConfig {private static Logger logger = LoggerFactory.getLogger(RedisSentinelConfig.class);@Value("#{'${spring.redis.sentinel.nodes}'.split(',')}")private List<String> nodes;@Value("${spring.redis.sentinel.nodes}")private String redisNodes;@Value("${spring.redis.sentinel.master}")private String master;//redis的连接池@Bean(name = "poolConfig")@ConfigurationProperties(prefix = "spring.redis")public JedisPoolConfig poolConfig() {JedisPoolConfig poolConfig = new JedisPoolConfig();return poolConfig;}@Beanpublic RedisSentinelConfiguration sentinelConfiguration() {RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();//配置matser的名称redisSentinelConfiguration.master(master);//数据库是1库redisSentinelConfiguration.setDatabase(1);//配置redis的哨兵sentinelSet<RedisNode> redisNodeSet = new HashSet<>();nodes.forEach(x -> {redisNodeSet.add(new RedisNode(x.split(":")[0], Integer.parseInt(x.split(":")[1])));});logger.info("redisNodeSet -->" + redisNodeSet);redisSentinelConfiguration.setSentinels(redisNodeSet);return redisSentinelConfiguration;}@Bean("redisConnectionFactory")public JedisConnectionFactory redisConnectionFactory(JedisPoolConfig poolConfig,RedisSentinelConfiguration sentinelConfig) {return new JedisConnectionFactory(sentinelConfig, poolConfig);}
}

6.2.2 redistemplate配置类

在该配置类中针对ke/value进行序列化相关设置,非必须,如果不设置将会使用java默认的序列化;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {/*** 方法描述: 初始化redis连接* @param redisConnectionFactory redis连接工厂* @return {@link RedisTemplate}*/@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 新建redisTemplate对象RedisTemplate<String, Object> template = new RedisTemplate<>();// 设置工厂template.setConnectionFactory(redisConnectionFactory);//序列化配置Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的//2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。//3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。//如果Key的Serializer也用和Value相同的Serializer的话,在Redis中保存的内容和上面Value的差异是一样的,所以我们保存时,只用StringRedisSerializer进行序列化// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(stringRedisSerializer);// 返回redisTemplate对象return template;}
}

6.2.3 添加测试接口

增加一个测试接口,测试在接口中操作哨兵集群

@RestController
@RequestMapping("/redis")
public class RedisController {@Autowiredprivate RedisTemplate redisTemplate;//localhost:8083/redis/setValue?key=address&value=hangzhou@GetMapping("setValue")public String setValue(String key,String value) {redisTemplate.opsForValue().set(key, value);return "true";}//localhost:8083/redis/getValue?key=address@GetMapping("getValue")public String getValue(String key) {String value = (String) redisTemplate.opsForValue().get(key);System.out.println(value);return value;}}

6.2.4 接口正常效果测试

启动工程后,调用上面的接口

 sentinel客户端窗口日志信息

浏览器中请求如下接口,向集群中插入一条数据

接口执行成功后,再执行查询接口,可以查到上述插入到集群中的key

同时可以登录redis的客户端,检查上述插入的key/value

 

6.2.5 接口异常效果测试一

将master节点进程强制kill掉,

kill掉master进程之后,集群存在一个短暂的重新选举的过程

然后触发重新选举master的过程

请求接口后控制台输出的日志,由于master被kill掉,会重新建立连接信息

如果在此期间继续向集群执行写入操作,将会存在短暂的不可用的过程,等到集群重新选出master节点之后,接口又可以重新写入数据了,而对于客户端来说,这个是无感知的,因为客户端并不关心数据写入到哪个节点上,从上面的选举来看,7002这个slave节点的实例被选举为主节点; 

6.2.6 重新恢复之前的master节点

再次启动7001的redis实例后,sentinel集群会重新发起选举,7001不再是master,而是作为7002实例的slave节点加入集群;

选举完成后,可以再次请求接口执行数据写入

 

登录到7002的客户端,可以看到数据写入成功

 

6.2.7 接口异常效果测试二

在集群模拟异常测试过程中,出现过下面的错误,这里贴出异常信息,大概的意思是,客户端写redis的时候,连接到了集群的从节点,默认情况下,哨兵集群中的从节点是没有写数据权限的;

 

关于这个异常,网上也有一些同学遇到过,大致的解决方案如下:

  • 配置sentinel.conf时,没有设置密码,所以需要在配置哨兵文件时增加密码的设置:sentinel auth-pass mymaster 123456;
  • 如果是阿里云或其他云服务器,可能是安全组中sentinel的端口没有开放,需要开放响应的端口;

该问题也是小编在实际工作中遇到的一个问题,对于这个问题,我在上面的故障模拟中的分析结论如下:

  • 网络延迟有点大,当网络延迟太大造成哨兵之间感知的时间超过了哨兵配置的故障转移时间,这种情况下,可能会造成选举时间过长而失败;
  • Redis主节点出现网络故障,与哨兵节点失联,这种情况下,哨兵无法获取主节点的信息,因此无法对主节点进行健康检查,并在需要时执行故障转移操作;
  • Redis哨兵节点自身故障,导致哨兵节点无法在集群中正常工作;

遇到上述问题的时候,为了尽量减少问题面的扩散,建议的做法是:

  • 排查网络,确认哨兵所在机器的网络是否有问题;
  • 检查redis集群自身的状况,看看主从集群的关系是否出现故障;
  • 如果确认了前两步没什么问题的情况下,建议重启哨兵;

七、写在文末

哨兵集群是一种非常重要的redis集群模式,这是一种高可用集群的常用部署方式,有必要深入的学习并掌握,希望对看到的同学有用,本篇到此结束,感谢观看!

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

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

相关文章

小C说历史(人物介绍第一篇):传奇人物Linus Torvalds 缔造Linux和Git

传奇人物Linus Torvalds 缔造Linux和Git Linus Torvalds&#xff0c;1969年12月28日出生于芬兰的赫尔辛基&#xff0c;Linux核心的创作者。当Linus十岁时&#xff0c;他的祖父&#xff0c;赫尔辛基大学的一位统计教授&#xff0c;购买了一台Commodore VIC-20计算机。Linus帮助他…

【波浪动态特效】基于jquery实现页面底部波浪动画效果(附完整源码下载)

文章目录 写在前面涉及知识点实现效果1、搭建页面1.1、创建两个片区1.2、创建波浪区域1.3、静态页面源码 2、JS实现波浪效果2.1 动画原理2.2 动画源码 3、源码分享3.1 百度网盘3.2 123云盘3.3 邮箱留言 总结 写在前面 想必搭建过企业官网的大多数对这个效果不陌生吧&#xff0…

vue中显示在页面顶部的进度条插件——NProgress

我们在一些网站中经常见到导航栏上方的进度条显示&#xff0c;大家仔细观察&#xff0c;其实csnd中也有类似的效果&#xff0c;如下图显示效果&#xff0c;我们现在就来一起看看这个功能需求是怎么实现的。 一、功能需求 首先&#xff0c;实现这个功能其实不难&#xff0c;说实…

C# Microsoft消息队列服务器的使用 MSMQ

先安装消息队列服务器 private static readonly string path ".\\Private$\\myQueue";private void Create(){if (!MessageQueue.Exists(path)){MessageQueue.Create(path);}}private void Send(){Stopwatch stopwatch new Stopwatch();stopwatch.Start();Message…

动画制作选择Blender还是Maya

Blender和Maya是两种最广泛使用的 3D 建模和动画应用程序。许多经验丰富的用户表示&#xff0c;Blender 在雕刻工具方面远远领先于 Maya&#xff0c;并且在 3D 建模方面达到了相同的质量水平。对于刚接触动画行业的人来说&#xff0c;您可能会问“我应该使用 Blender 还是 Maya…

复习之vsftp服务

一、vsftp服务简介 文件传输协议&#xff08;File Transfer Protocol&#xff0c;FTP&#xff09;是用于在网络上进行文件传输的一套标准协议&#xff0c;它工作在 OSI 模型的第七层 即应用层&#xff0c; 使用 TCP 传输而不是 UDP&#xff0c; 客户在和服务器建立连接前要经过…

mac电脑访问windows共享文件夹连接不上(设置445端口)

前提&#xff1a;首先需要保证mac和windows都在同一局域网内&#xff0c;如果不在肯定是连不上的&#xff0c;就不用往下看了。 事情是这样的&#xff0c;公司入职发了mac电脑&#xff0c;但是我是window重度用户&#xff0c;在折腾mac的过程中&#xff0c;有许多文件需要从wi…

运维作业4

一.简述静态网页和动态网页的区别。 静态页面资源特征 1. 处理文件类型&#xff1a;如.html、jpg、.gif、.mp4、.swf、.avi、.wmv、.flv等 2. 地址中不含有问号"&#xff1f;"或&等特殊符号。 3. 保存在网站服务器文件系统上的&#xff0c;是实实在在保存在服务器…

【有趣的】关于Map的一些小测试

Map在代码中用到得非常多&#xff0c;它是无序的、key-value结构的&#xff0c;其读取会非常快。 今天看了个小文章Map判空 、空字符串、空key值等各种判断方法&#xff0c;你都掌握了吗&#xff1f;便自己也玩一下。 一、判空 因为对象已经new出来了&#xff0c;所以map指向的…

Zabbix报警机制、配置钉钉机器人、自动发现、主动监控概述、配置主动监控、zabbix拓扑图、nginx监控实例

day02 day02配置告警用户数超过50&#xff0c;发送告警邮件实施验证告警配置配置钉钉机器人告警创建钉钉机器人编写脚本并测试添加报警媒介类型为用户添加报警媒介创建触发器创建动作验证自动发现配置自动发现主动监控配置web2使用主动监控修改配置文件&#xff0c;只使用主动…

汽车智能化再掀新热潮!「中央计算架构」进入规模量产周期

中央计算区域控制的新一代整车电子架构&#xff0c;已经成为车企继电动化、智能化&#xff08;功能上车&#xff09;之后&#xff0c;新一轮竞争的焦点。 如果说智能化的1.0阶段&#xff0c;是智能驾驶智能座舱的争夺战&#xff1b;那么&#xff0c;即将进入的2.0阶段&#xff…

爱尔眼科四川省区“同心博爱 光明工程”“西部健康公益行”炉霍站启动

8月1日&#xff0c;“同心博爱 光明工程”“西部健康公益行”炉霍站出征仪式在四川爱尔眼科医院隆重举行。 此次公益活动由民革成都市委会、中共锦江区委统战部指导&#xff0c;如意树爱心促进会主办&#xff0c;民革锦江区总支部、爱尔眼科四川省区支持&#xff0c;四川爱尔眼…

SCI论文的发文的模板(Elsevier,MDPI,IEEE)

不同的SCI期刊都有自己的出版商&#xff0c;不同的出版商有不同的发文格式。 最简单的方式就是去查官网上面&#xff0c;常用的期刊格式如下。到对应的位置下载模板即可&#xff0c;推荐使用latex。 MDPI MDPI | Preparing Manuscripts in LaTeX Elsevier Guide for authors …

【Linux指令篇】--- Linux常用指令汇总(克服指令繁杂问题)

文章目录 前言&#x1f31f;一、Linux基本指令&#x1f31f;二、ls指令&#x1f30f;2.1.语法&#xff1a;&#x1f30f;2.2.功能&#xff1a;&#x1f30f;2.3.常用选项&#xff1a; &#x1f31f;三、pwd指令&#x1f30f;3.1.语法&#xff1a;&#x1f30f;3.2.功能&#xf…

C++11 通用工具

通用工具 目录 pair和tuple智能指针数值极值type trait 和type utility辅助函数clock和timerbitset随机数 1 pair和Tuple 1.1 pair 头文件 #include<utility>pair定义 pair<string,string> author{James","joyce"};)] --> pair操作 1.2 tup…

100 个鲜为人知的 Python 高级技巧 0-20

100 鲜为人知的 Python 功能 这篇文章是为那些每天使用 Python&#xff0c;但从未真正坐下来通读所有文档的人准备的。 如果您已经使用 Python 多年&#xff0c;并且知道足够多的知识来完成工作&#xff0c;那么为了发现一些新技巧而通读几千页的文档可能不是明智之举。 因此&a…

【业务功能篇61】SpringBoot项目流水线 dependencyManagement 标签整改依赖包版本漏洞问题

业务场景&#xff1a;当前我们项目引入了公司自研的一些公共框架组件&#xff0c;比如SSO单点登录jar包&#xff0c;文件上传服务jar包等公共组件&#xff0c;开发新功能&#xff0c;本地验证好之后&#xff0c;部署流水线&#xff0c;报出一些jar包版本的整改漏洞问题&#xf…

变透明的黑匣子:UCLA 开发可解释神经网络 SNN 预测山体滑坡

内容一览&#xff1a;由于涉及到多种时空变化因素&#xff0c;山体滑坡预测一直以来都非常困难。深度神经网络 (DNN) 可以提高预测准确性&#xff0c;但其本身并不具备可解释性。本文中&#xff0c;UCLA 研究人员引入了 SNN。SNN 具有完全可解释性、高准确性、高泛化能力和低模…

Spring系列二:基于注解配置bean【建议收藏】

文章目录 &#x1f497;通过注解配置bean&#x1f35d;基本介绍&#x1f35d;快速入门&#x1f35d;注意事项和细节 &#x1f497;自己实现Spring注解配置Bean机制&#x1f35d;需求说明&#x1f35d;思路分析&#x1f35d;注意事项和细节 &#x1f497;自动装配 Autowired&…

P3373 【模板】线段树 2(乘法与加法)(内附封面)

【模板】线段树 2 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面三种操作&#xff1a; 将某区间每一个数乘上 x x x&#xff1b;将某区间每一个数加上 x x x&#xff1b;求出某区间每一个数的和。 输入格式 第一行包含三个整数 n , q , m n,q,m n,…