J2Cache的学习

2023-11-12

J2Cache的学习

此教程基于黑马程序员Java品达通用权限项目,哔哩哔哩链接:https://www.bilibili.com/video/BV1tw411f79E?p=97

一、j2cache介绍

j2cache是OSChina(开源中国)目前正在使用的两级缓存框架。

j2cache的两级缓存结构:

  • L1: 进程内缓存 caffeine/ehcache
  • L2: 集中式缓存 Redis/Memcached

j2cache其实并不是在重复造轮子,而是作资源整合,即将Ehcache、Caffeine、redis、Spring Cache等进行整合

由于大量的缓存读取会导致L2的网络成为整个系统的瓶颈,因此L1的目标是降低对L2的读取次数,因为L1是进程内的,读取数据没有网络开销,性能更高

该缓存框架主要用于集群环境中,单机也可使用,用于避免应用重启导致的ehcache缓存数据丢失。

j2cache从1.3.0版本开始支持JGroups和Redis Pub/Sub两种方式进行缓存事件的通知。

数据读取顺序 -> L1 -> L2 -> DB(数据库)

使用j2cache需要导入的maven坐标:

<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-spring-boot2-starter</artifactId>
    <version>2.8.0-release</version>
</dependency>
<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-core</artifactId>
    <version>2.8.0-release</version>
    <!-- 排除 -->
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

二、j2cache入门案例

第一步:创建maven工程j2cache_demo并配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>
    <groupId>cn.itcast</groupId>
    <artifactId>j2cache_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <!-- web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- j2cache依赖 -->
        <dependency>
            <groupId>net.oschina.j2cache</groupId>
            <artifactId>j2cache-spring-boot2-starter</artifactId>
            <version>2.8.0-release</version>
        </dependency>
        <!-- j2cache依赖 -->
        <dependency>
            <groupId>net.oschina.j2cache</groupId>
            <artifactId>j2cache-core</artifactId>
            <version>2.8.0-release</version>
            <!-- 排除 -->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-simple</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    
</project>

第二步:创建application.yml

server:
  port: 9000
# redis 通用配置, 不同的环境,需要配置不同的链接信息,
# 只需要将这段信息复制到具体环境的配置文件中进行修改即可
# 如:复制到pd-auth-server-dev.yml中将数据库名和ip改掉
pinda:
  redis:
    ip: 127.0.0.1
    port: 6379
    password:
    database: 0 # 使用0号数据库

spring:
  cache:
    type: GENERIC
  redis:
    host: ${pinda.redis.ip}
    password: ${pinda.redis.password}
    port: ${pinda.redis.port}
    database: ${pinda.redis.database}

j2cache:
  #  config-location: /j2cache.properties
  open-spring-cache: true
  cache-clean-mode: passive
  allow-null-values: true
  redis-client: lettuce #指定redis客户端使用lettuce,也可以使用Jedis
  l2-cache-open: true #开启二级缓存,false则表示只使用一级缓存
  # 事件通知的机制,j2cache从1.3.0版本开始支持JGroups和Redis Pub/Sub两种方式进行缓存事件的通知。
  # 此处我们使用基于redis的发布订阅模式来通知缓存的各个节点来进行缓存数据的同步(由j2cache进行实现,我们写上配置即可)
  broadcast: net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
  #  broadcast: jgroups
  L1: #指定一级缓存提供者为caffeine
    provider_class: caffeine
  L2: #指定二级缓存提供者为redis
    provider_class: net.oschina.j2cache.cache.support.redis.SpringRedisProvider
    config_section: lettuce
  sync_ttl_to_redis: true
  default_cache_null_object: false
  serialization: fst
caffeine:
  properties: /caffeine.properties   # 这个配置文件需要放在项目中
