【Redis】redis分布式锁(二)
我的个人博客:https://www.wuyizuokan.com
在上一个博文中,为了进行分布式锁的测试,写了几个测试用的服务。博文地址:
https://www.cnblogs.com/wuyizuokan/p/11111313.html
有一个使用Java语言,采用SpringBoot框架的简单的Web服务,提供几个Rest接口,其中PUT接口和GET接口是幂等的,一个设置计数值,一个查询计数值;另外还有一个接口是POST的,是用来修改计算器值的。当然原则上要采用Restful风格的话,POST接口的功能是不符合Restful风格的。
还有一个使用Go语言编写的,用来调用Web服务的接口,为了讨论分布式锁,这里不使用POST接口,而是组合使用Get接口和Post接口,为何不使用POST接口呢?因为Web服务太简单了,而且在内部已经使用了synchronized来防止多线程访问问题,所以只能使用Get接口和POST接口的组合来操作的原子性了。
最后一个使用Python语言编写的,也是用来调用Web服务的,方案同上。
首先我们限定Java编写的Web服务为生产者服务,使用Go语言编写的服务为Go消费者服务,使用Python编写的服务为Python消费者服务。
这里模拟的测试场景是这样的:
两个消费者服务循环1000次,每循环一次,首先查询Count的值,然后给Count加20,然后使用PUT接口设置新的Count值。
消费者的流程图很简单:
下面是消费者的代码:
Go:
func main(){ for i:= 1000; i > 0;i-- { count,err := getCount() if err != nil { fmt.Println(err) continue } fmt.Println("the count is: ", count) count += 20 setCount(count) } }
Python:
if __name__=="__main__": n = 1000 while n > 0: count = getCount() # 测试查询Count print("the count is:", count) count += 20 setCount(count) n = n - 1
首先做一下分析,如果两个消费者的动者都能成功,count的值将会增加1000 * 20 *2 = 40000。当然,因为存在访问共享资源,且消费者的动作没有原子性,很可能无法达到增加40000的效果。
首先单独运行一遍go消费者和python消费者,不让它们并行运行,预期的值应该是40000:
go消费者运行:
使用postman查询结果:
然后运行Python消费者:
使用postman查询结果:
符合预期。
下面进行测试,为了便于测试,首先初始化Count的值为0:
同时启动go消费者和python消费者:
使用Postman查询Count的最终结果:
35080,很明显没有达到40000,符合预期的因为没有锁机制导致的共享资源的错误。
接下来,会使用redis来做一个分布式锁,看看如何使用redis来保证多个服务间访问共享数据的安全性。
当然,后面还会使用zookeeper来做分布式锁的实验,相对于redis来说,我更喜欢使用zookeeper的分布式锁方案。