【Redis】redis分布式锁(二)

在上一个博文中,为了进行分布式锁的测试,写了几个测试用的服务。博文地址:

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的分布式锁方案。

猜你喜欢

转载自www.cnblogs.com/wuyizuokan/p/11300084.html