# lettuce是redis的一个客户端,也可以使用jedis,都是用来操作redis的java客户端
lettuce:
  mode: single
  namespace:
  storage: generic
  channel: j2cache
  scheme: redis
  hosts: ${pinda.redis.ip}:${pinda.redis.port}
  password: ${pinda.redis.password}
  database: ${pinda.redis.database}
  sentinelMasterId:
  maxTotal: 100
  maxIdle: 10
  minIdle: 10
  timeout: 10000

第三步:创建/resources/caffeine.properties文件

#########################################
# Caffeine configuration
# [name] = size, xxxx[s|m|h|d]
#########################################
# 默认区域,最多可以放入2000个缓存对象,缓存2个小时的时间,s表示秒,m分钟,h小时,d天
default=2000, 2h
# 定义的第二个缓存的区域,名字任意,此处为rx,最多存放50个缓存对象,缓存2个小时,时间到就会自动清除缓存
rx=50, 2h

第四步:创建MyController

package cn.itcast.controller;

import net.oschina.j2cache.CacheChannel;
import net.oschina.j2cache.CacheObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/cache")
public class MyController {

    private String key = "myKey"; // 定义缓存的key
    private String region="rx"; // 缓存的区域

    // 我们使用j2chache提供的CacheChannel来操作我们的缓存数据
    /*
    * 为什么我们没有配置就可以直接注入CacheChannel,因为我们导入了j2cache的坐标,他会帮我们自动完成配置
    * 自动加载我们在application.yml中的配置,把CacheChannel实例化出来,并且载入spring容器
    * */
    @Autowired
    private CacheChannel cacheChannel;

    // 放入缓存(一级缓存和二级缓存都会放入)
    @GetMapping("/getInfos")
    public List<String> getInfos(){
        CacheObject cacheObject = cacheChannel.get(region, key);
        if(cacheObject.getValue() == null){
            //缓存中没有找到,查询数据库获得
            List<String> data = new ArrayList<String>();
            data.add("info1");
            data.add("info2");
            //放入缓存,指定区域,key,数据
            cacheChannel.set(region,key,data);
            return data;
        }
        return (List<String>) cacheObject.getValue();
    }

    //清理指定缓存(一级缓存和二级缓存都会清理)
    @GetMapping("/evict")
    public String evict(){
        cacheChannel.evict(region,key);
        return "evict success";
    }

    //清理指定区域的缓存(会把整个区域的缓存进行清理掉,(一级缓存和二级缓存都会清理))
    @GetMapping("/clear")
    public String clear(){
        cacheChannel.clear(region);
        return "clear success";
    }

    //检测缓存数据是否存在
    @GetMapping("/exists")
    public String exists(){
        boolean exists = cacheChannel.exists(region, key);
        return "exists:" + exists;
    }

    // 检测指定的缓存数据是从哪一级缓存获取到的,如果两级缓存都没有数据,则返回为0
    @GetMapping("/check")
    public String check(){
        int check = cacheChannel.check(region, key);
        return "level:" + check;
    }
}

第五步:创建启动类

package cn.itcast;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class J2CacheApp {
    public static void main(String[] args) {
        SpringApplication.run(J2CacheApp.class,args);
    }
}

注意:由于我们当前第二级缓存使用的是redis,所以需要启动redis服务才能正常运行入门案例。

启动项目,访问地址:http://localhost:9000/cache/getInfos ,使用redis可视化工具RDM可以发现redis中已经缓存了数据:

image-20200317211408623

且获取数据首先是从一级缓存中进行缓存,

image-20220117145246021

重启项目,由于j2cache的一级缓存(caffeine)是进程级缓存,重启后一级缓存消失。但是二级缓存(redis)的数据还存在,再次访问 http://localhost:9000/cache/getInfos,通过debug断点调试可以看到程序从redis中获取了缓存数据。

image-20220117144811430

三、starter定制及使用

​ 我们可以开发一个starter,名字为pd-tools-j2cache,我们的应用直接引入其maven坐标并配置j2cache的配置文件就可以将CacheChannel对象直接注入到我们的程序中进行缓存数据操作了。具体使用过程和入门案例一致,只需要更换j2cache的maven坐标为pd-tools-j2cache的maven坐标即可。

