最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ZooKeeper 實(shí)現(xiàn)分布式鎖的方法示例

 更新時(shí)間:2019年06月17日 09:05:09   作者:Beck''s Blog  
這篇文章主要介紹了ZooKeeper 實(shí)現(xiàn)分布式鎖的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

ZooKeeper 是一個(gè)典型的分布式數(shù)據(jù)一致性解決方案,分布式應(yīng)用程序可以基于 ZooKeeper 實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖等功能。

節(jié)點(diǎn)

在介紹 ZooKeeper 分布式鎖前需要先了解一下 ZooKeeper 中節(jié)點(diǎn)(Znode),ZooKeeper 的數(shù)據(jù)存儲(chǔ)數(shù)據(jù)模型是一棵樹(Znode Tree),由斜杠(/)的進(jìn)行分割的路徑,就是一個(gè) Znode(如 /locks/my_lock)。每個(gè) Znode 上都會(huì)保存自己的數(shù)據(jù)內(nèi)容,同時(shí)還會(huì)保存一系列屬性信息。

Znode 又分為以下四種類型:

類型 描述
持久節(jié)點(diǎn) 節(jié)點(diǎn)創(chuàng)建后,會(huì)一直存在,不會(huì)因客戶端會(huì)話失效而刪除
持久順序節(jié)點(diǎn) 基本特性與持久節(jié)點(diǎn)一致,創(chuàng)建節(jié)點(diǎn)的過(guò)程中,ZooKeeper 會(huì)在其名字后自動(dòng)追加一個(gè)單調(diào)增長(zhǎng)的數(shù)字后綴,作為新的節(jié)點(diǎn)名
臨時(shí)節(jié)點(diǎn) 客戶端會(huì)話失效或連接關(guān)閉后,該節(jié)點(diǎn)會(huì)被自動(dòng)刪除
臨時(shí)順序節(jié)點(diǎn) 基本特性與臨時(shí)節(jié)點(diǎn)一致,創(chuàng)建節(jié)點(diǎn)的過(guò)程中,ZooKeeper 會(huì)在其名字后自動(dòng)追加一個(gè)單調(diào)增長(zhǎng)的數(shù)字后綴,作為新的節(jié)點(diǎn)名

鎖原理

ZooKeeper 分布式鎖是基于 臨時(shí)順序節(jié)點(diǎn) 來(lái)實(shí)現(xiàn)的,鎖可理解為 ZooKeeper 上的一個(gè)節(jié)點(diǎn),當(dāng)需要獲取鎖時(shí),就在這個(gè)鎖節(jié)點(diǎn)下創(chuàng)建一個(gè)臨時(shí)順序節(jié)點(diǎn)。當(dāng)存在多個(gè)客戶端同時(shí)來(lái)獲取鎖,就按順序依次創(chuàng)建多個(gè)臨時(shí)順序節(jié)點(diǎn),但只有排列序號(hào)是第一的那個(gè)節(jié)點(diǎn)能獲取鎖成功,其他節(jié)點(diǎn)則按順序分別監(jiān)聽(tīng)前一個(gè)節(jié)點(diǎn)的變化,當(dāng)被監(jiān)聽(tīng)者釋放鎖時(shí),監(jiān)聽(tīng)者就可以馬上獲得鎖。

而且用臨時(shí)順序節(jié)點(diǎn)的另外一個(gè)用意是如果某個(gè)客戶端創(chuàng)建臨時(shí)順序節(jié)點(diǎn)后,自己意外宕機(jī)了也沒(méi)關(guān)系,ZooKeeper 感知到某個(gè)客戶端宕機(jī)后會(huì)自動(dòng)刪除對(duì)應(yīng)的臨時(shí)順序節(jié)點(diǎn),相當(dāng)于自動(dòng)釋放鎖。

如上圖:ClientA 和 ClientB 同時(shí)想獲取鎖,所以都在 locks 節(jié)點(diǎn)下創(chuàng)建了一個(gè)臨時(shí)節(jié)點(diǎn) 1 和 2,而 1 是當(dāng)前 locks 節(jié)點(diǎn)下排列序號(hào)第一的節(jié)點(diǎn),所以 ClientA 獲取鎖成功,而 ClientB 處于等待狀態(tài),這時(shí) ZooKeeper 中的 2 節(jié)點(diǎn)會(huì)監(jiān)聽(tīng) 1 節(jié)點(diǎn),當(dāng) 1節(jié)點(diǎn)鎖釋放(節(jié)點(diǎn)被刪除)時(shí),2 就變成了 locks 節(jié)點(diǎn)下排列序號(hào)第一的節(jié)點(diǎn),這樣 ClientB 就獲取鎖成功了。

