91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用django_cache怎么實現分布式鎖

發布時間:2021-06-04 18:01:01 來源:億速云 閱讀:445 作者:Leah 欄目:開發技術

這篇文章給大家介紹使用django_cache怎么實現分布式鎖,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

第一種鎖命令INCR

這種加鎖的思路是, key 不存在,那么 key 的值會先被初始化為 0 ,然后再執行 INCR 操作進行加一。 然后其它用戶在執行 INCR 操作進行加一時,如果返回的數大于 1 ,說明這個鎖正在被使用當中。

第二種鎖命令SETNX

這種加鎖的思路是,如果 key 不存在,將 key 設置為 value 如果 key 已存在,則 SETNX 不做任何動作

第三種鎖命令SET

上面兩種方法都有一個問題,會發現,都需要設置 key 過期。那么為什么要設置key過期呢?如果請求執行因為某些原因意外退出了,導致創建了鎖但是沒有刪除鎖,那么這個鎖將一直存在,以至于以后緩存再也得不到更新。于是乎我們需要給鎖加一個過期時間以防不測。

在實際編寫中,我綜合了第二種和第三種方式,即用鍵名來設置鎖,同時設置了過期時間,以防長時間占用。

另外,關于如何使用django-cache去使用數據庫緩存,相關的API整理如下:

from django.core.cache import caches
# 設置鎖和超時時間
cache.set('my_key', 'Initial value', 60)
# 獲取鎖
cache.get('my_key')
# 更新鎖
cache.add('add_key', 'New value')

代碼編寫

在經過多次的迭代,并且對比了網上的各路寫法后,我結合django-cache的特性,最終總結了一套較為簡潔的寫法。

首先是一個CacheLock的類,初始化方法里可以傳執行超時時間,和拿鎖等待的時間。CacheLock類的主要方法有兩個,一個是拿鎖的方法,一個是釋放鎖的方法。

拿鎖的方法中,鍵名根據操作的具體對象來定,鍵值為uuid值,超時時間默認為60s。一旦發現能拿到鎖,則返回uuid值。

釋放鎖的方法中,首先比較鍵值和uuid值是否一致,一致則釋放,避免因超時情況導致把其他的正在操作的鎖給釋放掉。

class CacheLock(object):
 def __init__(self, expires=60, wait_timeout=0):
 self.cache = cache
 self.expires = expires # 函數執行超時時間
 self.wait_timeout = wait_timeout # 拿鎖等待超時時間

 def get_lock(self, lock_key):
 # 獲取cache鎖
 wait_timeout = self.wait_timeout
 identifier = uuid.uuid4()
 while wait_timeout >= 0:
  if self.cache.add(lock_key, identifier, self.expires):
  return identifier
  wait_timeout -= 1
  time.sleep(1)
 raise LockTimeout({'msg': '當前有其他用戶正在編輯該采集配置,請稍后重試'})

 def release_lock(self, lock_key, identifier):
 # 釋放cache鎖
 lock_value = self.cache.get(lock_key)
 if lock_value == identifier:
  self.cache.delete(lock_key)

另外,將緩存鎖寫成一個裝飾器,對需要加鎖的地方,添加上該裝飾器,則可以很輕松地實現鎖功能。

def lock(cache_lock):
 def my_decorator(func):
 def wrapper(*args, **kwargs):
  lock_key = 'bk_monitor:lock:xxx' # 具體的lock_key要根據調用時傳的參數而定
  identifier = cache_lock.get_lock(lock_key)
  try:
  return func(*args, **kwargs)
  finally:
  cache_lock.release_lock(lock_key, identifier)
 return wrapper
 return my_decorator

再舉一個實際調用中的例子:

@lock(CacheLock())
def f():
 pass

關于使用django_cache怎么實現分布式鎖就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大同县| 正阳县| 林周县| 贵定县| 柳州市| 望都县| 井研县| 龙江县| 内江市| 和政县| 旺苍县| 屏南县| 循化| 当阳市| 宁蒗| 雅安市| 金平| 温宿县| 大同县| 海盐县| 平果县| 锦屏县| 黔西| 澄城县| 呼图壁县| 日土县| 南江县| 长汀县| 涡阳县| 金寨县| 电白县| 临沭县| 比如县| 阳西县| 府谷县| 松滋市| 平原县| 泰宁县| 北宁市| 革吉县| 沙河市|