RedLock.Net - 基於Redis分布式鎖的開源實現

來源:互聯網
上載者:User

標籤:操作   res   執行   creat   manager   public   oop   start   logs   

 工作中,經常會遇到分布式環境中資源存取違規問題,比如商城的庫存數量處理,或者某個事件的原子性操作,都需要確保某個時間段內只有一個線程在訪問或處理資源。

因此現在網上也有很多的分布式鎖的解決方案,有資料庫、MemCache、ZoopKeeper等等的方式。

 這次,我們要學習的是一個基於Redis分布式鎖的外掛程式,RedLock.Net。

 

首先必須要有一個Redis服務來支援此分布式鎖,其次就當然是要擷取此外掛程式了。

可以從Nuget中擷取,也可以直接去Github下載   https://github.com/samcook/RedLock.net。

 

 擷取到外掛程式,話不多說上代碼。這個是分布式鎖的封裝類,在需要使用鎖的地方直接調用即可。

using RedLock;using System;using System.Collections.Generic;using System.Linq;using System.Net;namespace KingsBlog.Core{    public class DistributedLockManager    {        private List<RedisLockEndPoint> azureEndPoint;        public DistributedLockManager()        {            azureEndPoint = new List<RedisLockEndPoint>();            azureEndPoint.AddRange(GetEndPoint().Select(o => new RedisLockEndPoint { EndPoint = o.Item1, Password = o.Item2 }));        }        /// <summary>        /// 從設定檔擷取Redis串連        /// </summary>        /// <returns></returns>        private List<Tuple<EndPoint, string>> GetEndPoint()        {            List<Tuple<EndPoint, string>> result = new List<Tuple<EndPoint, string>>();            var redisParms = RedisCacheBase.ConnectionString.Split(‘;‘);            // "127.0.0.1:6379,password=ucs123;127.0.0.1:6378,password=ucs123;"            foreach (var re in redisParms)            {                var re1 = re.Split(‘,‘);                var re2 = re1[0].Split(‘:‘);                var re3 = re1[0].Split(‘=‘);                result.Add(new Tuple<EndPoint, string>(new DnsEndPoint(re2[0], Convert.ToInt16(re2.Length > 1 ? re2[1] : "6379")), re3[1]));            }            return result;        }        /// <summary>        /// 阻塞式調用,事情最終會被調用(等待時間內)        /// </summary>        /// <param name="resource">鎖定資源的標識</param>        /// <param name="expiryTime">鎖到期時間</param>        /// <param name="waitTime">等待時間</param>        /// <param name="work"></param>        public bool BlockingWork(string resource, TimeSpan expiryTime, TimeSpan waitTime, Action work)        {            resource = CreateKey(resource);            using (var redisLockFactory = new RedisLockFactory(azureEndPoint))            {                // blocks until acquired or ‘wait‘ timeout                using (var redisLock = redisLockFactory.Create(resource, expiryTime, waitTime, TimeSpan.FromSeconds(1)))                {                    if (redisLock.IsAcquired)                    {                        work();                        return true;                    }                }                return false;            }        }        /// <summary>        /// 跳過式調用,如果事情正在被調用,直接跳過        /// </summary>        /// <param name="resource">鎖定資源的標識</param>        /// <param name="expiryTime">鎖到期時間</param>        /// <param name="work"></param>        public bool OverlappingWork(string resource, TimeSpan expiryTime, Action work)        {            resource = CreateKey(resource);            using (var redisLockFactory = new RedisLockFactory(azureEndPoint))            {                using (var redisLock = redisLockFactory.Create(resource, expiryTime))                {                    if (redisLock.IsAcquired)                    {                        work();                        return true;                    }                }                return false;            }        }        /// <summary>        /// 重新設定鍵        /// </summary>        /// <param name="key"></param>        /// <returns></returns>        private string CreateKey(string key)        {            return string.Join("_", RedisCacheBase.SystemCode, "LOCK", key);        }    }}
View Code

調用樣本,簡單粗暴

                DistributedLockManager lockManager=new DistributedLockManager();                TimeSpan expiryTime = new TimeSpan(0,3,0);                bool isWork=lockManager.OverlappingWork("LockName",expiryTime,()=>{                    work(); //Do your job                });                if(isWork)                {                    //成功執行                }                else                {                    //未執行                }
View Code

這樣就十分簡單地實現了基於Redis的分布式鎖。

 

 

代碼很簡單,有興趣的朋友也可以利用反編譯軟體ILSpy去瞭解RedLock的實現原理,以下兩個其實就是RedLock的部分源碼:

 

其它就不多說了,如有疑問,歡迎提出。

 

RedLock.Net - 基於Redis分布式鎖的開源實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.