作为程序员你们显示是什么状态呢?
1.工作技术太落后,工作主要是CRUD,没有机会接触底层技术
2.想去大厂,一直待在中小公司或者外包公司,想去BAT一线互联网公司
3.工作危机,掌握的技术和工作年限严重不匹配,技术能力无法胜任目前工作岗位
4.自学很迷茫,Java技术栈很多,不知道该学哪些,看书,看博客效率太低,没人指导很迷茫,刚学的技术很快就忘了
很多程序员感觉可能会感觉自己的技术还可以,但是你们有没有尝试过去一线互联网面试看看,有的是不是被虐了,很多程序员会感觉遇到了技术瓶颈了,其实很多中小型的公司那些所谓的项目经理只是个title,title是什么意思,只是职位而已,可能他们还没有达到阿里P6技术能力,但是无可否认,还是有一小部分技术厉害的
看一下一线大厂的技术栈

我们可以看一下个大厂互联网公司技术等级对比


我们肯定会想到使用synchronzed同步代码块,我们都知道jdk提供的锁是在jvm进程级别的,说白了就是只在tomcat下有效,显然分布式项目并不适用
我们可以来测试一下高并发场景下的压力测试,使用Apache jMeter
我们在服务器中使用nginx设置两个集群,之后请求通过nginx进行分发具体的集群,我们开启两个tomcat,使用jMeter高并发压力测试设置200个请求,执行完后可以看到两个端口存在剩余库存相同的情况,这就验证了我们之前结论在分布式高并发场景下使synchronzed同步代码块失效
我们我们接下会想到一个问题,那就是在分布式架构下如何保证线程安全的问题,我们今天讲的是在分布式架构下如何实现redis分布式锁
我们对redis的nx锁肯定不陌生,它的格式是 setnx key value
将key的值设为value,当且仅当key不存在的时候,若给定的key已经存在,则setnx不做任何操作
设置一个全局的分布式锁 lockKey = "lockKey"设置到key里面
因为reids是单线程,当几个请求通过nginx分发同时到两个tomcat中同时请求redis,但是到达redis会给你们到达先后进行排队,谁先到谁先执行redis的操作
当nginx分发到tomcat后去执行redis具体的业务,先通过setnx获取锁,返回ture,则证明成功获取到锁,然后执行具体的业务逻辑,没有拿到锁直接返回获取锁失败,处理完业务逻辑后释放锁delete,留给后面的人获取
我们还需要考虑的一个问题,当我们拿到锁后执行完减库存操作的时候发生异常抛了一个异常,这个执行停止了,还没有来得及释放锁,这就以为着其它人请求都是获取锁失败,这就造成了死锁,那么我们怎能解决死锁的问题呢
这时候我们可以想到可以给redis锁加过期时间expire
这时候我们可能会产生质疑,如果在执行设置锁过期时间之前宕机了,我们还是仅仅不了死锁的问题,redis中有一个命令,可以给设置锁和设置过期时间一个原子操作命令,原子操作即要么同时成功,要么同时失败
我们需要思考的一个问题是在中小型公司可能业务的高并发需求不是很大,采用这种处理方案完全没问题,如果在阿里的高并发请求中这种完全失控,接下来我们来解析一下为什么完全失控

我们如何解决这样的问题呢
我们可以设置一个全局的锁的id,这个id是使用UIID.randomUUID生成的随机数,设置为cliendId,在获取锁的时候锁的id设置到value里面,当前线程执行完业务后释放锁之前先判断是否是自己的锁,如果是,则释放
我们还需要思考的问题
比如拿到锁后,锁的过期时间是30秒,处理业务30秒还是没有完成获取mysql在运行慢查询5分钟,这时候分布式锁还是失效
应该怎么解决这个问题呢,我们可以思考一下,使用使用redis的延长失效时间,具体的逻辑

String lockKey = "lockKey ";
RLock redissonLock = redisson.getLock(lockKey );
redissonLock.lock();
.................处理业务
redissonLock.unlock();
redisson底层原理
