- 缓存功能
通常项目使用redis作为缓存,mysql作为数据库。查询操作先从redis获取数据,如果没有则从数据库查询并缓存到redis。对常用参数配置值(促销活动某批次预售次数限制),业务对象值(用户数据,车辆),进行数据缓存。通常对数据缓存会设置一个失效时间,需要注意的是,缓存的失效时间会设置有些间隔,防止缓存集体失效时redis有所卡顿,影响redis的读写操作。
- 频率限制
对第三方收费插件进行频率限制,降低费用,节省开支。短信服务,通常在发送手机验证码时,限制同一用户1分钟发送一次短信验证码;违章查询服务,限制同一车牌一天内查询一次。短信服务示例代码如下:
String phone = "15123456366";
String msgLimitKey = "msg:limit:" + phone;
boolean canBeSent = redisTemplate.opsForValue().setIfAbsent(msgLimitKey, "1", Duration.ofSeconds(60));
if (canBeSent) {
// TODO send msg
} else {
// 限制频率
}
对于热销活动,为了限制黄牛倒卖商品,会限制同一用户对同一商品的购买数量。例如,火车票的售卖,秒杀商品。促销活动热销商品的示例代码如下:
int limitCount = 5;
long goodsId = 1l;
Date activityExpiredDate = DateUtil.tomorrow();
String goodsLimitKey = "goods:limit:" + goodsId;
boolean canBuy = redisTemplate.opsForValue().increment(goodsLimitKey) <= limitCount;
redisTemplate.expireAt(goodsLimitKey, activityExpiredDate);
if (canBuy) {
// TODO 购买商品
} else {
// 限制频率
}
使用消息队列消费消息时,需要对消息进行幂等处理,例如,支付成功修改订单状态。示例代码:
String msgId = "7311eb92-f395-4bad-9a68-a9c8d1800b07";
String msgLimitKey = "mq:msg:" + msgId;
boolean canHandleMsg = redisTemplate.opsForValue().setIfAbsent(msgLimitKey, "1", Duration.ofHours(1));
if (canHandleMsg) {
// TODO 处理消息
}else {
// 限制频率
}
- 用户session
在分布式中,简单实现用户登录认证,就是用户登录成功以后,把用户信息存储到redis。每次用户登录或更新用户从redis中集中获取。