欧美一区2区三区4区公司二百,国产精品婷婷午夜在线观看,自拍偷拍亚洲精品,国产美女诱惑一区二区

歡迎來到云服務器

交換存儲

分布式鎖的多種實現方式

目前幾乎很多大型網站及應用都是分布式部署的,分布式場景中的數據一致性問題一直是一個比較重要的話題。分布式的CAP理論告訴我們“任何一個分布式系統都無法同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance),最多只能同時滿足兩項。”所以,很多系統在設計之初就要對這三者做出取舍。在互聯網領域的絕大多數的場景中,都需要犧牲強一致性來換取系統的高可用性,系統往往只需要保證“最終一致性”,只要這個最終時間是在用戶可以接受的范圍內即可。

在很多場景中,我們為了保證數據的最終一致性,需要很多的技術方案來支持,比如分布式事務、分布式鎖等。有的時候,我們需要保證一個方法在同一時間內只能被同一個線程執行。在單機環境中,Java中其實提供了很多并發處理相關的API,但是這些API在分布式場景中就無能為力了。也就是說單純的Java Api并不能提供分布式鎖的能力。所以針對分布式鎖的實現目前有多種方案

針對分布式鎖的實現,目前比較常用的有以下幾種方案:基于數據庫實現分布式鎖基于緩存實現分布式鎖基于Zookeeper實現分布式鎖在分析這幾種實現方案之前我們先來想一下,我們需要的分布式鎖應該是怎么樣的?(這里以方法鎖為例,資源鎖同理)

可以保證在分布式部署的應用集群中,同一個方法在同一時間只能被一臺機器上的一個線程執行。

這把鎖要是一把可重入鎖(避免死鎖)

這把鎖最好是一把阻塞鎖(根據業務需求考慮要不要這條)

有高可用的獲取鎖和釋放鎖功能獲取鎖和釋放鎖的性能要好基于數據庫實現分布式鎖基于數據庫表要實現分布式鎖,最簡單的方式可能就是直接創建一張鎖表,然后通過操作該表中的數據來實現了。

當我們要鎖住某個方法或資源時,我們就在該表中增加一條記錄,想要釋放鎖的時候就刪除這條記錄。

創建這樣一張數據庫表:CREATE TABLE `methodLock` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '鎖定的方法名',`desc` varchar(1024) NOT NULL DEFAULT '備注信息',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存數據時間,自動生成',PRIMARY KEY (`id`),UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='鎖定中的方法';當我們想要鎖住某個方法時,執行以下SQL:insert into methodLock(method_name,desc) values (‘method_name’,‘desc’)

因為我們對method_name做了唯一性約束,這里如果有多個請求同時提交到數據庫的話,數據庫會保證只有一個操作可以成功,那么我們就可以認為操作成功的那個線程獲得了該方法的鎖,可以執行方法體內容。

當方法執行完畢之后,想要釋放鎖的話,需要執行以下Sql:delete from methodLock where method_name ='method_name'上面這種簡單的實現有以下幾個問題:1、這把鎖強依賴數據庫的可用性,數據庫是一個單點,一旦數據庫掛掉,會導致業務系統不可用。

2、這把鎖沒有失效時間,一旦解鎖操作失敗,就會導致鎖記錄一直在數據庫中,其他線程無法再獲得到鎖。

3、這把鎖只能是非阻塞的,因為數據的insert操作,一旦插入失敗就會直接報錯。沒有獲得鎖的線程并不會進入排隊隊列,要想再次獲得鎖就要再次觸發獲得鎖操作。

4、這把鎖是非重入的,同一個線程在沒有釋放鎖之前無法再次獲得該鎖。因為數據中數據已經存在了。

當然,我們也可以有其他方式解決上面的問題。

數據庫是單點?搞兩個數據庫,數據之前雙向同步。一旦掛掉快速切換到備庫上。

沒有失效時間?只要做一個定時任務,每隔一定時間把數據庫中的超時數據清理一遍。

非阻塞的?搞一個while循環,直到insert成功再返回成功。

非重入的?在數據庫表中加個字段,記錄當前獲得鎖的機器的主機信息和線程信息,那么下次再獲取鎖的時候先查詢數據庫,如果當前機器的主機信息和線程信息在數據庫可以查到的話,直接把鎖分配給他就可以了。

基于數據庫排他鎖除了可以通過增刪操作數據表中的記錄以外,其實還可以借助數據中自帶的鎖來實現分布式的鎖。

我們還用剛剛創建的那張數據庫表。可以通過數據庫的排他鎖來實現分布式鎖。 基于MySql的InnoDB引擎,可以使用以下方法來實現加鎖操作:public boolean lock(){ connection.setAutoCommit(false)

while(true){ try{ result = select * from methodLock where method_name=xxx for update;if(result==null){ return true;} }catch(Exception e){

騰訊云代理

Copyright © 2003-2021 MFISP.COM. 國外vps服務器租用 夢飛云服務器租用 版權所有 ? 粵ICP備11019662號

主站蜘蛛池模板: 奉新县| 东至县| 科尔| 台江县| 湾仔区| 二连浩特市| 平阴县| 济南市| 滦南县| 襄樊市| 渭源县| 桂东县| 芷江| 神农架林区| 绥阳县| 白沙| 磐石市| 丽江市| 富阳市| 仙居县| 临潭县| 台州市| 华容县| 元阳县| 江达县| 延川县| 洱源县| 临沧市| 彭州市| 濉溪县| 广平县| 开原市| 嘉义县| 金堂县| 舒城县| 丹棱县| 额尔古纳市| 辽宁省| 奉节县| 常熟市| 澄江县|