​ starter模块的定制可以参考b站链接:https://www.bilibili.com/video/BV1tw411f79E?p=103&spm_id_from=pageDriver,此处我们不做过多叙述

喜欢请关注我

至此,我们的J2Cache的学习就讲解完毕了。喜欢我的话可以关注我的微信公众号 我爱学习呀嘻嘻 ,不定期分享各类资源哦。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

J2Cache的学习 的相关文章

  • 使用 EVAL、SCAN 和 DEL 的 Redis 通配符删除脚本返回“非确定性命令后不允许写入命令”

    因此 我正在寻求构建一个 lua 脚本 该脚本使用 SCAN 根据模式查找键并删除它们 原子地 我首先准备了以下脚本 local keys local done false local cursor 0 repeat local resul
  • redis集群不断打印日志WSA_IO_PENDING

    当我启动redis集群的所有redis服务器时 所有这些服务器不断打印类似WSA IO PENDING clusterWriteDone的日志 9956 03 Feb 18 17 25 044 WSA IO PENDING writing
  • 如何统计 Redis 流中未读或已确认的消息?

    使用 Redis 5 0 3 假设我们创建一个名为streamy和一个消费群体consumers XGROUP CREATE streamy consumers MKSTREAM 然后向其中添加一些消息 XADD streamy messa
  • 库存管理系统的 SQL 与 NoSQL

    我正在开发一个基于 JAVA 的网络应用程序 主要目的是拥有在多个称为渠道的网站上销售的产品的库存 我们将担任所有这些渠道的管理者 我们需要的是 用于管理每个渠道的库存更新的队列 库存表 其中包含每个通道上分配的正确快照 将会话 ID 和其
  • 是否有可嵌入的 Java 替代 Redis?

    根据这个线程 https stackoverflow com questions 3047010 best redis library for java 如果我想从Java中使用Redis Jedis是最好的选择 然而 我想知道是否有任何库
  • Spring Data Redis JedisConnectionException:流意外结束

    雷迪斯3 0 5Spring数据Redis 1 3 6绝地武士2 6 3 我们的 Web 应用程序通过 pub sub 从 Redis 接收数据 还以键 值对的形式在 Redis 上执行数据读 写 读 写发生在监听线程 独立监控线程和htt
  • 通过 StackExchange.Redis 连接到 Redis Servier

    我尝试使用以下方法制作一个测试项目Redis https redis io服务器 通过 Virtual Box 安装在 Linux Ubuntu 虚拟机上 Linux 机器通过 Virtual Box 的桥接适配器与本地网络连接 Virtu
  • 如何测试我的 Redis 缓存是否正常工作?

    我已经安装了 django redis cache 和 redis py 我遵循了 Django 的缓存文档 据我所知 以下设置就是我所需要的 但我如何判断它是否正常工作 设置 py CACHES default BACKEND redis
  • 在 sidekiq 上配置 redis 身份验证

    我想我错过了一些东西 因为我在文档中找不到如何编写 redis 实例的用户名和密码以与 sidekiq 一起使用 有没有办法做到这一点 或者是通过 ENV 变量 Sidekiq 将无法识别的 Redis 选项直接传递给 Redis 驱动程序
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • Redis Cluster 与 Pub/Sub 中的 ZeroMQ,用于水平扩展的分布式系统

    如果我要设计一个巨大的分布式系统 其吞吐量应随系统中的订阅者数量和通道数量线性扩展 哪个会更好 1 Redis集群 仅适用于Redis 3 0 alpha 如果是集群模式 您可以在一个节点上发布并在另一个完全不同的节点上订阅 消息将传播并到
  • Java 将字节转换为二进制安全字符串

    我有一些以字节为单位的数据 我想将它们放入Redis中 但是Redis只接受二进制安全字符串 而我的数据有一些二进制非安全字节 那么如何将这些字节转换为二进制安全字符串以便将它们保存到 Redis 中呢 Base64 对我有用 但它使数据更
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • Spring Data JPA Redis:无法编写基于自定义方法的查询

    我已经使用 Redis 配置了 Spring Data JPA 并使用RedisRepositorieswith 提供了类似的方法find findAll 所有这些方法似乎都工作得很好 但我无法编写我的自定义方法 RedisEntity f
  • Redis是如何实现高吞吐量和高性能的?

    我知道这是一个非常普遍的问题 但是 我想了解允许 Redis 或 MemCached Cassandra 等缓存 以惊人的性能极限工作的主要架构决策是什么 如何维持连接 连接是 TCP 还是 HTTP 我知道它完全是用C写的 内存是如何管理
  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用
  • StackExchange.Redis Get 函数抛出 TimeoutException

    我在用着StackExchange Redis与 C 和StackExchangeRedisCacheClient Get函数抛出以下异常 myCacheClient Database StringGet txtKey Text myCac
  • redis dump.rdb / 保存小文件

    Context 我正在使用redis 数据库小于 100 MB 但是 我想进行每日备份 我也在 Ubuntu Server 12 04 上运行 当输入 redis cli save 我不知道 dump rdb 保存到哪里 因为 redis
  • 在 Redis 上为 Django 和 Express.js 应用程序共享会话存储

    我想创建一个包含一些登录用户的 Django 应用程序 另一方面 由于我想要一些实时功能 所以我想使用 Express js 应用程序 现在的问题是 我不希望身份不明的用户访问 Express js 应用程序的日期 因此 我必须在 Expr

