Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • 如何设计一个短链系统
  • 新Get的开发技巧
  • 项目通用工具

  • 用户模块

    • 持久层
    • 实体类
    • 用户查询
    • 用户注册
      • 如何防止用户名重复?
      • 大量请求一个未注册用户名?
      • 修改用户
    • 用户登录
    • 用户分库分表
    • 用户上下文
  • 短链模块

  • 流量风控
  • 如何获取用户IP?
  • SaaS短链接系统
  • 用户模块
Nreal
2024-01-03
目录

用户注册

# 如何防止用户名重复?

  1. 布隆过滤器将所有用户名加载;

  2. 数据库添加唯一索引;

# 大量请求一个未注册用户名?

加锁避免缓存穿透;

private final RedissonClient redissonClient;

// ......

@Override
public void register(UserRegisterReqDTO requestParam) {
    if(!hasUsername(requestParam.getUsername())){
        throw new ClientException(USER_NAME_EXIST);
    }
    RLock lock = redissonClient.getLock(LOCK_USER_REGISTER_KEY+requestParam.getUsername());
    try {
        if(lock.tryLock()){
            // 布隆过滤器误判,捕捉异常
            try {
                // 获得锁 插入数据库
                int inserted = baseMapper.insert(BeanUtil.toBean(requestParam, UserDO.class));
                if(inserted < 1){
                    throw new ClientException(USER_SAVE_ERROR);
                }
            } catch (DuplicateKeyException ex) {
                throw new ClientException(USER_EXIST);
            }
            userRegisterCachePenetrationBloomFilter.add(requestParam.getUsername());
            //todo 设置默认分组
            return ;
        }
        throw new ClientException(USER_NAME_EXIST);
    } finally {
        lock.unlock();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 修改用户

接口:

@PutMapping("/api/short-link/admin/v1/user")
public Result<Void> update(@RequestBody UserUpdateReqDTO requestParam) {
    userService.update(requestParam);
    return Results.success();
}
1
2
3
4
5
@Override
public void update(UserUpdateReqDTO requestParam) {
    // todo 验证当前用户名是否为登录用户
    LambdaUpdateWrapper<UserDO> updateWrapper = Wrappers.lambdaUpdate(UserDO.class)
            .eq(UserDO::getUsername, requestParam.getUsername());
    baseMapper.update(BeanUtil.toBean(requestParam,UserDO.class),updateWrapper);
}
1
2
3
4
5
6
7
用户查询
用户登录

← 用户查询 用户登录→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式