Springboot+ehcache 实现集群消息同步

SpringBoot 集成 Ehcache 实现本地缓存 EhCache是一种广泛使用的开源Java 分布式缓存。主要面向通用缓存、Java EE 和轻量级容器,可以和大部分 Java 项目无缝整合。Ehcache虽然也支持分布式模式,但是分布式方案不是很好,建议只将其作为单机的进程内缓存使用直接在 JVM 虚拟机中缓存,速度快,效率高支持多种缓存策略:LRU、LFU、FIFO 淘汰算法支持内存和磁盘存储,默认存储在内存中,如内存不够时把缓存数据同步到磁盘中;支持多缓存管理器实例,以及一个实例的多个缓存区域。 阅读详情

这个方式只适合两台服务器,多台不适用

近期由于项目上使用了集群方式部署,而我的项目中又用到了ehcache缓存,所有就要实现在集群中如何同步消息的问题。下面就是我的解决方案

使用 JGroups 集群配置

下面我们看具体步骤

1.添加pom依赖

        <!-- JGroups for Ehcache clustering -->
        <dependency>
        <groupId>org.jgroups</groupId>
        <artifactId>jgroups</artifactId>
        <version>3.6.13.Final</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-jgroupsreplication</artifactId>
            <version>1.7</version>
        </dependency>

2.修改ehcache.xml的配置

我们有两台服务器,所有在配置上稍微有点区别

192.168.1.10的配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir"/>
    <!-- JGroups 集群配置(两台服务器使用相同配置) -->
   
    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
            properties="connect=TCP(bind_addr=192.168.1.10;bind_port=17800;port_range=20):
                    TCPPING(initial_hosts=192.168.1.10[17800],192.168.1.9[17800];
                    port_range=0;timeout=3000):
                    MERGE3(min_interval=10000;max_interval=30000):
                    FD_SOCK:FD_ALL(timeout=12000;interval=3000):
                    VERIFY_SUSPECT(timeout=3000):
                    pbcast.NAKACK2(use_mcast_xmit=false;xmit_interval=500):
                    UNICAST3:
                    pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=4M):
                    pbcast.GMS(join_timeout=10000;print_local_addr=true;max_join_attempts=10):
                    FRAG2(frag_size=60K):
                    pbcast.FLUSH"
            propertySeparator="::"/>

    <!-- 默认缓存 -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>

    <!-- 临时cache -->
    <cache name="temp_cache"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="1800"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>

    <!-- 持久化cache -->
    <cache name="eternal_cache"
           maxElementsInMemory="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="10">
    </cache>

    <!-- 字典cache -->
    <cache name="sys_dict"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="0"
           timeToLiveSeconds="0"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

 

    <!-- 验证码缓存cache -->
    <cache name="captcha_codes"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="180"
           timeToLiveSeconds="180"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LFU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

    <!-- 用户缓存cache -->
    <cache name="login_tokens"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="1800"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LFU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

 
</ehcache>

192.168.1.9的配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir"/>
    <!-- JGroups 集群配置(两台服务器使用相同配置) -->
   
    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
            properties="connect=TCP(bind_addr=192.168.1.9;bind_port=17800;port_range=20):
                    TCPPING(initial_hosts=192.168.1.10[17800],192.168.1.9[17800];
                    port_range=0;timeout=3000):
                    MERGE3(min_interval=10000;max_interval=30000):
                    FD_SOCK:FD_ALL(timeout=12000;interval=3000):
                    VERIFY_SUSPECT(timeout=3000):
                    pbcast.NAKACK2(use_mcast_xmit=false;xmit_interval=500):
                    UNICAST3:
                    pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=4M):
                    pbcast.GMS(join_timeout=10000;print_local_addr=true;max_join_attempts=10):
                    FRAG2(frag_size=60K):
                    pbcast.FLUSH"
            propertySeparator="::"/>

    <!-- 默认缓存 -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>

    <!-- 临时cache -->
    <cache name="temp_cache"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="1800"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>

    <!-- 持久化cache -->
    <cache name="eternal_cache"
           maxElementsInMemory="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="10">
    </cache>

    <!-- 字典cache -->
    <cache name="sys_dict"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="0"
           timeToLiveSeconds="0"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

 

    <!-- 验证码缓存cache -->
    <cache name="captcha_codes"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="180"
           timeToLiveSeconds="180"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LFU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

    <!-- 用户缓存cache -->
    <cache name="login_tokens"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="1800"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LFU">
        <persistence strategy="localTempSwap"/>
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=true,
                            replicatePuts=true,
                            replicateUpdates=true,
                            replicateUpdatesViaCopy=true,
                            replicateRemovals=true"/>
    </cache>

 
