day06-缓存,redisson

1.查询缓存

为了系统性能的提升,一般都会将数据放入缓存中,加速访问。而db承担数据的持久化操作

高并发系统,缓存是必备的

 

2.压力测试工具

jmeter

 

3.分布式的锁

由于以前的锁都是进程内的锁,所以在分布式系统下并没有效果,这里就需要更加先进的适合分布式的锁

锁的原理就是多个线程使用同一把锁

以前的锁:进程内的锁

RPC需要的是进程间的锁

 

day06-缓存,redisson

 

spring的组件是单例模式的,就算有100个Controller请求,spring也只会注入一个bean.所以一个Sereviced的锁是同一个锁

所以在Service通过synchronized(this)可以锁住,通过synchronize(组件)也可以锁住当前线程,因为bean是单实例的

 

那么分布式下怎么办呢?

1)加锁操作一定要是原子性的。这里的思想就是利用了redis,往redis中存一个值,其他线程想获取锁就是从redis取出这个值,谁拿到了这个值谁就拿到了锁,没拿到的就自旋等待。因为redis是单线程的,所以可以把操作弄成一个原子操作,,即setnx 也就是set if not exist

Integer lock = setnx("lock","111")

lock =0说明已经有人获得锁,此次获取失败,lock=1说明可以开始获取锁,即别人没有占用锁,setnx能保证就算1万个线程进来也只有一个线程可以执行setnx得到值1

但是这个时候如果得到锁的线程无限循环等原因导致锁没释放,其他线程永远自旋等待

2)设置过期时间        加锁和设置过期时间也必须是原子性的,这两个操作合在一起是原子操作。也就是这样设置 set lock ex 10 nx

(设置一个key叫做lock,超时时间10s,当该key不存在时执行),用这个代替setnx lock,即多了超时时间

String ok = setnxex().还要保证删除的锁是自己的锁,把自己的uuid作为key存进redis,最后的问题是我们获取锁时,锁的值正在给我们返回的过程中过期了,redis删除了该key,这里的原因又是因为删除锁不是原子操作的

 

所以,分布式锁的核心

1)加锁一定要是原子性的

2)锁要设置超时时间

3)解锁也要是原子性的

day06-缓存,redisson

 

 

锁的考虑

1)自旋

      自旋次数

      自旋超时

2)锁设置

       锁粒度:细,记录级别

              a)各自服务各自的锁

             b)分析好粒度,不要锁住无关数据。一种数据一种锁,一条数据一个锁

3)锁类型

       读写锁

       。。。

 

要解决上述的考虑,就要用到redisson了

附上redisson的github地址:https://github.com/redisson/redisson/wiki/8.-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%92%8C%E5%90%8C%E6%AD%A5%E5%99%A8