问题

  • 资源竞争

场景

  • JVM内竞争

分布式环境竞争

解决方案

DB:mysql
  • 设置唯一主键,insert拿到锁,用完删除。注意唯一性,比如a线程上锁,需要a线程删锁
  • 乐观锁,update table set version = xxx where version = xx
  • 可能存在问题:
    • 一旦上锁后,服务重启,则无法释放锁了,其他线程无法释放
      • 解决方案:定时任务处理清除超时一定时间的数据
    • 锁非阻塞的:insert失败没有排队队列,需要重新触发重新获取锁
      • 客户端处理
    • 锁为非重入锁
      • 建表时,增加进入次数字段
Redis
  • 非重入:set lockKey randomValue NX PX 5000
  • 重入:可以基于hash实现可重入锁,key对应的value增加count属性,每次重入+1,释放-1
  • 优点:
    • redis速度快
    • Redission处理多节点加锁问题,处理主从数据同步问题
Zookeeper
  • 序号小的获取到锁资源,watch前一个节点,避免“羊群效应”
  • 优点
    • 内存中,性能高于DB
  • 缺点:
    • 并发问题:ZK集群网络分区,会出现多个client同时获取到锁的情况