随机推荐

  • 更改SVN的用户名、密码等信息的两种方式

    一 背景 在刚入职一家公司的时候 经常会去安装一些版本管理工具 例如 git或者svn 下面就拿svn来举例 假如你拿到的电脑是上位同事留下的 里面的记录并没有被完全清空 当你安装好svn 大概率还是会使用上一位同事的配置文件 那在此之后你
  • Verilog HDL FPGA 从入门到放弃(1)

    这是一篇入门文章 笔者也曾经迷茫过 也很困惑过 硬件编程是怎么样的 但是功夫不负有心人 希望我的文章获得读者的认同 谦虚使人进步 希望不足之处请提意见 对于有意思的东西大家可以探讨一下 硬件编程verilog 建模 一个简单的模型 流水灯的
  • 使用Spring Boot和EasyExcel的导入导出

    在当今信息化社会 数据的导入和导出在各种业务场景中变得越来越重要 为了满足复杂的导入导出需求 结合Java编程语言 Spring Boot框架以及EasyExcel库 我们可以轻松地构建出强大而灵活的数据处理系统 本文将引导您通过一个案例学
  • Odoo(OpenERP)补货规则笔记整理 - 草稿

    感谢Jeffery Jason ccdos roson 等人分享讨论 推式规则 移库规则 从一个库位推送到另一个库位 拉式规则 补货规则 包括生产 采购 移动 进行仓库设置时 会自动创建默认的拉式规则 最小库存规则 再订货规则 补货 某个库
  • iphone 服务器未响应,iPhone 死机没反应?先试试这些方法!

    iPhone 突然死机了 相信很多果粉都遇过这种情况 通常在手机死机的时候 无论我们怎么点屏幕都没反应 如果在一些紧急情况下发生死机 是很头疼的一件事 那么 iPhone 死机没反应 我们到底应该怎么处理呢 今天 疯师傅教你们三招 自己在家
  • 静态类型

    从程序运行或者二进制的角度 或者说 运行时 的角度来看 静态类型就是 没有类型 因为程序实际上不在运行时保存任何的静态类型 这也是静态类型又被称为 编译时类型 的原因 因为一旦经过编译 静态类型系统就基本上消失殆尽了 为什么又说基本上了呢
  • freemarker+itext5实现用模板方式,导出word和pdf(spring-boot直接可使用)

    第一步 需要引入的jar包
  • PHP$_FILES原生图片上传

    PHP FILES原生图片上传 if empty FILES file name header Content type text html charset utf 8 if FILES file error 0 判断上传是否正确 file
  • 接口自动化测试框架-Python+Requests+Yaml

    零代码极限封装的 接口自动化测试框架 目前已经完全能够实现真正的零代码落地并在企业中推广 其中用到的最核心的封装技术如下 核心技术 1 热加载封装 是全网最早应用于自动化测试框架的封装技术 2 Requests统一请求封装 3 接口关联封装
  • windows下Qt、MinGW、libmodbus源码方式的移植与使用

    windows下Qt MinGW libmodbus源码方式的移植与使用 1 前言 libmodbus官网 https libmodbus org github下载 https github com stephane libmodbus 截
  • element-ui 源码解析,你知道 v-loading 是如何实现的吗?

    前言 相信大家肯定都用过 element ui 里面的 v loading 来写加载 但是如果让你来写一个的话你会怎么写呢 众所周知 element ui 框架的 v loading 有两种使用方式 一种是在需要 loading 的标签上直
  • Yolov5目标检测环境搭建过程(Cuda+Pytorch+Yolov5)

    本文介绍了如何搭建yolov5目标检测代码的环境 详细记录了python虚拟环境 安装pytorch 加载yolov5项目以及运行检测程序的全过程 完成了本文的yolov5项目搭建后 可以查看本文下一篇文章 使用yolov5训练自己的数据集
  • chown、chmod详解

    首先通过ll命令查看目录下文件 主要看最前面一列 我把 drwxr xr x 拿出来说 d 目录 文件类型 rwx 可读 可写 可执行 2 4位 所属者权限 r x 可读 可执行 5 7位 所属组权限 r x 可读 可执行 8 10位 其它
  • OpenTK---空间中单个三维点的绘制

    OpenTK是一个跨平台的包 可以让我们能够使用C 来调用OpenGL来进行三维可视化的开发 因为这是第一篇 所以会写的比较详细 后面重复用到的内容就不再二次说明了 创建主程序中的类 using OpenTK Mathematics usi
  • 关于iptables禁止全部ip访问问题

    关于iptables禁止全部ip访问问题 旁边兄弟在iptables想要实现任何ip禁止访问 只开发个别端口供个别ip访问 开放ip端口 A INPUT s 192 168 1 1 p tcp dport 8848 j ACCEPT A I
  • C++学习(四十一)stderr stdout

    stdout 标准输出设备 stderr 标准错误输出设备 两者默认向屏幕输出 但如果用转向标准输出到磁盘文件 则可看出两者区别 stdout输出到磁盘文件 stderr在屏幕 在默认情况下 stdout是行缓冲的 他的输出会放在一个buf
  • 双向链表为何时间复杂度为O(1)?

    双向链表相比于单向链表 所谓的O 1 是指删除 插入操作 单向链表要删除某一节点时 必须要先通过遍历的方式找到前驱节点 通过待删除节点序号或按值查找 若仅仅知道待删除节点 是不能知道前驱节点的 故单链表的增删操作复杂度为O n 双链表 双向
  • SpringBoot注解大全(超详细)

    一 启动注解 Spring Boot 应用的入口注解 SpringBootApplication SpringBootApplication 是一个注解 它是 Spring Boot 应用的入口注解 用于表示一个应用程序的主类 这个注解通常
  • php设置一分钟访问一次接口,php 如何锁定接口,让一个接口,同一时间只处理同一人的一次请求?...

    最后我是用redis锁解决问题的 锁的代码如下 redis操作 ps 如果没有安装redis 会直接返回false 不会报错 Created by PhpStorm User haua Date 16 10 21 Time 23 02 cl
  • J2Cache的学习

    J2Cache的学习 此教程基于黑马程序员Java品达通用权限项目 哔哩哔哩链接 https www bilibili com video BV1tw411f79E p 97 一 j2cache介绍 j2cache是OSChina 开源中国