代碼測(cè)試

請(qǐng)確保 ZooKeeper 服務(wù)已啟動(dòng),ZooKeeper 的搭建可參考Kafka 集群 中的 ZooKeeper 集群部分

以下是基于 C# 的測(cè)試,Java 可使用 Curator 框架,實(shí)現(xiàn)原理和上面描述是一致的,有興趣可以看看源碼,應(yīng)該也不難理解。

創(chuàng)建 .NET Core 控制臺(tái)程序 Nuget

安裝 ZooKeeperNetEx.Recipes

創(chuàng)建 ZooKeeper Client

private const int CONNECTION_TIMEOUT = 50000;
private const string CONNECTION_STRING = "127.0.0.1:2181";
private ZooKeeper CreateClient()
{
	var zooKeeper = new ZooKeeper(CONNECTION_STRING, CONNECTION_TIMEOUT, NullWatcher.Instance);
	Stopwatch sw = new Stopwatch();
	sw.Start();
	while (sw.ElapsedMilliseconds < CONNECTION_TIMEOUT)
	{
		var state = zooKeeper.getState();
		if (state == ZooKeeper.States.CONNECTED || state == ZooKeeper.States.CONNECTING)
		{
			break;
		}
	}
	sw.Stop();
	return zooKeeper;
}

class NullWatcher : Watcher
  {
    public static readonly NullWatcher Instance = new NullWatcher();
    private NullWatcher() { }
    public override Task process(WatchedEvent @event)
    {
      return Task.CompletedTask;
    }
  }

添加 Lock 方法

/// <summary>
/// 加鎖
/// </summary>
/// <param name="key">加鎖的節(jié)點(diǎn)名</param>
/// <param name="lockAcquiredAction">加鎖成功后需要執(zhí)行的邏輯</param>
/// <param name="lockReleasedAction">鎖釋放后需要執(zhí)行的邏輯,可為空</param>
/// <returns></returns>
public async Task Lock(string key, Action lockAcquiredAction, Action lockReleasedAction = null)
{
	// 獲取 ZooKeeper Client
	ZooKeeper keeper = CreateClient();
	// 指定鎖節(jié)點(diǎn)
	WriteLock writeLock = new WriteLock(keeper, $"/{key}", null);

	var lockCallback = new LockCallback(() =>
	{
		lockAcquiredAction.Invoke();
		writeLock.unlock();
	}, lockReleasedAction);
	// 綁定鎖獲取和釋放的監(jiān)聽(tīng)對(duì)象
	writeLock.setLockListener(lockCallback);
	// 獲取鎖(獲取失敗時(shí)會(huì)監(jiān)聽(tīng)上一個(gè)臨時(shí)節(jié)點(diǎn))
	await writeLock.Lock();
}

class LockCallback : LockListener
{
	private readonly Action _lockAcquiredAction;
	private readonly Action _lockReleasedAction;

	public LockCallback(Action lockAcquiredAction, Action lockReleasedAction)
	{
		_lockAcquiredAction = lockAcquiredAction;
		_lockReleasedAction = lockReleasedAction;
	}

	/// <summary>
	/// 獲取鎖成功回調(diào)
	/// </summary>
	/// <returns></returns>
	public Task lockAcquired()
	{
		_lockAcquiredAction?.Invoke();
		return Task.FromResult(0);
	}

	/// <summary>
	/// 釋放鎖成功回調(diào)
	/// </summary>
	/// <returns></returns>
	public Task lockReleased()
	{
		_lockReleasedAction?.Invoke();
		return Task.FromResult(0);
	}
}

多線程模擬測(cè)試

static async Task RunAsync()
{
	Parallel.For(1, 10, async (i) =>
	{
		await new ZooKeeprDistributedLock().Lock("locks", () =>
		{
			Console.WriteLine($"第{i}個(gè)請(qǐng)求,獲取鎖成功:{DateTime.Now},線程Id:{Thread.CurrentThread.ManagedThreadId}");
			Thread.Sleep(1000); // 業(yè)務(wù)邏輯...
		}, () =>
		{
			Console.WriteLine($"第{i}個(gè)請(qǐng)求,釋放鎖成功:{DateTime.Now},線程Id:{Thread.CurrentThread.ManagedThreadId}");
			Console.WriteLine("-------------------------------");
		});
	});
	await Task.CompletedTask;
}

雖然模擬的是多線程并行執(zhí)行,但最終都會(huì)依賴鎖的獲取和釋放而串行執(zhí)行實(shí)際業(yè)務(wù)邏輯。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#中BitmapImage與BitmapSource接口的區(qū)別對(duì)比小結(jié)

    C#中BitmapImage與BitmapSource接口的區(qū)別對(duì)比小結(jié)

    BitmapImage和BitmapSource都可以用于表示和顯示圖像,本文就來(lái)介紹一下C#中BitmapImage與BitmapSource接口的區(qū)別對(duì)比,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • DevExpress實(shí)現(xiàn)GridControl根據(jù)列選中一行

    DevExpress實(shí)現(xiàn)GridControl根據(jù)列選中一行

    這篇文章主要介紹了DevExpress實(shí)現(xiàn)GridControl根據(jù)列選中一行,比較實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • C#多線程系列之進(jìn)程同步Mutex類

    C#多線程系列之進(jìn)程同步Mutex類

    本文詳細(xì)講解了C#多線程中的進(jìn)程同步Mutex類,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • C# 爬蟲簡(jiǎn)單教程

    C# 爬蟲簡(jiǎn)單教程

    這篇文章主要介紹了C# 爬蟲的簡(jiǎn)單教程,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-12-12
  • 淺談C# 抽象類與開(kāi)閉原則

    淺談C# 抽象類與開(kāi)閉原則

    這篇文章主要介紹了C# 抽象類與開(kāi)閉原則的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • C#中Hashtable和Dictionary的區(qū)別與用法示例

    C#中Hashtable和Dictionary的區(qū)別與用法示例

    由于 Hashtable 和 Dictionary 同時(shí)存在, 在使用場(chǎng)景上必然存在選擇性, 并不任何時(shí)刻都能相互替代。所以這篇文章主要給大家介紹了關(guān)于C#中Hashtable和Dictionary區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • jQuery結(jié)合C#實(shí)現(xiàn)上傳文件的方法

    jQuery結(jié)合C#實(shí)現(xiàn)上傳文件的方法

    這篇文章主要介紹了jQuery結(jié)合C#實(shí)現(xiàn)上傳文件的方法,涉及C#文件上傳的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04
  • C#實(shí)現(xiàn)異步操作的幾種方式

    C#實(shí)現(xiàn)異步操作的幾種方式

    在C#中,異步操作可以提高程序的性能和響應(yīng)能力,本文主要介紹了C#實(shí)現(xiàn)異步操作的幾種方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C#基于Miniblink控件編寫一個(gè)簡(jiǎn)易的瀏覽器

    C#基于Miniblink控件編寫一個(gè)簡(jiǎn)易的瀏覽器

    miniblink是一款精簡(jiǎn)小巧的瀏覽器控件,基于chromium精簡(jiǎn)而成,是市面上最小巧的chromium內(nèi)核控件沒(méi)有之一,本文將結(jié)合C#和Miniblink編寫一個(gè)簡(jiǎn)易的瀏覽器,感興趣的可以了解下
    2024-01-01
  • C#實(shí)現(xiàn)讀寫ini文件類實(shí)例

    C#實(shí)現(xiàn)讀寫ini文件類實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)讀寫ini文件類,實(shí)例分析了C#實(shí)現(xiàn)針對(duì)ini文件的讀、寫、刪除等操作的常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03

最新評(píng)論

句容市| 左权县| 永平县| 平果县| 渝北区| 林甸县| 安顺市| 鲁甸县| 道真| 镇平县| 德江县| 温宿县| 孝昌县| 额济纳旗| 柯坪县| 康保县| 洞头县| 沈阳市| 绥芬河市| 英山县| 抚远县| 镇赉县| 南宫市| 青田县| 霍州市| 崇礼县| 永宁县| 嘉黎县| 泸水县| 沂水县| 北辰区| 广安市| 赤壁市| 东乌珠穆沁旗| 保亭| 大关县| 蚌埠市| 巩留县| 雷山县| 许昌市| 静宁县|