当前位置: 首页 > news >正文

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存,我们完成了在Spring Boot中完成了对EhCaChe的使用,这篇,我们将对EhCache的进一步了解,也就是搭建一个EhCache的缓存集群。

集群

在搭建一个EhCache的时候,我们需要先了解,什么是集群?集群具有的特点?

什么是集群?以及集群的特点?

集群是值将多个独立的计算机节点连接在一起,通过网络协议协同工作,用以实现工共同的目标,在集群中,各个节点通过通信和协作来提供更高的性能,可用性和可扩展性。

集群可以用于各种不同领域,和应用场景,包括计算、存储、数据库、网络服务等,通过将各个节点组成集群,可以实现以下特点(或者成为好处):

  • 高性能: 集群可以将任务分配给不同的节点并行处理,从而进一步提高整体的计算能力和处理速度,通过增加节点的数量,可以进一步提高集群的性能。
  • 高可用性:集群中的节点可以相互备份和冗余,当某个节点发生故障时,其他节点可以接管其工作,保证系统的持续可用性。这种冗余机制可以提高系统的容错能力。
  • 可扩展性:通过向集群中添加新的节点,可以轻松的拓展系统的处理能力和存储容量,这种可拓展性可以使得集群能够应对不同增长的需求和负载。
  • 负载均衡:集群可以通过负载均衡算法将请求分发到不同节点上,从而平衡各个节点的负载,避免单个节点过载,提高系统的稳定性和性能。
  • 故障恢复:集群可以通过故障检测和自动恢复机制来处理节点故障,当某个节点发生故障的时候,集群可以自动将任务重新分配给其他正常工作的节点,从而实现故障的快速恢复。

集群demo的搭建

引入相关依赖:

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

application.properties配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create#logging.level.net.sf.ehcache=debug# 不同实例的配置
#spring.cache.ehcache.config=classpath:ehcache-1.xml
#spring.cache.ehcache.config=classpath:ehcache-2.xml# 用不同命令启动不同实例
#-Dserver.port=8001 -Dspring.cache.ehcache.config=classpath:ehcache-1.xml
#-Dserver.port=8002 -Dspring.cache.ehcache.config=classpath:ehcache-2.xml

创建一个User实体类:

@Entity
public class User implements Serializable {@Id@GeneratedValueprivate Long id;private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public User() {}
}

创建一个User实体的数据访问实现

//插入缓存注解
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository<User, Long> {@CacheableUser findByName(String name);
}

在resources目录下分别创建ehcache-1.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd"><!--这里的users对应我们常用的--><cache name="users"maxEntriesLocalHeap="200"timeToLiveSeconds="600"><cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=false,replicateRemovals=true "/></cache><cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=10.10.0.100,port=40001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//10.10.0.101:40001/users" /></ehcache>

创建另一个ehcache-2.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd"><cache name="users"maxEntriesLocalHeap="200"timeToLiveSeconds="600"><cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=false,replicateRemovals=true "/></cache><cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=10.10.0.101,port=40001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//10.10.0.100:40001/users" /></ehcache>

cache标签中定义名为users的缓存,这里我们增加了一个子标签定义cacheEventListenerFactory,这个标签主要用来定义缓存事件监听的处理策略,它有以下这些参数用来设置缓存的同步策略:
replicatePuts:当一个新元素增加到缓存中的时候是否要复制到其他的peers。默认是true。
replicateUpdates:当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。
replicateRemovals:当元素移除的时候是否进行复制。默认是true。
replicateAsynchronously:复制方式是异步的指定为true时,还是同步的,指定为false时。默认是true
replicatePutsViaCopy:当一个新增元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。
replicateUpdatesViaCopy:当一个元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。
新增了一个cacheManagerPeerProviderFactory标签的配置,用来指定组建的集群信息和要同步的缓存信息,其中:
hostName:是当前实例的主机名
port:当前实例用来同步缓存的端口号
socketTimeoutMillis:同步缓存的Socket超时时间
peerDiscovery:集群节点的发现模式,有手工与自动两种,这里采用了手工指定的方式
rmiUrls:当peerDiscovery设置为manual的时候,用来指定需要同步的缓存节点,如果存在多个用|连接

注意以上ip地址的分配

ok具体的配置我们已经配置完毕了,那么我们启动项目和添加测试类进行测试了:

