干货详解:一文带你了解分布式场景下的并发安全问题

1.并发场景下JDK锁的局限性

使用JDK的锁在单节点上能很好解决并发安全问题,可一旦到了分布式场景下,JDK的锁就会捅娄子了。

1.1. 初始代码

干货详解:一文带你了解分布式场景下的并发安全问题

上图是个Controller本身这controller的OrderNumGenerator已经解决了并发安全问题

<code>

package

cn.enjoy.lock;

import

cn.enjoy.utils.FileId;

import

java.text.SimpleDateFormat;

import

java.util.Date;

import

java.util.concurrent.locks.ReentrantLock;

public

class

OrderNumGenerator

{

private

java.util.concurrent.locks.Lock lock =

new

ReentrantLock(); /<code>


1.2. 启动2个tomcat

修改springboot配置文件application.properties

干货详解:一文带你了解分布式场景下的并发安全问题

修改端口为8081

使用启动类分别启动8080,8081

干货详解:一文带你了解分布式场景下的并发安全问题

1.3. 配置nginx访问

干货详解:一文带你了解分布式场景下的并发安全问题

1.4. 使用JMeter测试

干货详解:一文带你了解分布式场景下的并发安全问题

把测试结果排序后

干货详解:一文带你了解分布式场景下的并发安全问题

虽然单个节点解决了并发安全问题,但是在分布式场景下,依然出现了并发安全问题

2. 使用分布式锁解决

通过上面的案例使用JDK的锁解决不了分布式场景下的并发安全问题,接下来就考虑使用分布式锁来解决了。

2.1. 解决方案概述

分布式锁有很多种方案

干货详解:一文带你了解分布式场景下的并发安全问题

这些方案可以使用一个设计模式来统一

2.2. 模板方法模式

2.2.1. 模板方法介绍

在父类中编排主流程,将步骤实现延迟到子类去实现。

干货详解:一文带你了解分布式场景下的并发安全问题

上图网上购物的时候总体4个流程

  1. 清点商品
  2. 计算价格
  3. 支付(未知扩展)
  4. 送货上门

2.2.2. 代码实现

<code>

package

cn.enjoy.template;

import

java.util.ArrayList;

import

java.util.HashMap;

import

java.util.List;

import

java.util.Map;

public

abstract

class

AbstractTemplate

{

public

void

shopping

()

{ Map cars =

new

HashMap(); cars.put(

"电池"

,

10f

); cars.put(

"娃娃"

,

20f

); cars.put(

"打气筒"

,

30f

); /<code>

对于支付来说是【未知的扩展】因此它是个抽象的方法,如果想使用微信支付可以重现pay方法

干货详解:一文带你了解分布式场景下的并发安全问题

2.3.
分布式锁的模板方法

2.3.1. 概览

干货详解:一文带你了解分布式场景下的并发安全问题

1、定义锁的接口Lock

2、在AbstractLock模板锁里面实现getLock方法,实现通用的逻辑。

3、不能确实的步骤,作为虚拟方法,甩锅给子类实现。

4、子类只需要聚焦自己的小步骤逻辑,实现tryLock,waitLock,unLock方法

2.3.2. 代码实现

干货详解:一文带你了解分布式场景下的并发安全问题

实现tryLock,waitLock,与Lock接口的unLock方法

2.4. MySql实现方式

2.4.1. 实现思路

利用数据库自身提供的锁机制实现,要求数据库支持行级锁;

干货详解:一文带你了解分布式场景下的并发安全问题

2.4.2. 实现流程

干货详解:一文带你了解分布式场景下的并发安全问题

2.4.3. 代码

2.4.3.1. Mysql分布式锁的实现

干货详解:一文带你了解分布式场景下的并发安全问题

2.4.3.2. 修改Controller

增加分布式锁

干货详解:一文带你了解分布式场景下的并发安全问题

2.4.4. 测试

搞定分布式安全问题

干货详解:一文带你了解分布式场景下的并发安全问题

2.5. ZK实现方式

2.5.1. 实现思路

基于zk的节点特性以及watch机制实现;

2.5.2. 实现流程

干货详解:一文带你了解分布式场景下的并发安全问题

2.5.3. 代码

干货详解:一文带你了解分布式场景下的并发安全问题

2.5.3.1. tryLock

干货详解:一文带你了解分布式场景下的并发安全问题

尝试创建 /lock 节点,如果创建成功获得锁

2.5.3.2. unLock

干货详解:一文带你了解分布式场景下的并发安全问题

操作完毕后释放锁

2.5.3.3. waitLock

干货详解:一文带你了解分布式场景下的并发安全问题

使用countdownLatch 当/lock节点被删除再发送通知。



分享到:


相關文章: