u2-distributed-operator提供了一些分布式系统中常用的组件,解决方案,原理讲解,只需简单的配置便可使用
基于zookeeper的分布式锁原理
1.注解
lockName:锁名称,可以自定义锁名称,如果不定义,则自动生成
LockType:锁类型,提供了多种锁类型,默认为可重入锁
requireTime:获取锁时间,获取锁时间就是在这个时间范围内如果获取不到锁,则会退出,防止无休止的等待下去,造成阻塞
unit:时间单位
public @interface U2Lock {
/**
* 锁名字
*/
String lockName() default "";
/**
* 锁类型
* @return
*/
LockType lockType() default LockType.MUTEX_LOCK;
/**
* 时间
*/
long requireTime() default 30000;
/**
* 时间单位
*/
TimeUnit unit() default TimeUnit.MILLISECONDS;
}
2.yml配置
配置zookeeper的一些连接连接属性,
u2-lock:
address: 127.0.0.1:2181 #多机逗号隔开
connection-timeout: 1500000000
session-timeout: 600000
retry-policy: retry-forever #重试策略
retry-forever: #对应重试策略配置
retry-interval-ms: 3000
3.使用
@GetMapping("get")
@U2Lock(lockName = "order-get",lockType = LockType.MUTEX_LOCK,requireTime = 50000)
public Map<String,Object> lock(@RequestParam int id , @RequestParam String num){
Map<String,Object> map = new HashMap<>();
if (count > 0){
count--;
map.put("order_num",count);
return map;
}
map.put("msg","商品已售罄");
return map;
}
1.注解
lockType:所类型默认为可重入锁,还有其他锁可选
公平锁(Fair Lock)
联锁(MultiLock)
红锁(RedLock)
读写锁(ReadWriteLock)
waitTime:等待时间,在这个时间范围内获取不到锁,则退出获取锁
leaseTime:就是锁过期时间,达到这个时间,redis会删除这个key
public @interface U2Lock {
/**
* 锁类型
* @return
*/
LockType lockType() default LockType.REENTRANT_LOCK;
/**
* 等待时间
* @return
*/
long waitTime() default 25;
/**
* 释放锁时间
* @return
*/
long leaseTime() default 50;
/**
* 时间单位
* @return
*/
TimeUnit unit() default TimeUnit.SECONDS;
/**
* 锁名称
* @return
*/
String lockName() default "";
}
2.yml
u2-lock:
pattern: SINGLE
password: xiaosi520
address: redis://101.200.54.149:6379
idle-connection-timeout: 6000
idle-size: 10
pattern为redis模式,可单机(SINGLE),集群(CLUSTER),主从(MASTER_SLAVE),哨兵(SENTINEL),使用红锁pattern为RED_LOCK
红锁:
基于Redis的Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例,Martin Kleppmann建议红锁至少要5个redis节点以上。
红锁配置如下
u2-lock:
pattern: RED_LOCK
password: xiaosi520
address: redis://116.198.160.10:6379
red-lock:
- "redis://116.198.160.10:6379,123456" #123456为密码
- "redis://116.198.160.11:6379,123456"
- "redis://116.198.160.12:6379,123456"
- "redis://116.198.160.25:6379,123456"
- "redis://116.198.160.20:6379,123456"
@GetMapping("test")
@U2Lock(lockType = LockType.REENTRANT_LOCK,lockName = "red-lock")
public void test() throws InterruptedException {
}
无论是分布式系统还是单机系统,总会遇到表单按钮重复提交问题,前端可以进行控制,但是后端也必须进行控制,这里基于redis来进行防重
1.注解
lockTime():在这段时间类,这个用户不能重复提交
public @interface U2RepeatSubmit {
/**
* 锁接口时间
* @return
*/
long lockTime() default 1000L;
/**
* 时间单位
* @return
*/
TimeUnit unit() default TimeUnit.MILLISECONDS;
/**
* 消息提醒
* @return
*/
String msg() default "请勿重复提交";
}
2.yml
我们的项目和请求各不相同,所以可以基于参数防重,session会话,请求头,只需要携带能代表用户的唯一标识便可。
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
repeat-submit: #防重提交
identity: token #唯一标识
identity-location: header #参数位置 可为请求头header , 会话session , 请求参数parameter
3.使用
@U2RepeatSubmit(lockTime = 2000)
@GetMapping("submit")
public void submit(@RequestParam("uid") String uid){
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。