@EnableCaching
@SpringBootApplication
public class Application {public static void main(String[] args) throws Exception {
//		LocateRegistry.createRegistry(Integer.valueOf(System.getProperty("rmi.port")));SpringApplication.run(Application.class, args);}@RestControllerstatic class HelloController {@Autowiredprivate UserRepository userRepository;@GetMapping("/create")public void create() {userRepository.save(new User("AAA", 10));}@GetMapping("/update")public User update() {User u1 = userRepository.findByName("AAA");u1.setAge(20);u1 = userRepository.save(u1);return u1;}@GetMapping("/find")public User find() {User u1 = userRepository.findByName("AAA");System.out.println("查询AAA用户:" + u1.getAge());return u1;}}
}

我们通过打包的方式运行我们的实例:

# 实例1
-Dspring.cache.ehcache.config=classpath:ehcache-1.xml
# 实例2 
-Dspring.cache.ehcache.config=classpath:ehcache-2.xml

在以上代码中,也就是我们常用的Controller层,主要围绕我们所说的命令参数,启动相关实例。

  • 调用实例1的/create接口,创建一条数据

  • 调用实例1的/find接口,此时会清除缓存中的User,同时同步缓存相关信息给另一个实例,在实例1中会存在我们常用的SQL语句。

  • 调用实例2的/find接口,由于缓存集群同步了User的信息,所以在实例2中的这次查询也不会出现SQL语句

以及创建一个测试类:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {@Autowiredprivate UserRepository userRepository;@Autowiredprivate CacheManager cacheManager;@Testpublic void test() throws Exception {System.out.println("CacheManager type : " + cacheManager.getClass());// 创建1条记录userRepository.save(new User("AAA", 10));User u1 = userRepository.findByName("AAA");System.out.println("第一次查询:" + u1.getAge());User u2 = userRepository.findByName("AAA");System.out.println("第二次查询:" + u2.getAge());}
}

在这里插入图片描述

注意,以上实例建议在多机的情况下进行,有云服务器就是使用云服务器,并配备好上述的Ip地址,方便集群之间进行通讯,通过打包的方式运行,可以帮助我们减少很多麻烦

相关文章:

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存&#xff0c;我们完成了在Spring Boot中完成了对EhCaChe的使用&#xff0c;这篇&#xff0c;我们将对EhCache的进一步了解&#xff0c;也就是搭建一个EhCache的缓存集群。 集群 在搭建一个EhCache的时候&#xff0c;我们需要先了解&…...

yolov5模型代码怎么修改

yaml配置文件 深度乘积因子 宽度乘积因子 所有版本只有这两个参数的不同&#xff0c;s m l x逐渐加宽加深 各种类型层参数对照 backbone里的各层&#xff0c;在这里解析&#xff0c;只需要改.yaml里的各层参数就能控制网络结构 修改网络结构 第一步&#xff1a;把新加的模块…...

VIM去掉utf-8 bom头

Windows系统的txt文件在使用utf-8编码保存时会默认在文件开头插入三个不可见的字符&#xff08;0xEF 0xBB 0xBF&#xff09;称为BOM头 BOM头文件 0.加上BOM标记&#xff1a; :set bomb 1.查询当前UTF-8编码的文件是否有BOM标记&#xff1a; :set bomb? :set bomb? 2.BOM头:文…...

Go 使用Viper处理Go应用程序的配置

在开发Go应用程序时&#xff0c;处理配置是一个常见的需求。配置可能来自于配置文件、环境变量、命令行参数等等。Viper是一个强大的库&#xff0c;可以帮助我们处理这些配置。 什么是Viper&#xff1f; Viper是一个应用程序配置解决方案&#xff0c;用于Go应用程序。它支持JS…...

hadoop安装网址

Hadoop是什么 1&#xff09;Hadoop是一个有Apache基金会所开发的分布式系统基础架构。 2&#xff09;主要解决海量数据的存储和海量数据的分析计算问题。 3&#xff09;广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念---Hadoop生态圈。 Hadoop发行版本 Hadoop发行的…...

JavaMail邮件发送服务

记录一次使用基于SpringBoot来设置发送邮件的服务 导入依赖 <!--邮件发送--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>${springboot.version}</ve…...

【918.环形子数组的最大和】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:int maxSubarraySumCircular(vector<int>& nums) {int sum0;for(auto x:nums) sumx;vector<int> f(nums.size());vector<int> g(nums.size…...

Unity Quaternion接口API的常用方法解析_unity基础开发教程

Quaternion接口的常用方法 Quaternion.Euler()Quaternion.Lerp()Quaternion.Inverse()Quaternion.RotateTowards() Quaternion在Unity中是一种非常重要的数据类型&#xff0c;用于表示3D空间中的旋转。Quaternion可以表示任何旋转&#xff0c;无论是在哪个轴上旋转多少度&#…...

Rust开发——使用rust实现Redis中hset

一、Redis中hset HSET 是 Redis 中用于在哈希数据结构中设置指定字段的值的命令。哈希是一种类似于字典或映射的数据结构&#xff0c;它存储了键值对的集合&#xff0c;其中每个键都包含多个字段和与这些字段相关联的值。 哈希表在 Redis 中以键值对形式存储&#xff0c;并通…...

海康Visionmaster-环境配置:VB.Net 二次开发环境配 置方法

Visual Basic 进行 VM 二次开发的环境配置分为三步。 第一步&#xff0c;使用 VS 新建一个框架为.NET Framework 4.6.1&#xff0c;平台去勾选首选 32 为的工程&#xff0c;重新生成解决方案&#xff0c;保证工程 Debug 下存在 exe 文件&#xff0c;最后关闭新建工程&#xff1…...

51单片机应用从零开始(四)

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;三&#xff09;-CSDN博客 详解 KEIL C51 软件的使用建立工程-CSDN博客 详解 KEIL C51 软件的使用设置工程编绎与连接程序…...

Django下的Race Condition漏洞

目录 环境搭建 无锁无事务的竞争攻击复现 无锁有事务的竞争攻击复现 悲观锁进行防御 乐观锁进行防御 环境搭建 首先我们安装源码包&#xff1a;GitHub - phith0n/race-condition-playground: Playground for Race Condition attack 然后将源码包上传到Ubuntu 为了方便使…...

【数据结构】希尔排序(最小增量排序)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…...

Android Native崩溃信息分析和 工具(addr2line和ndkstack)使用

这里以一个实际的crash案例未demo进行分析和讲解。针对native的崩溃信息。一般来讲&#xff0c;较快的方式是直接检索到backtrace&#xff0c;然后通过分析和使用工具addr2line和 ndk-stack等定位到出问题的地方。这里截取了一段 崩溃日志&#xff0c;具体如下&#xff1a; 01…...

2023年05月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 明明每天坚持背英语单词,他建立了英语单词错题本文件“mistakes.txt”,将每天记错的单词增加到该文件中,下列打开文件的语句最合适的是?( ) A: f = open(“mistakes.txt”) B: …...

SQLite3 数据库学习(文章链接汇总)

参考引用 SQLite 权威指南&#xff08;第二版&#xff09;SQLite3 入门 SQLite3 数据库学习&#xff08;一&#xff09;&#xff1a;数据库和 SQLite 基础 SQLite3 数据库学习&#xff08;二&#xff09;&#xff1a;SQLite 中的 SQL 语句详解 SQLite3 数据库学习&#xff08;三…...

【VSCode】Visual Studio Code 下载与安装教程

前言 Visual Studio Code&#xff08;简称 VS Code&#xff09;是一个轻量级的代码编辑器&#xff0c;适用于多种编程语言和开发环境。本文将介绍如何下载和安装 Visual Studio Code。 下载安装包 首先&#xff0c;我们需要从官方网站下载 Visual Studio Code 的安装包。请访…...

分布式教程从0到1【1】分布式基础

1 分布式基础概念 1.1 微服务 微服务架构风格&#xff0c;就像是把一个单独的应用程序开发为一套小服务&#xff0c;每个小服务运行在自己的进程中&#xff0c;并使用轻量级机制通信&#xff0c;通常是 HTTP API。这些服务围绕业务能力来构建&#xff0c;并通过完全自动化部署…...

Ubuntu22.04 部署Mqtt服务器

1、打开Download EMQX &#xff08;www.emqx.io&#xff09;下载mqtt服务器版本 2、Download the EMQX repository curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash 3.Install EMQX sudo apt-get install emqx 4.Run EMQX sudo systemctl start…...

HMM与LTP词性标注之LTP介绍

文章目录 LTP 上图缺点&#xff1a;参数太多&#xff0c;中文语料库匮乏 注意力机制&#xff0c;相当于给每一个词赋予一个权重&#xff0c;权重越大的越重要。 bert的缺点&#xff1a;神经元太多&#xff0c;较慢。 LTP 如果只是需要做词性的识别&#xff0c;那么用LTP就可…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...