Springboot-Redisson - 5.分布式对象

👀分布式对象

名称作用使用场景优点缺点Redisson调用的方法
通用对象桶 (Object Bucket)存储单一对象对象缓存快速、灵活单一对象存储RBucket
二进制流 (Binary Stream)存储二进制数据大文件存储高效、节省空间读写复杂RBinaryStream
地理空间对象桶 (Geospatial Bucket)存储地理位置信息地理位置查询高效、准确数据结构特定RGeo
BitSet位集合位操作、大量布尔值存储节省空间、高效仅限于位操作RBitSet
数据分片 (Sharding)分布式位集合分布式位操作分布式存储、高可用维护复杂RRoaringBitmap
原子整长形 (AtomicLong)原子操作的长整数计数器、序列生成线程安全、原子操作仅支持整数RAtomicLong
原子双精度浮点 (AtomicDouble)原子操作的双精度浮点数精确计算线程安全、原子操作仅支持浮点数RAtomicDouble
话题 (Topic)发布/订阅消息系统消息传递、事件通知实时、高效需要消息订阅者在线RTopic
模糊话题使用模式匹配的发布/订阅系统模糊消息匹配灵活、实时更复杂的匹配逻辑RPatternTopic
布隆过滤器 (Bloom Filter)用于测试一个元素是否在集合中快速查找、去重快速、节省空间有一定的误判率RBloomFilter
数据分片 (Sharding)分布式布隆过滤器分布式快速查找分布式存储、高可用维护复杂RBloomFilter with sharding
基数估计算法 (HyperLogLog)估算集合的基数去重、大数据统计节省空间、高效为估算值,可能有误差RHyperLogLog
整长型累加器 (LongAdder)高并发环境下的长整数加法器高并发计数高效、线程安全仅支持加法RLongAdder
双精度浮点累加器 (DoubleAdder)高并发环境下的双精度浮点数加法器高并发计算高效、线程安全仅支持加法RDoubleAdder
限流器 (RateLimiter)限制特定资源的访问速率API调用限流、资源保护高效、灵活限制资源访问RRateLimiter

分布式对象是在分布式系统中运行的对象,它们可以跨多个节点共享数据和操作。利用分布式对象,开发者可以轻松构建高可用、可扩展的应用。

✍作用

分布式对象提供了一种方式,使得对象能够在多个物理位置上的计算机之间共享和交互。这样,即使某些节点失败,应用程序仍然可以持续运行,因为其他节点上的对象可以接管工作。

✍使用场景

  • 分布式缓存:当需要在多个服务器之间共享缓存数据时。
  • 分布式计算:当任务需要在多个节点上并行处理时。
  • 高可用性应用:当应用需要在某个节点失败时仍然可用。

✍优缺点

优点:

  • 高可用性:由于数据和操作分布在多个节点上,即使某个节点出现故障,应用也能继续运行。
  • 可扩展性:可以轻松添加或删除节点,以适应变化的工作负载。

缺点:

  • 复杂性:管理分布式对象和处理节点之间的通信可能会增加复杂性。
  • 数据一致性:确保所有节点上的数据保持同步可能是一个挑战。

✌通用对象桶(Object Bucket)

通用对象桶是一个分布式数据结构,允许您在一个桶中存储大量的对象。

✍作用

允许用户在一个集中的地方存储和检索对象,有助于减少网络通信和提高数据访问速度。

✍使用场景

  • 数据缓存:当需要在多个服务或应用之间共享数据对象时。
  • 配置管理:存储和检索应用的配置数据。

✍优缺点

优点:

  • 高效:提供了快速的数据访问速度。
  • 简单:易于使用和管理。

缺点:

  • 容量限制:每个桶的大小可能有限制。

✍示例

Redisson 提供了一个 Java 客户端来操作 Redis,它不仅支持常见的 Redis 操作,还提供了许多高级功能。其中的 “Object Bucket”,即 RBucket,是一个通用对象容器,可以将 Java 对象保存在 Redis 中。

以下是如何在 Spring Boot 中使用 Redisson 的 RBucket 的详细示例:

  1. 创建 Spring Boot 项目

首先,使用 Spring Initializr 或其他方式创建一个新的 Spring Boot 项目。

  1. 添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Redisson 的依赖:

<!-- Spring Boot Starter Data Redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 依赖 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.0</version> <!-- 使用合适的版本 -->
</dependency>
  1. 配置 Redis 和 Redisson

application.propertiesapplication.yml 文件中添加 Redis 和 Redisson 的配置。

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

# Redisson 配置
redisson.config=classpath:redisson.yaml

在资源目录下创建 redisson.yaml 文件:

singleServerConfig:
  address: "redis://127.0.0.1:6379"
  1. 使用 RBucket

现在我们创建一个 Service 类来使用 Redisson 的 RBucket:

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 将对象保存到 Redis 的 RBucket 中
     *
     * @param key   存储的键
     * @param value 要存储的对象
     */
    public void setObjectToBucket(String key, Object value) {
        // 通过 key 获取一个 RBucket 对象
        RBucket<Object> bucket = redissonClient.getBucket(key);
        // 使用 set 方法将对象存储到 RBucket 中
        bucket.set(value);
    }

    /**
     * 从 Redis 的 RBucket 中获取对象
     *
     * @param key 存储的键
     * @return 存储的对象
     */
    public Object getObjectFromBucket(String key) {
        // 通过 key 获取一个 RBucket 对象
        RBucket<Object> bucket = redissonClient.getBucket(key);
        // 使用 get 方法从 RBucket 中获取对象
        return bucket.get();
    }

    /**
     * 从 Redis 的 RBucket 中删除对象
     *
     * @param key 存储的键
     */
    public void removeObjectFromBucket(String key) {
        // 通过 key 获取一个 RBucket 对象
        RBucket<Object> bucket = redissonClient.getBucket(key);
        // 使用 delete 方法从 RBucket 中删除对象
        bucket.delete();
    }
}

这个 Service 类提供了将对象保存到 Redis 的 RBucket、从 RBucket 获取对象以及从 RBucket 删除对象的方法。

你可以在 Spring Boot 的 Controller 或其他组件中使用此 Service 来操作 Redis 的 RBucket。这样,你就可以非常方便地在 Redis 中存储和操作 Java 对象了。

✌二进制流(Binary Stream)

二进制流是一种数据结构,用于存储和处理大量的二进制数据。

✍作用

提供一种高效的方式来存储、检索和处理二进制数据。

✍使用场景

  • 文件存储:当需要在分布式系统中存储和访问大文件时。
  • 数据流处理:对大量的数据流进行处理和分析。

✍优缺点

优点:

  • 高效:针对大数据量的存储和处理进行了优化。
  • 灵活:可以处理任何类型的二进制数据。

缺点:

  • 与特定的数据格式不太兼容:处理特定格式的数据可能需要额外的工作。

✍示例

Redisson 提供了一个称为 RBinaryStream 的 API,用于在 Redis 中处理二进制流数据。这对于存储、检索和操作大的二进制数据(例如文件、图像或视频)特别有用。

下面是如何在 Spring Boot 中使用 Redisson 的 RBinaryStream 的详细示例:

创建一个 Service 类来使用 Redisson 的 RBinaryStream

import org.redisson.api.RBinaryStream;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.io.OutputStream;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 将二进制数据写入 Redis
     *
     * @param key           用于存储的键
     * @param binaryContent 要存储的二进制数据输入流
     */
    public void writeToRedis(String key, InputStream binaryContent) throws Exception {
        // 通过 key 获取一个 RBinaryStream 对象
        RBinaryStream stream = redissonClient.getBinaryStream(key);
        
        // 获取 RBinaryStream 的 OutputStream
        try (OutputStream os = stream.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            // 从输入流读取数据并写入到 Redis
            while ((bytesRead = binaryContent.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        }
    }

    /**
     * 从 Redis 中读取二进制数据
     *
     * @param key 用于检索的键
     * @return 存储的二进制数据输出流
     */
    public InputStream readFromRedis(String key) {
        // 通过 key 获取一个 RBinaryStream 对象
        RBinaryStream stream = redissonClient.getBinaryStream(key);
        
        // 返回 RBinaryStream 的 InputStream
        return stream.getInputStream();
    }

    /**
     * 从 Redis 中删除与特定键关联的二进制数据
     *
     * @param key 要删除的数据的键
     */
    public void deleteFromRedis(String key) {
        // 通过 key 获取一个 RBucket 对象
        RBucket<Object> bucket = redissonClient.getBucket(key);
        // 使用 delete 方法删除与 key 关联的数据
        bucket.delete();
    }
}

以上示例提供了将二进制数据保存到 Redis 和从 Redis 中读取二进制数据的方法。你可以使用 writeToRedis 方法保存大的二进制数据,如文件或图像,并使用 readFromRedis 方法检索它。

✌地理空间对象桶(Geospatial Bucket)

地理空间对象桶是一个分布式数据结构,专门用于存储和查询地理空间数据,如坐标点。

✍作用

允许用户存储、检索和查询地理空间数据,如坐标点、线和多边形。

✍使用场景

  • 地图应用:存储和查询地点、路线等。
  • 位置基础的服务:如寻找附近的商店或服务。

✍优缺点

优点:

  • 高效:提供了快速的地理空间查询。
  • 灵活:支持多种地理空间数据类型。

缺点:

  • 数据大小限制:存储的地理空间数据大小可能有限制。

✍示例

Redisson 的地理空间对象桶 (Geospatial Bucket) 是一个非常有趣的功能,它是基于 Redis 的地理空间数据类型构建的。这允许用户存储、检索和查询地理位置数据。此功能通常用于实现位置搜索、定位等功能。

以下是如何在 Spring Boot 中使用 Redisson 的地理空间对象桶的详细示例:

创建一个 Service 类来使用 Redisson 的 RGeo

import org.redisson.api.RGeo;
import org.redisson.api.RedissonClient;
import org.redisson.api.geo.GeoEntry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Map;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 添加地理位置信息
     *
     * @param key      用于存储的键
     * @param latitude 纬度
     * @param longitude 经度
     * @param member   位置名称或标识符
     */
    public void addLocation(String key, double latitude, double longitude, String member) {
        // 获取 RGeo 对象
        RGeo<String> geo = redissonClient.getGeo(key);
        // 添加地理位置信息
        geo.add(new GeoEntry(longitude, latitude, member));
    }

    /**
     * 根据位置名称或标识符获取地理位置
     *
     * @param key    用于检索的键
     * @param member 位置名称或标识符
     * @return 地理位置坐标
     */
    public Collection<Map.Entry<String, org.redisson.client.protocol.ScoredEntry<org.redisson.api.geo.GeoPosition>>> getLocation(String key, String member) {
        // 获取 RGeo 对象
        RGeo<String> geo = redissonClient.getGeo(key);
        // 获取地理位置坐标
        return geo.radiusWithDistance(member, 0);
    }

    /**
     * 从 Redis 中删除地理位置信息
     *
     * @param key    用于删除的键
     * @param members 要删除的位置名称或标识符
     */
    public void removeLocation(String key, String... members) {
        // 获取 RGeo 对象
        RGeo<String> geo = redissonClient.getGeo(key);
        // 删除地理位置信息
        geo.remove(members);
    }
}

在上面的示例中,我们使用 RGeo 接口提供的方法来添加、获取和删除地理位置信息。

✌BitSet

BitSet是一个分布式数据结构,允许您存储和操作一系列的位。

✍作用

提供一种高效的方式来存储和操作大量的位。

✍使用场景

  • 数据过滤:当需要使用位来表示某些数据是否存在或有效。
  • 位操作:如AND、OR和NOT操作。

✍优缺点

优点:

  • 高效:位操作通常比其他数据结构更快。
  • 空间有效:只需要少量的空间来存储大量的位。

缺点:

  • 不是很灵活:只能存储和操作位。

✍示例

BitSet 是一种数据结构,用于存储位(即0或1)。它通常用于有效地存储大量的小整数、状态、标志等。在 Redis 和 Redisson 中,BitSet 提供了一种有效的方式来处理和存储位数据。

在 Redisson 中,你可以使用 RBitSet 接口与 BitSet 交互。以下是如何在 Spring Boot 中使用 Redisson 的 RBitSet 的示例:

创建一个 Service 类来使用 Redisson 的 RBitSet

import org.redisson.api.RBitSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 设置指定位置的位
     *
     * @param key    用于存储的键
     * @param position 位的位置
     * @param value 位的值(true or false)
     */
    public void setBit(String key, int position, boolean value) {
        // 获取 RBitSet 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 设置指定位置的位
        bitSet.set(position, value);
    }

    /**
     * 获取指定位置的位
     *
     * @param key    用于检索的键
     * @param position 位的位置
     * @return 位的值(true or false)
     */
    public boolean getBit(String key, int position) {
        // 获取 RBitSet 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 获取指定位置的位
        return bitSet.get(position);
    }

    /**
     * 获取 BitSet 的长度
     *
     * @param key 用于检索的键
     * @return BitSet 的长度
     */
    public long size(String key) {
        // 获取 RBitSet 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 返回 BitSet 的长度
        return bitSet.size();
    }

    /**
     * 清除 BitSet 中的所有位
     *
     * @param key 用于清除的键
     */
    public void clear(String key) {
        // 获取 RBitSet 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 清除所有位
        bitSet.clear();
    }
}

上述示例展示了如何在 Spring Boot 中使用 Redisson 的 RBitSet 进行位数据的操作,包括设置、获取、获取长度和清除位。

✌BitSet数据分片(Sharding)

BitSet数据分片是一种策略,用于将大型的BitSet分成多个小片,以提高效率和可扩展性。

✍作用

允许用户高效地存储和操作大型的BitSet。

✍使用场景

  • 当BitSet的大小超过单个节点的容量限制。
  • 当需要在多个节点上并行处理BitSet数据。

✍优缺点

优点:

  • 高效:通过分片可以提高数据访问和处理的速度。
  • 可扩展性:可以轻松地添加或删除节点。

缺点:

  • 复杂性:管理和操作分片的数据可能会增加复杂性。

✍示例

在 Redisson 中,数据分片 (sharding) 通常用于大规模数据。通过数据分片,你可以将大量数据分散到多个 Redis 节点上,从而提高数据处理的性能和可扩展性。

当使用 RBitSet 的时候,如果你知道你的 BitSet 会非常大,你可能希望使用 RShardedBitSet 进行数据分片。它将数据均匀地分布到所有连接的 Redis 服务上。

以下是如何在 Spring Boot 中使用 Redisson 的 RShardedBitSet 的示例:

  1. 创建 Spring Boot 项目

使用 Spring Initializr 或其他方式创建一个新的 Spring Boot 项目。

  1. 添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Redisson 的依赖:

<!-- Spring Boot Starter Data Redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 依赖 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.0</version> <!-- 使用合适的版本 -->
</dependency>
  1. 配置 Redis 和 Redisson

application.propertiesapplication.yml 文件中添加 Redis 和 Redisson 的配置:

# Redisson 配置
redisson.config=classpath:redisson-cluster.yaml

对于分片,通常你会连接到一个 Redis 集群或多个 Redis 服务器。在资源目录下创建 redisson-cluster.yaml 文件:

clusterServersConfig:
  scanInterval: 1000
  nodeAddresses:
  - "redis://127.0.0.1:7000"
  - "redis://127.0.0.1:7001"
  # ...其他的节点...
  1. 使用 RShardedBitSet

创建一个 Service 类来使用 Redisson 的 RShardedBitSet

import org.redisson.api.RShardedBitSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 设置指定位置的位
     *
     * @param key    用于存储的键
     * @param position 位的位置
     * @param value 位的值(true or false)
     */
    public void setBit(String key, int position, boolean value) {
        // 获取 RShardedBitSet 对象
        RShardedBitSet bitSet = redissonClient.getShardedBitSet(key);
        // 设置指定位置的位
        bitSet.set(position, value);
    }

    /**
     * 获取指定位置的位
     *
     * @param key    用于检索的键
     * @param position 位的位置
     * @return 位的值(true or false)
     */
    public boolean getBit(String key, int position) {
        // 获取 RShardedBitSet 对象
        RShardedBitSet bitSet = redissonClient.getShardedBitSet(key);
        // 获取指定位置的位
        return bitSet.get(position);
    }

    /**
     * 获取 BitSet 的长度
     *
     * @param key 用于检索的键
     * @return BitSet 的长度
     */
    public long size(String key) {
        // 获取 RShardedBitSet 对象
        RShardedBitSet bitSet = redissonClient.getShardedBitSet(key);
        // 返回 BitSet 的长度
        return bitSet.size();
    }

    /**
     * 清除 BitSet 中的所有位
     *
     * @param key 用于清除的键
     */
    public void clear(String key) {
        // 获取 RShardedBitSet 对象
        RShardedBitSet bitSet = redissonClient.getShardedBitSet(key);
        // 清除所有位
        bitSet.clear();
    }
}

✌BitSet分布式(RoaringBitMap)

✍作用

RoaringBitMap是一种高效的位图数据结构,适用于在大量数据中存储、查询和操作位标志。

✍使用场景

  • 存储和查询大量的布尔值数据(例如用户是否访问过某个网页)。
  • 大数据和流处理中的快速集合操作。

✍优缺点

优点:

  • 空间效率高。
  • 操作速度快。

缺点:

  • 相对于普通的BitSet,复杂度稍高。

✍示例

Redisson 的 RoaringBitmap 是一个实现了位集合的分布式对象。与 Java 的 java.util.BitSet 相比,RoaringBitmap 有更好的压缩能力,尤其在稀疏的位集上。这使其在存储大量数据时更加高效。

以下是在 Spring Boot 中使用 Redisson 的 RoaringBitmap 的详细示例:

  1. 创建 Spring Boot 项目

使用 Spring Initializr 或其他工具创建一个新的 Spring Boot 项目。

  1. 添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Redisson 的依赖:

<!-- Spring Boot Starter Data Redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 依赖 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.0</version> <!-- 请根据实际情况选择版本 -->
</dependency>
  1. 配置 Redis 和 Redisson

application.propertiesapplication.yml 文件中添加 Redis 和 Redisson 的配置:

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

# Redisson 配置
redisson.config=classpath:redisson.yaml

创建 redisson.yaml 文件:

singleServerConfig:
  address: "redis://127.0.0.1:6379"
  1. 使用 RoaringBitmap

创建一个 Service 类来使用 Redisson 的 RoaringBitmap

import org.redisson.api.RBitSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BitSetService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 设置位的值
     *
     * @param key 位集合的名字
     * @param bitIndex 位的索引
     * @param value 位的值(true 或 false)
     */
    public void setBit(String key, long bitIndex, boolean value) {
        // 获取 RoaringBitmap 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 设置位的值
        bitSet.set(bitIndex, value);
    }

    /**
     * 获取位的值
     *
     * @param key 位集合的名字
     * @param bitIndex 位的索引
     * @return 位的值(true 或 false)
     */
    public boolean getBit(String key, long bitIndex) {
        // 获取 RoaringBitmap 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 返回位的值
        return bitSet.get(bitIndex);
    }

    /**
     * 获取位集合的大小
     *
     * @param key 位集合的名字
     * @return 位集合的大小
     */
    public long size(String key) {
        // 获取 RoaringBitmap 对象
        RBitSet bitSet = redissonClient.getBitSet(key);
        // 返回位集合的大小
        return bitSet.size();
    }
}
  1. 使用 BitSetService

在 Controller 或其他组件中调用 BitSetService 的方法,以操作 RoaringBitmap

例如,使用在一个 RESTful API 的 Controller 中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BitSetController {

    @Autowired
    private BitSetService bitSetService;

    @GetMapping("/setBit")
    public void setBit(@RequestParam String key, @RequestParam long index, @RequestParam boolean value) {
        bitSetService.setBit(key, index, value);
    }

    @GetMapping("/getBit")
    public boolean getBit(@RequestParam String key, @RequestParam long index) {
        return bitSetService.getBit(key, index);
    }

    @GetMapping("/size")
    public long size(@RequestParam String key) {
        return bitSetService.size(key);
    }
}

在此示例中,我们展示了如何在 Spring Boot 中使用 Redisson 的 RoaringBitmap 进行位集合操作。这是一个非常高效的方法,尤其在处理大量数据时。

✌原子整长形(AtomicLong)

原子整长形是一个分布式数据结构,允许您进行原子操作,如增加或减少其值。

✍作用

提供一种方式在分布式环境中进行原子的整数操作。

✍使用场景

  • 计数器:如网站访问计数、库存计数等。
  • 生成唯一ID:在分布式系统中生成唯一的序列号或ID。

✍优缺点

优点:

  • 原子性:确保操作在分布式环境中的原子性。
  • 高效:提供快速的数值操作。

缺点:

  • 范围限制:作为一个长整数,它有一个最大和最小值。

✍示例

Redisson 提供了 RAtomicLong 接口,允许用户对存储在 Redis 中的整数进行原子操作。该接口的功能类似于 Java 的 AtomicLong,但其值是分布式的并存储在 Redis 中。

以下是在 Spring Boot 中使用 Redisson 的 RAtomicLong 的详细示例:

import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 为指定的键增加值
     *
     * @param key 用于存储的键
     * @param delta 增加的值
     * @return 新的值
     */
    public long addAndGet(String key, long delta) {
        // 获取 RAtomicLong 对象
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        // 增加值并返回新的值
        return atomicLong.addAndGet(delta);
    }

    /**
     * 设置指定键的值
     *
     * @param key 用于存储的键
     * @param newValue 新的值
     */
    public void set(String key, long newValue) {
        // 获取 RAtomicLong 对象
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        // 设置新的值
        atomicLong.set(newValue);
    }

    /**
     * 获取指定键的值
     *
     * @param key 用于检索的键
     * @return 当前值
     */
    public long get(String key) {
        // 获取 RAtomicLong 对象
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        // 返回当前值
        return atomicLong.get();
    }

    /**
     * 原子性地递增指定键的值
     *
     * @param key 用于存储的键
     * @return 递增后的值
     */
    public long incrementAndGet(String key) {
        // 获取 RAtomicLong 对象
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        // 递增并返回新的值
        return atomicLong.incrementAndGet();
    }

    /**
     * 原子性地递减指定键的值
     *
     * @param key 用于存储的键
     * @return 递减后的值
     */
    public long decrementAndGet(String key) {
        // 获取 RAtomicLong 对象
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        // 递减并返回新的值
        return atomicLong.decrementAndGet();
    }
}

✌原子双精度浮点(AtomicDouble)

原子双精度浮点是一个分布式数据结构,允许您进行原子操作,如增加或减少其值。

✍作用

提供一种方式在分布式环境中进行原子的双精度浮点数操作。

✍使用场景

  • 用于需要高精度计算的应用,如金融、科学计算等。
  • 在分布式系统中跟踪平均值或其他统计数据。

✍优缺点

优点:

  • 原子性:确保操作在分布式环境中的原子性。
  • 高精度:适用于需要高精度计算的场景。

缺点:

  • 浮点数的问题:如舍入误差等。

✍示例

RAtomicDouble 是 Redisson 提供的一个接口,允许用户对存储在 Redis 中的浮点数进行原子操作。该接口的功能类似于原子化的 Double,但其值是分布式的并存储在 Redis 中。

以下是在 Spring Boot 中使用 Redisson 的 RAtomicDouble 的详细示例:

import org.redisson.api.RAtomicDouble;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 为指定的键增加值
     *
     * @param key   用于存储的键
     * @param delta 增加的值
     * @return 新的值
     */
    public double addAndGet(String key, double delta) {
        // 获取 RAtomicDouble 对象
        RAtomicDouble atomicDouble = redissonClient.getAtomicDouble(key);
        // 增加值并返回新的值
        return atomicDouble.addAndGet(delta);
    }

    /**
     * 设置指定键的值
     *
     * @param key      用于存储的键
     * @param newValue 新的值
     */
    public void set(String key, double newValue) {
        // 获取 RAtomicDouble 对象
        RAtomicDouble atomicDouble = redissonClient.getAtomicDouble(key);
        // 设置新的值
        atomicDouble.set(newValue);
    }

    /**
     * 获取指定键的值
     *
     * @param key 用于检索的键
     * @return 当前值
     */
    public double get(String key) {
        // 获取 RAtomicDouble 对象
        RAtomicDouble atomicDouble = redissonClient.getAtomicDouble(key);
        // 返回当前值
        return atomicDouble.get();
    }
}

✌话题(订阅分发)

话题是一种发布/订阅模式的实现,允许多个订阅者监听并接收到发布者发布的消息。

✍作用

允许多个服务或应用在没有直接通信的情况下共享信息。

✍使用场景

  • 事件通知:当某个事件发生时,通知所有订阅者。
  • 日志聚合:从多个服务中收集和分发日志。

✍优缺点

优点:

  • 解耦:发布者和订阅者之间没有直接的依赖关系。
  • 扩展性:可以轻松添加或删除订阅者。

缺点:

  • 消息可靠性:确保所有订阅者都收到消息可能是一个挑战。

✍示例

Redisson 提供了订阅-发布功能,允许您创建分布式的消息发布和订阅模式。其实现的功能类似于 Redis 的 PUBLISH 和 SUBSCRIBE 命令。

以下是在 Spring Boot 中使用 Redisson 进行消息发布和订阅的详细示例:

import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.api.listener.MessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonTopicService {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 发布消息到指定的话题
     *
     * @param topicName 话题名称
     * @param message   要发布的消息内容
     */
    public void publish(String topicName, String message) {
        // 获取 RTpoic 对象
        RTopic<String> topic = redissonClient.getTopic(topicName);
        // 发布消息
        topic.publish(message);
    }

    /**
     * 订阅指定话题的消息
     *
     * @param topicName 话题名称
     * @param listener  消息监听器
     * @return 监听器的 ID
     */
    public int subscribe(String topicName, MessageListener<String> listener) {
        // 获取 RTopic 对象
        RTopic<String> topic = redissonClient.getTopic(topicName);
        // 订阅消息并返回监听器的 ID
        return topic.addListener(listener);
    }

    /**
     * 取消订阅指定话题的消息
     *
     * @param topicName 话题名称
     * @param listenerId 监听器的 ID
     */
    public void unsubscribe(String topicName, int listenerId) {
        // 获取 RTopic 对象
        RTopic<String> topic = redissonClient.getTopic(topicName);
        // 使用监听器的 ID 来取消订阅
        topic.removeListener(listenerId);
    }
}

Redisson 支持基于 Redis 的 Pub/Sub 订阅分发系统,还提供了对模糊话题(Pattern topic)的支持,允许订阅者根据某种模式匹配的话题来接收消息。

下面是一个示例,展示如何在 Spring Boot 应用中使用 Redisson 实现模糊话题订阅分发:

import org.redisson.api.RPatternTopic;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.api.listener.MessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PatternTopicService {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 发布消息到特定的话题
     *
     * @param topicName 话题名
     * @param message 消息内容
     * @return 发送的消息 ID
     */
    public long publish(String topicName, String message) {
        RTopic<String> topic = redissonClient.getTopic(topicName);
        return topic.publish(message);
    }

    /**
     * 订阅匹配模式的话题,并设置消息监听器
     *
     * @param pattern 匹配模式,例如 "news.*"
     * @param listener 消息监听器
     * @return 监听器的 ID
     */
    public int subscribePatternTopic(String pattern, MessageListener<String> listener) {
        RPatternTopic<String> patternTopic = redissonClient.getPatternTopic(pattern);
        return patternTopic.addListener(listener);
    }

    /**
     * 取消订阅模糊话题
     *
     * @param pattern 匹配模式
     * @param listenerId 监听器 ID
     */
    public void unsubscribePatternTopic(String pattern, int listenerId) {
        RPatternTopic<String> patternTopic = redissonClient.getPatternTopic(pattern);
        patternTopic.removeListener(listenerId);
    }
}





import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class PatternTopicController {

    @Autowired
    private PatternTopicService patternTopicService;

    @PostMapping("/publish")
    public long publish(@RequestParam String topicName, @RequestParam String message) {
        return patternTopicService.publish(topicName, message);
    }

    // 由于真实的情境下,订阅通常是在后端的启动逻辑或其他非请求响应模式下完成的,这里只是为了示范。
    @GetMapping("/subscribe")
    public String subscribe(@RequestParam String pattern) {
        int listenerId = patternTopicService.subscribePatternTopic(pattern, (channel, msg) -> {
            System.out.println("Received on pattern channel: " + channel + ", message: " + msg);
        });
        return "Subscribed with listenerId: " + listenerId;
    }
}


✌布隆过滤器(Bloom Filter)

✍作用

布隆过滤器是一种空间效率极高的数据结构,用于判断一个元素是否在集合中。

✍使用场景

  • 用于缓存系统,快速判断某个对象是否存在于缓存中。
  • 数据库前的查询过滤,减少不必要的磁盘I/O。

✍优缺点

优点:

  • 节省空间。
  • 快速查询。

缺点:

  • 存在一定的误判率。
  • 一旦创建,不能删除其中的元素。

✍示例

布隆过滤器 (Bloom Filter) 是一种空间效率极高的数据结构,用于判断一个元素是否存在于一个集合。它可能会出现误判(判断存在但实际不存在),但不会错过任何真实存在的元素。Redisson 提供了分布式的布隆过滤器实现。

下面是如何在 Spring Boot 中使用 Redisson 的 RBloomFilter 的详细示例:

  1. 创建 Spring Boot 项目

使用 Spring Initializr 或其他工具创建一个新的 Spring Boot 项目。

  1. 添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Redisson 的依赖:

<!-- Spring Boot Starter Data Redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 依赖 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.0</version> <!-- 请根据实际情况选择版本 -->
</dependency>
  1. 配置 Redis 和 Redisson

application.propertiesapplication.yml 文件中添加 Redis 和 Redisson 的配置:

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

# Redisson 配置
redisson.config=classpath:redisson.yaml

resources 目录下创建 redisson.yaml 文件:

singleServerConfig:
  address: "redis://127.0.0.1:6379"
  1. 使用 RBloomFilter

创建一个 Service 类来使用 Redisson 的 RBloomFilter

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BloomFilterService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 初始化布隆过滤器
     * 
     * @param key 布隆过滤器的名字
     * @param expectedInsertions 预计插入的元素数量
     * @param falseProbability 误判的概率
     */
    public void initBloomFilter(String key, long expectedInsertions, double falseProbability) {
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(key);
        // 使用预计插入数量和误判率初始化
        bloomFilter.tryInit(expectedInsertions, falseProbability);
    }

    /**
     * 往布隆过滤器中添加元素
     *
     * @param key 布隆过滤器的名字
     * @param value 要添加的元素
     */
    public boolean add(String key, Object value) {
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(key);
        return bloomFilter.add(value);
    }

    /**
     * 检查元素是否可能存在于布隆过滤器中
     *
     * @param key 布隆过滤器的名字
     * @param value 要检查的元素
     * @return 如果存在返回 true,否则返回 false
     */
    public boolean contains(String key, Object value) {
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(key);
        return bloomFilter.contains(value);
    }
}
  1. 使用 BloomFilterService

在 Controller 或其他组件中调用 BloomFilterService 的方法,以操作 RBloomFilter

例如,使用在一个 RESTful API 的 Controller 中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class BloomFilterController {

    @Autowired
    private BloomFilterService bloomFilterService;

    @PostMapping("/initBloomFilter")
    public void initBloomFilter(@RequestParam String key,
                                @RequestParam long expectedInsertions,
                                @RequestParam double falseProbability) {
        bloomFilterService.initBloomFilter(key, expectedInsertions, falseProbability);
    }

    @PostMapping("/add")
    public boolean add(@RequestParam String key, @RequestParam String value) {
        return bloomFilterService.add(key, value);
    }

    @GetMapping("/contains")
    public boolean contains(@RequestParam String key, @RequestParam String value) {
        return bloomFilterService.contains(key, value);
    }
}

✌布隆过滤器数据分片(Sharding)

✍作用

通过将数据分成多个分片来优化布隆过滤器,使其能够处理更大的数据集并保持误报率。

✍使用场景

  • 处理大数据集时,保持低误报率。

✍优缺点

优点:

  • 更高的扩展性。
  • 误报率保持较低。

缺点:

  • 复杂度增加。
  • 维护难度提高。

✍示例

Redisson 提供了一种分布式的布隆过滤器实现。但当数据量非常大时,传统的布隆过滤器可能会有一定的限制,这时数据分片 (Sharding) 会非常有用。Redisson 的 RBloomFilter 还提供了一个 RBloomFilterSharding,这是一个基于分片的布隆过滤器。

以下是如何在 Spring Boot 中使用 Redisson 的 RBloomFilterSharding 的详细示例:

  1. 创建 Spring Boot 项目

