redis

单点登陆大概逻辑

=============================查询部分==================================
1.取出Cookie
2.判断Cookie中是否有CSESSIONID
3.有,直接使用
4:没有,创建一个CSESSIONID,并保存到COOKIE中,
  同时,把此COOKIe写回浏览器  使用此生成的CSESSIONID 
5.设置 存活时间 -1(关闭页面)
6.设置路径 /
7.设置跨域
8.以CSESSIONID:NAME为key获取value
9.value不为null,以CSESSIONID:NAME为key,超时时间为value存入redis,
刷新超时时间,返回success
10.value为null,返回fail
=============================登陆部分==================================
1.判断账户密码的准确性
2.重复查询部分1-7
3.以CSESSIONID:NAME为key,超时时间为value存入redis,设置超时时间
==============================备注=====================================
CSESSIONID=UUID去除-
Jedis jedis = jedisPool.getResource();
jedis.close();
如果是使用连接池的形式,这个并非真正的close,而是把连接放回连接池中
复制代码

接口权限认证AOP

ReentrantLock保证线程安全/分布式可以用分布式锁
@Around环绕方式
lock.lock();
(ProceedingJoinPoint)pjp.proceed(args);token失败修改一个参数即可
lock.unlock();
=======================ReentrantLock(重入锁)============================
private Lock lock = new ReentrantLock();
private Condition condition=lock.newCondition();
线程1
lock.lock();
condition.await();释放了锁
线程2
lock.lock();
condition.signal();线程1继续跑
特别的:condition对象的signal只对本condition对象的await生效,
而object的notify()随机,两者的wait都释放锁,thread的sleep不释放
ReentrantReadWriteLock读写锁
lock.readLock().lock();
lock.readLock().unlock();
lock.writeLock().lock();
lock.writeLock().unlock();
多线程异步读,同步写
复制代码

redis分布式锁

场景一:C0操作超时了,但它还持有着锁,C1和C2读取lock.foo检查时间戳,先后发现超时了。 
C1 发送DEL lock.foo 
C1 发送SETNX lock.foo 并且成功了。 
C2 发送DEL lock.foo 
C2 发送SETNX lock.foo 并且成功了。 
这样一来,C1,C2都拿到了锁!问题大了!

场景二:C3发送SETNX lock.foo 想要获得锁,由于C0还持有锁,所以Redis返回给C3一个0 
C3发送GET lock.foo 以检查锁是否超时了,如果没超时,则等待或重试。 
反之,如果已超时,C3通过下面的操作来尝试获得锁: 
GETSET lock.foo <current Unix time + lock timeout + 1> 
通过GETSET,C3拿到的时间戳如果仍然是超时的,那就说明,C3如愿以偿拿到锁了。 
如果在C3之前,有个叫C4的客户端比C3快一步执行了上面的操作,那么C3拿到的时间戳是个未超时的值,
这时,C3没有如期获得锁,需要再次等待或重试。留意一下,尽管C3没拿到锁,
但它改写了C4设置的锁的超时值,不过这一点非常微小的误差带来的影响可以忽略不计。 

	     Jedis jedis = jedisPool.getResource();
	     //setNx加锁
	     long now = System.currentTimeMillis();
	     boolean result = jedis.setnx(lockName, String.valueOf(now + expire * 1000)) == 1;
	     if (!result) {
	         //防止死锁的容错 
	         String timestamp = jedis.get(lockName);
	         //检查锁是否超时了,如果没超时,则等待或重试
	         if (timestamp != null && Long.parseLong(timestamp) < now) {
	             //不通过del方法来删除锁。而是通过同步的getSet
	             String oldValue = jedis.getSet(lockName, String.valueOf(now + expire));
	             if (oldValue != null && oldValue.equals(timestamp)) {
	            	 //到的时间戳如果仍然是超时的,那就说明,C1如愿以偿拿到锁了
	                 result = true;
	                 jedis.expire(lockName, expire);
	             }
	         }
	     }
	     if (result) {
	         jedis.expire(lockName, expire);
	     }
	     //从源码可以分析得到,如果是使用连接池的形式,这个并非真正的close,而是把连接放回连接池中
	     jedis.close();
	     return result;
	     
	     
高版本的set命令也可以搞定。

复制代码

转载于:https://juejin.im/post/5c174686e51d452d2e7a91b8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值