</ehcache>

两台服务器配置区别就在bind_addr,需要配置自己的ip,网上也有方式说是可以自动获取,我的服务器是双网卡,我试了之后不太好使,所有就写死了。

上面就是两台服务器之前实现ehcache消息同步的方法,这个方案也适用两台服务器多个子系统间ehcache同步

数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现 前两章我们讲到了关于图的基本知识,和广度/深度优先搜索。本章,我们将介绍加权图和最短路径的相关知识。最短路径和最小生成树是图论中常见的问题。最短路径是指在一个图中找到两个节点之间的最短路径,最小生成树是指在一个图中找到一个连通子图,使得所有节点都能够互相到达,且总权值最小。最短路径算法常见的有floyd算法(弗洛伊德算法)和 dijkstra算法(迪杰斯特拉)。本文只介绍dijkstra算法。最短路径运用非常广泛,比如在导航系统中,确定两个地点间哪条路线最短; 阅读详情

相关推荐

V-REP(Cooprliesim EDU)自学笔记 实现UR5机械臂末端按轨迹移动

V-REP(Cooprliesim EDU)自学笔记 实现UR5机械臂末端按轨迹移动

xu_white的博客 7583

Ehcache原理详细解读

文章目录1 统计代码耗时1.1 前言1.2 常规方法1.2.1 时间差统计1.2.2 StopWatch 1 统计代码耗时 今天跟大家分享一下,如何在代码中,统计接口耗时,最优雅,性能最高,接下来我将介绍4种统计方式。 1.1 前言 代码耗时统计在日常开发中算是一个十分常见的需求,特别是在需要找出代码性能瓶颈时。 可能也是受限于 Java 的语言特性,总觉得代码写起来不够优雅,大量的耗时统计代码,干扰了业务逻辑。特别是开发功能的时候,有个感受就是刚刚开发完代码很清爽优雅,结果加了一大堆辅助代码后,整个代码就

上善若泪 2359

编程小白的自学笔记四(正则表达式模块search函数)

本文仅仅简单介绍了search的使用,供小白学习探讨。

m0_49914128的博客 2323

SpringBoot + EhCache实现本地缓存

一、EhCache 介绍 1.1 什么是EhCache ? EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。 Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache)

oyc的博客 2697

LLC电路细讲笔记(二)LLC谐振转换器:频率、增益与Q值的详细探讨

这本电子书通过详细分析LLC谐振转换器的工作原理、等效电路和增益公式,帮助读者深入理解如何设计和优化谐振转换器系统。通过这些公式和设计方法,工程师可以根据不同的应用需求调整参数,实现高效的电能转换。

weixin_43199439的博客 6904

【20260309】【亲测可用】【异常】Get https://registry-1.docker.io/v2/: net/http: request canceled

【异常】Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection。

奶爸的编程之路,也就一周冷个三天 2万+

(七)整合 Redis集群 ,实现消息队列场景

整合 Redis集群 ,实现消息队列场景1、Redis集群简介1.1 RedisCluster概念2、SpringBoot整合Redis集群2.1 核心依赖2.2 核心配置2.3 参数渲染类2.4 集群配置文件2.5 配置Redis模板类3、模拟队列场景案例3.1 加锁解锁工具3.2 消息消费3.3 消息监听器3.4 消息生产者3.5 场景测试接口 1、Redis集群简介 1.1 RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当一个服

爱是与世界平行 1237

Agentic AI商业化落地指南:提示工程架构师的7步优化法

