乾貨詳解:一文帶你瞭解分佈式場景下的併發安全問題

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節點被刪除再發送通知。



分享到:


相關文章: