Redisson中RSet的使用场景及用它来做网站独立访客统计的例子

server/2024/9/20 3:51:49/ 标签: redis, java

RSet 是 Redisson 提供的一个用于操作 Redis 的 Set 数据类型的高级接口。在 Redis 中,Set 是一个存储字符串元素的无序集合,不允许重复元素。RSet 在 Java 应用程序中提供了一种方便的方式来操作 Redis 中的 Set 结构。下面列举了一些可能使用 RSet 的场景:

  1. 用户权限管理
    在权限系统中,可以使用 RSet 来存储用户的权限列表。例如,一个用户可以拥有多个权限标识符,这些标识符可以存储在一个 RSet 中。

  2. 标签系统
    在社交媒体或内容管理系统中,文章或用户可以有多个标签。RSet 可以用来存储与文章或用户相关的所有标签,便于管理和查询。

  3. 黑名单/白名单
    在网络安全或反垃圾邮件系统中,可以使用 RSet 来存储黑名单或白名单的 IP 地址或邮箱地址,用于过滤请求或邮件。

  4. 去重统计
    当需要统计某个指标但要排除重复项时,RSet 可以用来存储已经统计过的唯一元素。例如,统计网站独立访客数量时,可以将每个访客的唯一标识符存入 RSet

  5. 好友列表
    在社交网络应用中,RSet 可以用来存储用户的“关注”或“好友”列表。

  6. 推荐系统
    推荐系统中,可以使用 RSet 来存储推荐给用户的商品或内容列表,确保不会重复推荐。

  7. 游戏排行榜
    尽管通常推荐使用 Sorted Set 来实现排行榜,但在一些不需要排序或排序逻辑较为简单的场景下,RSet 也可以用来存储玩家的ID,而分数可以单独存储或通过用户ID查询。

  8. 事件订阅
    在事件驱动架构中,RSet 可以用来存储订阅特定事件的用户或服务列表。

  9. 分布式锁
    RSet 可以用于实现分布式锁的等待队列,当一个资源被锁定时,其他请求可以被放入 RSet 中等待解锁。

  10. 缓存数据的版本控制
    当需要跟踪缓存数据的版本变化时,可以使用 RSet 来存储不同版本的标识符。

以下是使用 RSet 来统计网站的独立访客数量是一种常见做法,尤其是当需要去重访客标识符(比如 IP 地址、用户 ID 或 cookie 标识符)时。下面是一个详细的例子,展示了如何使用 Redisson 的 RSet 来实现这一功能。

首先,确保你已经添加了 Redisson 的依赖,并且配置好了 Redis 连接。以下是 Maven 依赖和 Java 配置的示例:

<!-- pom.xml -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.1</version>
</dependency>
java">// Java 配置
import org.redisson.Redisson;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class UniqueVisitorCounter {private static final String UNIQUE_VISITORS_KEY = "unique_visitors";private RedissonClient redisson;public UniqueVisitorCounter() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");this.redisson = Redisson.create(config);}//...
}

接下来,我们将定义方法来记录独立访客以及查询独立访客的数量。

记录独立访客

这个方法将接收一个访客标识符作为参数,并将其添加到 RSet 中。如果该访客之前已经访问过,则 RSet 的去重特性将防止其再次被添加。

java">public void recordVisitor(String visitorId) {RSet<String> uniqueVisitors = redisson.getSet(UNIQUE_VISITORS_KEY);uniqueVisitors.add(visitorId);
}

查询独立访客数量

这个方法将返回 RSet 中元素的数量,即独立访客的数量。

java">public long getUniqueVisitorCount() {RSet<String> uniqueVisitors = redisson.getSet(UNIQUE_VISITORS_KEY);return uniqueVisitors.size();
}

完整示例

将上述方法整合到一个类中,得到完整的示例代码如下:

java">import org.redisson.Redisson;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class UniqueVisitorCounter {private static final String UNIQUE_VISITORS_KEY = "unique_visitors";private RedissonClient redisson;public UniqueVisitorCounter() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");this.redisson = Redisson.create(config);}public void recordVisitor(String visitorId) {RSet<String> uniqueVisitors = redisson.getSet(UNIQUE_VISITORS_KEY);uniqueVisitors.add(visitorId);}public long getUniqueVisitorCount() {RSet<String> uniqueVisitors = redisson.getSet(UNIQUE_VISITORS_KEY);return uniqueVisitors.size();}public static void main(String[] args) {UniqueVisitorCounter counter = new UniqueVisitorCounter();// 假设这是从 web 日志或前端收集到的访客标识符counter.recordVisitor("visitor_1");counter.recordVisitor("visitor_2");counter.recordVisitor("visitor_1"); // 重复的访客,将不会被再次添加System.out.println("独立访客数量: " + counter.getUniqueVisitorCount());}
}

在这个示例中,recordVisitor 方法用于记录每个独立访客,而 getUniqueVisitorCount 方法则返回当前已记录的独立访客总数。这种方法适用于实时统计独立访客数量的场景,同时由于 RSet 的去重特性,可以有效避免重复计数的问题。


http://www.ppmy.cn/server/88902.html

相关文章

ubuntu安装mysql8.0

文章目录 ubuntu版本安装修改密码取消root跳过密码验证 ubuntu版本 22.04 安装 更新软件包列表 sudo apt update安装 MySQL 8.0 服务器 sudo apt install mysql-server在安装过程中&#xff0c;系统可能会提示您设置 root 用户的密码&#xff0c;请务必牢记您设置的密码。…

Github遇到的问题解决方法总结(持续更新...)

1.github每次push都需要输入用户名和token的解决方法 push前&#xff0c;执行下面命令 &#xff1a; git config --global credential.helper store 之后再输入一次用户名和token之后&#xff0c;就不用再输入了。 2.git push时遇到“fatal: unable to access https://githu…

Docker-Compose实现MySQL之主从复制

1. 主服务器(IP:192.168.186.77) 1.1 docker-compose.yml services:mysql-master:image: mysql:latest # 使用最新版本的 MySQL 镜像container_name: mysql-master # 容器的名称environment:MYSQL_ROOT_PASSWORD: 123456 # MySQL root 用户的密码MYSQL_DATABASE: masterd…

编写Dockerfile文件解释

编写Dockerfile文件的基本步骤如下&#xff1a; 首先&#xff0c;创建一个新的文本文件&#xff0c;并将其命名为Dockerfile。 在Dockerfile的第一行添加基础镜像的指令。例如&#xff0c;使用ubuntu 18.04作为基础镜像&#xff0c;可以添加以下指令&#xff1a; FROM ubunt…

数据结构第二讲:顺序表

数据结构第二讲&#xff1a;顺序表 1.线性表2.什么是顺序表3. 静态顺序表4.动态顺序表4.1顺序表基础4.2顺序表的初始化4.3顺序表的销毁4.4顺序表的尾插4.5顺序表的头插4.6顺序表的尾删4.7顺序表的头删4.8顺序表在指定位置之前插入数据4.9顺序表删除指定位置的数据4.10顺序表查找…

分享一个最近在进行前后端联调时改了2天的bug...

场景再现 我们这边前端端口是8080 后端端口是8121 我们在前端里在首页面写了一个任务 当进入网页三秒后 发起一个叫getLoginUser的请求 我们的getLoginUser是调用的这里 一个异步请求 这边我们前端调用后端的接口也已经写好 我们先把后端跑起来 访问前端页面 接收到了这个…

1858. 数组查找及替换

问题描述 给定某整数数组和某一整数 b 。 要求删除数组中可以被 b 整除的所有元素&#xff0c;同时将该数组各元素按从小到大排序。如果数组元素数值在 &#x1d434;‘ 到 Z 的 ASCII 之间&#xff0c;替换为对应字母。 元素个数不超过 100&#xff0c;&#x1d44f; 在 1 …

linux shell(中)

结构化命令 if语句 if-then 最基本的结构化命令是 if-then 语句。if-then 语句的格式如下&#xff1a; if command thencommands ifif command; then # 通过把分号&#xff08;;&#xff09;放在待求值的命令尾部&#xff0c;可以将 then 语句写在同一行commands ifbash sh…

git stash 命令详解

git stash 描述 git stash 命令用于将当前工作目录中的未提交更改&#xff08;包括暂存区和工作区的更改&#xff09;保存到一个栈中&#xff0c;并恢复工作目录到干净的 HEAD 状态。这样您可以在不提交当前更改的情况下&#xff0c;切换到其他分支或进行其他操作。后续可以通…

Golang使用docker sdk管理docker

包括列出容器、创建容器、删除容器、进入容器、构建镜像等操作。 package dockertoolimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/ap…

微服务安全——OAuth2.1详解、授权码模式、SpringAuthorizationServer实战、SSO单点登录、Gateway整合OAuth2

文章目录 Spring Authorization Server介绍OAuth2.0协议介绍角色OAuth2.0协议的运行流程应用场景授权模式详解客户端模式密码模式授权码模式简化模式token刷新模式 OAuth 2.1 协议介绍授权码模式PKCE扩展设备授权码模式拓展授权模式 OpenID Connect 1.0协议Spring Authorizatio…

java对接soap工具类-callSonyInterfaceQuery

新写的工具类&#xff0c;其中有对接soap的工具类 import com.shutong.common.exception.ServiceException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.Cont…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-抄送服务处理

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为仿钉钉设计器里抄送人是一个服务任务&#xff0c;所以要根据这个服务任务进行处理 2、前端就是一个抄送&#xff0c;选择人 3、这里用了jeecg的选择人组件 <el-form-item prop…

LongAlign:大模型长文本处理能力提升之道

人工智能咨询培训老师叶梓 转载标明出处 大模型&#xff08;LLMs&#xff09;在处理长文本时&#xff0c;需要在输入序列上进行指令微调&#xff08;instruction finetuning&#xff09;&#xff0c;以确保它们能够有效地处理长文本。现有的方法主要集中在上下文扩展&#xff0…

Qt第十三章 目录和文件操作

目录和文件操作 文章目录 目录和文件操作设备I/O简介I/O设备的类型基本文件读写QFileQTemporaryFile 流操作QTextStreamQDataStream QFileInfoQDirQFileSystemWatcherQStandardPathsQSettings 设备I/O 简介 I/O设备的类型 基本文件读写 QFile QFile file("C:/Users/PV…

C++ | Leetcode C++题解之第278题第一个错误的版本

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstBadVersion(int n) {int left 1, right n;while (left < right) { // 循环直至区间左右端点相同int mid left (right - left) / 2; // 防止计算时溢出if (isBadVersion(mid)) {right mid; // 答案…

力扣984.不含AAA或BBB的字符串

力扣984.不含AAA或BBB的字符串 贪心 如下 class Solution {public:string strWithout3a3b(int a, int b) {string res;while(a > b && b > 0){res "aab";a--,a--;b--;}while(b > a && a > 0){res "bba";b--,b--;a--;}whi…

C#实现数据采集系统-modbustcp数据通知

实现数据推送 在ModbusTcp模块中已经能够获取到正确的plc值,接下来做的就是如何让外部调用的程序获取到相关的数据,主要就是两种方法:通过对象属性进行共享;通过事件进行推送 方法一:通过类属性共享 在RegisterPoint类中增加public object Value { get; set; }value属性…

算法之递归算法

递归是非常常见的一种算法&#xff0c; 也比较难以理解&#xff0c;简而言之&#xff0c;递归就是写了一个方法&#xff0c;方法中还调用了该方法&#xff0c;相当于自己调用自己&#xff0c;如果书写不当&#xff0c;就会有堆栈溢出的风险&#xff0c;无法跳出。 所以我们编写…

【CTFWP】ctfshow-web36

文章目录 题目介绍&#xff1a;题目分析&#xff1a;payload&#xff1a;payload解释&#xff1a;flag 题目介绍&#xff1a; <?php/* # -*- coding: utf-8 -*- # Author: h1xa # Date: 2020-09-04 00:12:34 # Last Modified by: h1xa # Last Modified time: 2020-09-…