使用 Spring Initializr 或其他工具创建一个新的 Spring Boot 项目。

  1. 添加依赖

在项目的 pom.xml 文件中添加 Redis 和 Redisson 的依赖:

<!-- Spring Boot Starter Data Redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 依赖 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.0</version> <!-- 请根据实际情况选择版本 -->
</dependency>
  1. 配置 Redis 和 Redisson

application.propertiesapplication.yml 文件中添加 Redis 和 Redisson 的配置:

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

# Redisson 配置
redisson.config=classpath:redisson.yaml

resources 目录下创建 redisson.yaml 文件:

singleServerConfig:
  address: "redis://127.0.0.1:6379"
  1. 使用 RBloomFilterSharding

创建一个 Service 类来使用 Redisson 的 RBloomFilterSharding

import org.redisson.api.RBloomFilterSharding;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BloomFilterShardingService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 初始化分片的布隆过滤器
     * 
     * @param key 布隆过滤器的名字
     * @param expectedInsertions 预计插入的元素数量
     * @param falseProbability 误判的概率
     */
    public void initBloomFilter(String key, long expectedInsertions, double falseProbability) {
        RBloomFilterSharding<Object> bloomFilter = redissonClient.getBloomFilterSharding(key);
        // 使用预计插入数量和误判率初始化
        bloomFilter.tryInit(expectedInsertions, falseProbability);
    }

    /**
     * 往分片的布隆过滤器中添加元素
     *
     * @param key 布隆过滤器的名字
     * @param value 要添加的元素
     */
    public boolean add(String key, Object value) {
        RBloomFilterSharding<Object> bloomFilter = redissonClient.getBloomFilterSharding(key);
        return bloomFilter.add(value);
    }

    /**
     * 检查元素是否可能存在于分片的布隆过滤器中
     *
     * @param key 布隆过滤器的名字
     * @param value 要检查的元素
     * @return 如果存在返回 true,否则返回 false
     */
    public boolean contains(String key, Object value) {
        RBloomFilterSharding<Object> bloomFilter = redissonClient.getBloomFilterSharding(key);
        return bloomFilter.contains(value);
    }
}
  1. 使用 BloomFilterShardingService

在 Controller 或其他组件中调用 BloomFilterShardingService 的方法,以操作 RBloomFilterSharding

例如,在一个 RESTful API 的 Controller 中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class BloomFilterShardingController {

    @Autowired
    private BloomFilterShardingService bloomFilterService;

    @PostMapping("/initShardedBloomFilter")
    public void initShardedBloomFilter(@RequestParam String key,
                                       @RequestParam long expectedInsertions,
                                       @RequestParam double falseProbability) {
        bloomFilterService.initBloomFilter(key, expectedInsertions, falseProbability);
    }

    @PostMapping("/addSharded")
    public boolean addSharded(@RequestParam String key, @RequestParam String value) {
        return bloomFilterService.add(key, value);
    }

    @GetMapping("/containsSharded")
    public boolean containsSharded(@RequestParam String key, @RequestParam String value) {
        return bloomFilterService.contains(key, value);
    }
}

以上示例显示了如何在 Spring Boot 中使用 Redisson 的 RBloomFilterSharding 进行分片布隆过滤器操作。

✌基数估计算法(HyperLogLog)

✍作用

HyperLogLog是一种用于估计集合的基数(即集合中的不同元素数量)的算法。

✍使用场景

  • 估计大数据集中的唯一元素数量。
  • 流量统计。

✍优缺点

优点:

  • 使用的内存量很小。
  • 能够处理非常大的数据集。

缺点:

  • 提供的是估计值,而不是确切的计数。
  • 有一定的误差范围。

✍示例

Redisson 提供了 HyperLogLog 的实现,它是一个用于基数估计的算法。基数估计的应用之一是估算唯一元素的数量,而不必存储这些元素本身。HyperLogLog 特别适用于数据量非常大时的场景。

import org.redisson.api.RHyperLogLog;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class HyperLogLogService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 往 HyperLogLog 中添加元素
     *
     * @param key HyperLogLog 的名字
     * @param value 要添加的元素
     * @return 如果添加成功返回 true,否则返回 false
     */
    public boolean add(String key, Object value) {
        RHyperLogLog<Object> hyperLogLog = redissonClient.getHyperLogLog(key);
        return hyperLogLog.add(value);
    }

    /**
     * 获取 HyperLogLog 中估算的基数(唯一元素数量)
     *
     * @param key HyperLogLog 的名字
     * @return 估算的基数
     */
    public long count(String key) {
        RHyperLogLog<Object> hyperLogLog = redissonClient.getHyperLogLog(key);
        return hyperLogLog.count();
    }

    /**
     * 合并多个 HyperLogLog
     *
     * @param destinationKey 合并后的 HyperLogLog 名字
     * @param sourceKeys 需要合并的 HyperLogLog 名字数组
     */
    public void mergeTo(String destinationKey, String... sourceKeys) {
        RHyperLogLog<Object> destination = redissonClient.getHyperLogLog(destinationKey);
        RHyperLogLog<Object>[] sources = new RHyperLogLog[sourceKeys.length];
        for (int i = 0; i < sourceKeys.length; i++) {
            sources[i] = redissonClient.getHyperLogLog(sourceKeys[i]);
        }
        destination.mergeWith(sources);
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class HyperLogLogController {

    @Autowired
    private HyperLogLogService hyperLogLogService;

    @PostMapping("/addHLL")
    public boolean add(@RequestParam String key, @RequestParam String value) {
        return hyperLogLogService.add(key, value);
    }

    @GetMapping("/countHLL")
    public long count(@RequestParam String key) {
        return hyperLogLogService.count(key);
    }

    @PostMapping("/mergeHLL")
    public void merge(@RequestParam String destinationKey, @RequestParam String[] sourceKeys) {
        hyperLogLogService.mergeTo(destinationKey, sourceKeys);
    }
}

✌整长型累加器(LongAdder)

整长型累加器是一个分布式数据结构,用于在多线程环境中高效地累加长整数值。

✍作用

提供一种高效的方式在分布式环境中累加长整数。

✍使用场景

  • 统计:累加大量数据。
  • 计数器:如网站访问计数、库存计数等。

✍优缺点

优点:

  • 高效:为多线程环境优化,比原子整数更快。
  • 可扩展性:适用于分布式环境。

缺点:

  • 精度:由于是累加器,只能进行加操作。

✍示例

RLongAdder 是 Redisson 提供的一个接口,允许用户对存储在 Redis 中的长整型数进行原子操作。它是分布式的并存储在 Redis 中。此接口的功能与 Java 的 LongAdder 相似,但具有分布式特性。

import org.redisson.api.RLongAdder;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 增加指定键的值
     *
     * @param key   用于存储的键
     * @param value 要增加的值
     */
    public void add(String key, long value) {
        // 获取 RLongAdder 对象
        RLongAdder longAdder = redissonClient.getLongAdder(key);
        // 增加值
        longAdder.add(value);
    }

    /**
     * 获取指定键的当前值
     *
     * @param key 用于检索的键
     * @return 当前值
     */
    public long sum(String key) {
        // 获取 RLongAdder 对象
        RLongAdder longAdder = redissonClient.getLongAdder(key);
        // 返回当前的累计值
        return longAdder.sum();
    }

    /**
     * 重置指定键的值为0
     *
     * @param key 用于重置的键
     */
    public void reset(String key) {
        // 获取 RLongAdder 对象
        RLongAdder longAdder = redissonClient.getLongAdder(key);
        // 重置为0
        longAdder.reset();
    }
}

✌双精度浮点累加器(DoubleAdder)

双精度浮点累加器是一个分布式数据结构,用于在多线程环境中高效地累加双精度浮点数。

✍作用

提供一种高效的方式在分布式环境中累加双精度浮点数。

✍使用场景

  • 统计分析:累加大量的浮点数数据。
  • 数据处理:需要高精度累加的应用。

✍优缺点

优点:

  • 高效:为多线程环境优化,比原子双精度浮点更快。
  • 可扩展性:适用于分布式环境。

缺点:

  • 精度:由于是累加器,只能进行加操作。

✍示例

RDoubleAdder 是 Redisson 提供的一个接口,允许用户对存储在 Redis 中的双精度浮点数进行原子操作。这是一个分布式的累加器,其功能与 Java 的 DoubleAdder 类似,但它具有分布式特性,数据是存储在 Redis 中的。

import org.redisson.api.RDoubleAdder;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedissonService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 增加指定键的值
     *
     * @param key   用于存储的键
     * @param value 要增加的值
     */
    public void add(String key, double value) {
        // 获取 RDoubleAdder 对象
        RDoubleAdder doubleAdder = redissonClient.getDoubleAdder(key);
        // 增加值
        doubleAdder.add(value);
    }

    /**
     * 获取指定键的当前值
     *
     * @param key 用于检索的键
     * @return 当前累加的值
     */
    public double sum(String key) {
        // 获取 RDoubleAdder 对象
        RDoubleAdder doubleAdder = redissonClient.getDoubleAdder(key);
        // 返回当前的累计值
        return doubleAdder.sum();
    }

    /**
     * 重置指定键的值为0.0
     *
     * @param key 用于重置的键
     */
    public void reset(String key) {
        // 获取 RDoubleAdder 对象
        RDoubleAdder doubleAdder = redissonClient.getDoubleAdder(key);
        // 重置为0.0
        doubleAdder.reset();
    }
}

✌限流器(RateLimiter)

限流器是一个工具,用于限制某些资源或操作的访问速率。

✍作用

确保系统不会因为过多的请求而崩溃,通过限制访问速率来维护系统的稳定性。

✍使用场景

  • Web应用:防止DDoS攻击或过多的用户请求。
  • API:确保API不会被过度使用。

✍优缺点

优点:

  • 保护系统:确保系统稳定运行,不会因为过多的请求而崩溃。
  • 可配置性:可以根据需要配置速率限制。

缺点:

  • 延迟:可能会增加请求的延迟。
  • 需要管理:必须正确配置和管理速率限制。

✍示例

Redisson 的 RRateLimiter 提供了一个分布式的速率限制器,允许你在分布式系统中实现限流功能,这在防止资源过度使用或确保服务不被过多的请求淹没等场景下是非常有用的。

import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RateLimiterService {

    // 自动注入 RedissonClient
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 初始化限流器
     *
     * @param key         限流器的名字
     * @param rateType    限流类型 (例如 RateType.OVERALL)
     * @param permitsPerSecond 允许的请求数量/秒
     */
    public void initRateLimiter(String key, RateType rateType, long permitsPerSecond) {
        // 获取限流器对象
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
        // 设置配置
        rateLimiter.trySetRate(rateType, permitsPerSecond, 1, RateIntervalUnit.SECONDS);
    }

    /**
     * 获取令牌,如果当前没有可用令牌则阻塞
     *
     * @param key 限流器的名字
     * @return true 如果获取到令牌, false 否则
     */
    public boolean acquire(String key) {
        // 获取限流器对象
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
        // 尝试获取令牌
        return rateLimiter.tryAcquire();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yueerba126

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值