基于redis数据结构ZSET实现邀请人排行榜

基于redis数据结构ZSET实现邀请人排行榜

  1. 背景:用户注册可以填写邀请人id,系统记录邀请人排行情况
  2. 方案:因为ZSET是一个天然有序的数据结构,我们可以把积分当做score,userId当做member,放到zset中,zset会默认按照SCORE进行排序的。
  3. 代码实现

maven依赖

        <!--    Redisson    -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.24.3</version>
        </dependency>
    //用户注册
    //更新排名(inviterId邀请人ID)
    updateInviteRank(inviterId);

updateInviteRank的具体代码实现:

//定义RScoredSortedSet对象
private RScoredSortedSet<String> inviteRank;
//初始化
@Override
public void afterPropertiesSet() throws Exception {
    this.inviteRank = redissonClient.getScoredSortedSet("inviteRank");
}

private void updateInviteRank(String inviterId) {
    // 如果邀请者ID为空,则直接返回,不进行操作
    if (inviterId == null) {
        return;
    }
    // 获取Redisson的锁对象
    RLock rLock = redissonClient.getLock(inviterId);
    // 对邀请者ID对应的锁进行加锁操作,避免并发更新
    rLock.lock();
    try {
        // 获取邀请者的当前排名分数
        Double score = inviteRank.getScore(inviterId);
        // 如果当前分数为空,则设置默认为0.0
        if (score == null) {
            score = 0.0;
        }
        // 将邀请者的排名分数增加100.0,并更新到排行榜中
        inviteRank.add(score + 100.0, inviterId);
    } finally {
        // 最终释放邀请者ID对应的锁
        rLock.unlock();
    }
}

RScoredSortedSet提供了很多方法方便对ZSET进行操作,以下是一些常用的排行方法:

  • Double getScore(V var1); 获取指定成员的分数。
  • boolean add(double var1, V var3); 向有序集合中添加一个成员,指定该成员的分数。
  • Integer rank(V var1); 获取指定成员在有序集合中的排名(从小到大排序,排名从 0 开始)。
  • Integer revRank(V var1);获取指定成员在有序集合中的排名(从大到小排序,排名从 0 开始)。
  • Collection<ScoredEntry> entryRange(int var1, int var2); 获取分数在指定范围内的成员及其分数的集合。

获取前N个用户的排名信息

//按照分数从高到低,获取前N个用户的排名信息
public List<InviteRankInfo> getTopN(Integer topN) {
    Collection<ScoredEntry<String>> rankInfos = inviteRank.entryRangeReversed(0, topN - 1);

    List<InviteRankInfo> inviteRankInfos = new ArrayList<>();

    if (rankInfos != null) {
        for (ScoredEntry<String> rankInfo : rankInfos) {
            InviteRankInfo inviteRankInfo = new InviteRankInfo();
            String userId = rankInfo.getValue();
            if (StringUtils.isNotBlank(userId)) {
                User user = findById(Long.valueOf(userId));
                if (user != null) {
                    inviteRankInfo.setNickName(user.getNickName());
                    inviteRankInfo.setInviteCount(rankInfo.getScore().intValue() / 100);
                    inviteRankInfos.add(inviteRankInfo);
                }
            }
        }
    }
    return inviteRankInfos;
}
### 关于 'cache-loader' 模块未找到的解决方案 当遇到 `Syntax Error: Error: Cannot find module 'cache-loader'` 错误时,通常是因为某些依赖项未能正确安装或存在版本兼容性问题。以下是针对该问题的具体分析和解决方法: #### 1. 删除现有依赖并重新安装 由于部分依赖可能未完全下载或配置失败,建议清理当前环境中的依赖文件,并重新执行安装操作。 - **删除旧依赖** 进入项目根目录,运行以下命令以移除现有的 `node_modules` 文件夹以及锁定文件: ```bash rm -rf node_modules package-lock.json ``` - **重新安装依赖** 使用以下命令重新拉取所有必要的模块: ```bash npm install ``` 此过程会依据 `package.json` 配置自动解析所需依赖关系[^3]。 #### 2. 处理高版本 Node.js 和 NPM 的兼容性问题 如果使用的 Node.js 或 NPM 版本较高,则可能会触发上游依赖冲突的情况。此时可以通过指定参数来忽略此类警告并强制完成安装流程。 - 执行带选项的安装指令: ```bash npm install --legacy-peer-deps ``` 上述命令能够有效规避因新策略引入而导致的部分历史遗留库无法匹配的问题[^4]。 #### 3. 明确目标加载器及其关联插件的状态 确认是否遗漏了其他间接影响到构建链路的关键组件(例如 `sass-loader`, `style-loader`)。对于特定场景下的样式表预处理工具缺失情况也需要同步关注[^1]。 通过上述措施基本可以消除由缓存机制引发的相关异常状况;当然,在实际开发过程中还应定期更新全局管理软件至最新稳定版次从而减少不必要的麻烦发生几率。 ```javascript // 示例代码片段展示如何验证已修复后的服务端渲染功能是否恢复正常工作状态。 const express = require('express'); const path = require('path'); let app = express(); app.use(express.static(path.join(__dirname, './dist'))); app.listen(8080,function(){ console.log("Server is running on port 8080..."); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值