# shortlink **Repository Path**: zandls/shortlink ## Basic Information - **Project Name**: shortlink - **Description**: 短链系统 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-09-05 - **Last Updated**: 2024-09-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 官方文档 - 什么是 SaaS 短链接系统:[https://nageoffer.com/shortlink](https://nageoffer.com/shortlink) - 🔥SaaS 短链接视频教程:[https://nageoffer.com/shortlink/video](https://nageoffer.com/shortlink/video) --- 模块学习路径: 1、用户模块 2、短链分组 3、短链管理 4、回收站管理 5、短链监控 6、功能扩展 在线体验地址:[SaaS短链接演示环境](http://shortlink.magestack.cn) 受限于网络安全规则,短链接跳转的目标网址仅支持 [拿个offer](https://nageoffer.com)、[知乎](https://zhihu.com)、[掘金](https://juejin.cn)、[博客园](https://cnblogs.com) 域名下所属链接。 ## 学习说明 - 固定脱敏操作(这里不适用于动态去敏) UserRespDTO.class 注解:@JsonSerialize(using = PhoneDesensitizationSerializer.class) ```java public class PhoneDesensitizationSerializer extends JsonSerializer { @Override public void serialize(String phone, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { String phoneDesensitization = DesensitizedUtil.mobilePhone(phone); jsonGenerator.writeString(phoneDesensitization); } } ``` - redis的布隆过滤器 这里注意布隆过滤器无法精确查询,而当前项目认为可以查询到,这里注意点,下面是布隆过滤器的具体实现方式 ```java import org.redisson.api.RBloomFilter; public class demo { private final RBloomFilter userRegisterCachePenetrationBloomFilter; public void getInfo() { userRegisterCachePenetrationBloomFilter.add(requestParam.getUsername()); userRegisterCachePenetrationBloomFilter.contains(username); } } ``` - ThreadLocal的大批量使用 ```java public final class UserContext { /** * */ private static final ThreadLocal USER_THREAD_LOCAL = new TransmittableThreadLocal<>(); /** * 设置用户至上下文 * * @param user 用户详情信息 */ public static void setUser(UserInfoDTO user) { USER_THREAD_LOCAL.set(user); } /** * 获取上下文中用户 ID * * @return 用户 ID */ public static String getUserId() { UserInfoDTO userInfoDTO = USER_THREAD_LOCAL.get(); return Optional.ofNullable(userInfoDTO).map(UserInfoDTO::getUserId).orElse(null); } /** * 获取上下文中用户名称 * * @return 用户名称 */ public static String getUsername() { UserInfoDTO userInfoDTO = USER_THREAD_LOCAL.get(); return Optional.ofNullable(userInfoDTO).map(UserInfoDTO::getUsername).orElse(null); } /** * 获取上下文中用户真实姓名 * * @return 用户真实姓名 */ public static String getRealName() { UserInfoDTO userInfoDTO = USER_THREAD_LOCAL.get(); return Optional.ofNullable(userInfoDTO).map(UserInfoDTO::getRealName).orElse(null); } /** * 清理用户上下文 */ public static void removeUser() { USER_THREAD_LOCAL.remove(); } } ``` - 分布式锁的使用 lock.lock() 和 lock.tryLock() Redisson 是一种基于 Redis 的分布式锁框架,提供了 lock() 和 tryLock() 两种获取锁的方法。 lock() 方法是阻塞获取锁的方式,如果当前锁被其他线程持有,则当前线程会一直阻塞等待获取锁,直到获取到锁或者发生超时或中断等情况才会结束等待。该方法获取到锁之后可以保证线程对共享资源的访问是互斥的,适用于需要确保共享资源只能被一个线程访问的场景。Redisson 的 lock() 方法支持可重入锁和公平锁等特性,可以更好地满足多线程并发访问的需求。 而 tryLock() 方法是一种非阻塞获取锁的方式,在尝试获取锁时不会阻塞当前线程,而是立即返回获取锁的结果,如果获取成功则返回 true,否则返回 false。Redisson 的 tryLock() 方法支持加锁时间限制、等待时间限制以及可重入等特性,可以更好地控制获取锁的过程和等待时间,避免程序出现长时间无法响应等问题。 因此,两种获取锁的方式各有优缺点,在实际应用中需要根据具体场景和业务需求来选择合适的方法,以确保程序的正确性和高效性。 注意tryLock()加了leaveTime就没看门狗机制,所以提供了public boolean tryLock(long waitTime, TimeUnit unit)和public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)