Agentic AI(具备自主感知、决策与行动能力的智能体系统)是未来AI商业化的核心方向,其价值在于将大模型的“认知能力”转化为“实际行动”,解决复杂商业场景中的自动化与个性化需求。而提示工程(Prompt Engineering)作为连接人类意图与智能体行为的“翻译器”,直接决定了智能体的可控性、效率与用户体验,是Agentic AI商业化落地的关键支撑。本文结合第一性原理与工程实践,提出提示工程架构师的“7步优化法”,覆盖从“商业目标定义”到“规模化推广”的全流程。通过理论框架推导架构设计拆解。

AI架构全栈开发实战笔记 1万+

SpringBoot缓存技术选型:Redis集群与本地缓存Ehcache深度对比

在当今的软件开发中,缓存技术是提升系统性能的关键手段之一。在Spring Boot应用开发里,合理选择缓存技术能够显著减少数据库访问压力,加快数据响应速度。本文将深入探讨两种常见的缓存技术:Redis集群和本地缓存Ehcache,分析它们各自的特点、适用场景,并通过详细的代码示例和性能对比,为技术人员在Spring Boot项目中选择合适的缓存方案提供参考。

梵心白莲的博客 945

基于深度学习的茶叶等级检测识别系统:YOLOv10 + UI界面 + 数据集

YOLOv10是YOLO系列的最新版本,继承了YOLO模型的优点,并对速度和精度进行了优化。YOLOv10在目标检测中使用卷积神经网络(CNN)作为基础,通过改进网络结构和优化训练策略,实现了在更低的延迟下进行高精度的目标检测。本文详细介绍了基于YOLOv10的茶叶等级检测与识别系统的设计与实现过程。我们从数据集准备、模型训练与推理、UI界面设计等多个方面进行了详细讲解,并给出了相应的代码实现。通过本系统,我们可以高效地自动检测茶叶的等级,并通过UI界面直观地展示结果。

YOLO 765

Calibre:LVS 快速debug short/open技巧

用Fix Suggestion和Short Isolate两种方法debug LVS问题

m0_61544122的博客 7462

SpringBoot缓存技术选型:Redis+Ehcache+Guava性能对比

在当今的软件开发中,缓存技术是提升系统性能的关键手段之一。在Spring Boot项目里,合理地使用缓存能够显著减少数据库的访问次数,降低系统响应时间,提高系统的吞吐量。常见的缓存技术有Redis、Ehcache和Guava,它们各自有着不同的特点和适用场景。本文将对这三种缓存技术在Spring Boot中的应用进行性能对比,帮助技术人员在实际项目中做出更合适的缓存技术选型。

梵心白莲的博客 1030

Multisim14使用教程详尽版--(2025最新版)

摘要:本文详细介绍了Multisim14电路仿真软件的功能和使用方法。主要内容包括:1)主流电路仿真软件比较,突出Multisim在教学、竞赛设计中的优势;2)软件界面说明,涵盖菜单栏、工具栏、元器件库和仪器仪表;3)18类元器件分类详解及其使用操作;4)15种仪器仪表的原理和应用场景;5)电路原理图设计与仿真流程;6)基本电路分析方法(直流静态工作点分析、交流分析等)。文章还提供了硬件工程师笔试面试相关资源链接,涵盖电阻、电容、三极管等器件知识及AD软件操作指南。通过系统讲解,帮助用户掌握Multisim

XU157303764的博客 2万+

Ehcache、Redis应用场景比较

转自:https://blog.youkuaiyun.com/ShiXueTanLang/article/details/79596198 1. Ehcache简介 EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它...

u012501054的博客 293

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SpringBoot项目里,除了Redis,我为什么还选了Ehcache 3.x做本地缓存?

本文探讨了在SpringBoot项目中结合使用Redis和Ehcache 3.x构建混合缓存架构的优势与实践。通过对比分析,Ehcache 3.x作为本地缓存可显著降低响应时间至纳秒级,特别适合高频访问数据。文章详细介绍了Ehcache的核心特性、SpringBoot集成方法以及缓存一致性解决方案,为开发者提供了性能优化的实用指南。

weixin_30729609的博客 411

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

springboot集成ehcache_SpringBoot原理

前言​ java因为众多优秀好用的开源框架和工具而保持活力,然而如此众多的框架使用均有各自的配置文件,并且当框架之间集成时需要匹配的版本号,我们想一个工程只配置一次,可不可以不要这么麻烦。dao层:hibernate、mybatis、springData service:spring web表现层:springMVC Web服务器:tomcat和Nginx 微服务:Zookeeper、Dubb...

