熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

【C#|.NET】分布式鎖服務

2022-06-13   來源: .NET編程 





  

  背  景

  分布式鎖服務在大家的項目中或許用的不多因為大家都把排他放在數據庫那一層來擋當大量的行鎖表鎖事務充斥著數據庫的時候不如換個角度思考問題一般web應用很多的瓶頸都在數據庫上這裡給大家介紹的是減輕數據庫鎖負擔的一種方案


  簡  介

  如果我們的需求很簡單例如對於用戶的賬戶資金要保證原子性操作並且不同的客戶端在同一時間內只能提交一個對象操作lock單例?!在單台上還可以但是大型web項目上負載均衡是常用的技術手段手段同一意義的對象可能存在不同的副本這時我們又如何保證排他操作數據庫的事務!除了這個接下來我們引出本章的主題分布式鎖服務

  一個簡單的鎖服務實現起來並不難甚至利用memcache很快就能構造一套分布式鎖系統我們只需要在操作對象時寫入kv鍵值對操作完畢時釋放kv在讀取對象時判斷kv中是否有數據就可以了我們甚至還可以給它一個默認的釋放時間

  這是一種解決方案但是如果我們的要求更高一點我們需要權限認證(例如只能來自xxx域名的請求)需要上下級節點關聯(例如一個用戶的資金賬戶被鎖住同時鎖住他的購物車積分等)需要監視器回調甚至需要考慮單點故障問題那麼蟲子在這裡推薦另一套方案zookeeper

  

  Zookeeper是Hadoop中的一個模塊是一個分布式的開源的分布式應用程序協調服務用它可以來現同步服務配置維護

  更多的內容大家看文檔吧或者直接網上搜一下理論性的內容寫多了讓人困我們直接看實踐


  性能篇

  服務器ubuntu (虛擬機一台)

  客戶端window

  服務端安裝好java環境 然後跟著官方的介紹部署

  

  啟動zkserver

  我們測試下鎖服務相關的操作

  

  ps試下本機的windows  因為是本地環境 不於上面做對比 僅看看zookeeper本身的數據處理效率

  

  


  功能篇

  一張圖就可以介紹完普通功能

  

  再看下watcher

  


    public class MyWatch : IWatcher  
        {  
            public void Process(WatchedEvent qevent)  
            {  
                ConsoleWriteLine(this is MyWatch);  
            }       
        }  
    public class MyWatch : IWatcher  
        {  
            public void Process(WatchedEvent qevent)  
            {  
                ConsoleWriteLine(this is MyWatch);  
            }     
        } 

  創建連接時 new ZooKeeper(: new TimeSpan( ) new MyWatch());

  檢查是否存在時zkExists(Dir new MyWatch());

  獲取數據時zkGetData(Dir new MyWatch() stat);

  我們再運行一遍之前的demo  去掉delete操作

  

  加上delete操作

  


  淺  析

  創建連接


    獲取服務主機列表
    設置超時時間
    注冊客戶端事件
    以線程安全的方式創建請求連接(啟動客戶端請求隊列循環隊列基於socket通信根據請求類型執行不同的請求動作)

  請求流程

  構造請求頭構造requestreponse構造響應頭構造Packet對象packet對象准備好後把整個對象放入一個outgoingQueue
packet被放入outgoingQueue中等待SendThread把packet對應的內容發送給serverserver處理分步在 doio方法中ReadLength ReadConnectResult ReadResponse直到ReadResponse方法中確定packet請求結束

  響應流程

  針對心跳的ping請求的resp針對auth請求的resp一般接口請求的resp如果接口請求要求了watcher當watcher關注的內容有變化時的notification

  鎖相關部分API方法

  創建節點create

  demozkCreate(Dir severnameGetBytes() IdsOPEN_ACL_UNSAFE CreateModePersistent);

  其中CreateMode分為類PersistentPersistentSequentialEphemeralEphemeralSequential

  PERSISTENT 創建持久化節點對應機器關閉連接後節點/數據不會消失

  PERSISTENT_SEQUENTIAL 如果PATH是以/結尾則以這個PATH作為父節點創建一個子節點其子節點名字是一個按先後順序排列的數值否則創建一個名字是/後面字符加上先後順序排列的數值字符串的節點同樣創建持久節點

  EPHEMERAL 創建瞬時節點Zookeeper在感知連接機器宕機後會清除它創建的瞬時節點

  EPHEMERAL_SEQUENTIAL 穿件瞬時順序節點和PERSISTENT_SEQUENTIAL一樣區別在於它是瞬時的

  刪除節點 delete

  demo zkDelete(Dir );

  前一個參數代表節點名稱(一般用作路徑)後一個是版本號 表示全匹配

  查看節點 exists

  demo zkExists(Dir new MyWatch());

  獲取數據 getData 

  demo zkGetData(Dir new MyWatch() stat);

  獲取一個節點的數據可注入watcher 

  設置數據 setData 

  demo  zkSetData(Dir new byte[] );

  獲取下級節點集合 GetChildren

  demo zkGetChildren(Dir true);

  存  儲

  znodes類似文件和目錄但它不是一個典型的文件系統zookeeper數據保存在內存中這意味著zookeeper可以實現高吞吐量和低延遲

  watcher

  Zookeeper有兩種watches一種是data watches另一種是child watches其中getData()和exists()以及create()等會添加data watchesgetChildren()會添加child watches而delete()涉及到刪除數據和子節點會同時觸發data watches和child watches


From:http://tw.wingwit.com/Article/program/net/201311/12811.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.