weixin_39739395的博客 118

27-多级缓存架构-服务本地堆缓存:完成spring boot整合ehcache,基于kafka+ehcache+redis完成缓存数据生产服务的开发与测试

首先是kafka与zookeeper集群的搭建我们已经完成了在上一节中。这一章我们主要来实现代码整合Kafka,实现一个业务上的,从kafka获取监听到数据以后的业务逻辑。 1、将kafka整合到spring boot中 <dependency> <groupId>org.apache.kafka</groupId> <artifa...

weixin_40663800的博客 441

Spring Boot 2.0.0.M7 使用 Caching-EhCache

Spring Boot 2.0.0.M7 用 Caching-EhCache更多干货spring-boot系列一 之restfull api与多环境配置springboot系列二之 日志SpringBoot系列三之 MVC 模版引擎SpringBoot 2.0.0.M7 系列四 异常处理springboot 2.0.0.M7之 注解 与 配置springboot 2.0.0.M7 配置mvcspr...

架构师的成长之路的博客 2316

springboot各种集成系列(redis,dubbo,ehcache,rabbitmq,websocket等等)

https://gitee.com/ydd1989/springboot/tree/master/springboot-rabbitmq

ITJAUser的博客 431

Springboot整合J2cache实现声明式缓存方案

​ J2Cache 是 OSChina 目前正在使用的两级缓存框架(要求至少 Java 8)。​ 第一级缓存使用内存(同时支持 Ehcache 2.x、Ehcache 3.x 和 Caffeine),第二级缓存使用 Redis(推荐)/Memcached 。L1: 进程内缓存 caffeine(默认使用) / ehcacheL2: 集中式缓存 Redis(推荐使用) / Memcached

LiuCJ_20000的博客 2128

wot-design-uni Picker 选择器组件完全指南:从基本用法到多级联动与确定前校验

本文是 wot-design-uni 组件库中 `wd-picker` 选择器组件的完整实战指南。该组件是 `popup` 弹出层与 `pickerView` 滚筒选择器的组合封装,适用于 uni-app(H5 / 小程序 / App)场景下的单列选择、多列选择、多级联动选择以及表单联动校验等需求。读完本文,你将掌握 `columns` 数据源、`v-model` 绑定、`column-chang

gitblog_00085的博客 480

基于SpringBoot + Spring Data Jpa + Thymeleaf + Shiro + Jwt + EhCache技术的在线博客管理后台设计与实现

基于SpringBoot + Spring Data Jpa + Thymeleaf + Shiro + Jwt + EhCache技术的在线博客管理后台设计与实现

mr_lili_111的博客 1153

基于springboot旅游网站设计开发实现vue

【代码】基于springboot旅游网站设计开发实现vue。

2501_93025599的博客 720

分布式系列

分布式缓存架构 分布式缓存 知识点 《ehcache入门基础示例》 jvm内置缓存ehcache ehcache 的五种集群模式 ehcache + Redis 实现一级缓存、二级缓存 《springboot整合ehcache+redis实现双缓存》 分布式Redis缓存持久化 分布式Redis缓存水平拆分 分布式Redis缓存主从复制 分布式Redis缓存集群模式 分布式Redis缓存穿透、雪崩...

DaoZhuang的博客 693

springboot的《计算机基础》网上考试系统设计开发实现

【代码】springboot的《计算机基础》网上考试系统设计开发实现。

2501_93250029的博客 395

数据缓存的Java实现

目录 基础概念和问题 缓存相关概念 缓存相关问题 本地缓存 Guava Cache EHCache 远程缓存 Redis集群  对于缓存大家应该都不陌生,缓存的核心是用空间换实践,通过分配一块高速存储区域(一般都是内存)来提高数据的读写效率,其实现的难点在于清空策略的实现,比较合理的思路就是定时回收与及时判断数据是否过期相结合。    下面文章是转发的,主要从本地缓存、远程缓存...

比我NB的人,仍然在努力 8152
上一篇: SpringBoot + camel+IBM MQ实现消息队列处理
Java程序之猿
博客等级 码龄9年 2599粉丝 140原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值