當前位置:首頁 » 編程軟體 » 腳本重入

腳本重入

發布時間: 2023-05-28 01:17:20

A. 大廠面試題詳解:如何用Redis實現分布式鎖

說一道常見面試題:

一個很簡單的答案就是去使用 Redission 客戶端。Redission 中的鎖方案就是 Redis 分布式鎖得比較完美的詳細方案。

那麼,Redission 中的鎖方案為什麼會比較完美呢?

正好,我用 Redis 做分布式鎖經驗十分豐富,在實際工作中,也 探索 過許多種使用 Redis 做分布式鎖的方案,經過了無數血淚教訓。

所以,在談及 Redission 鎖為什麼比較完美之前,先給大家看看我曾經使用 Redis 做分布式鎖是遇到過的問題。

我曾經用 Redis 做分布式鎖是想去解決一個用戶搶優惠券的問題。這個業務需求是這樣的:當用戶領完一張優惠券後,優惠券的數量必須相應減一,如果優惠券搶光了,就不允許用戶再搶了。

在實現時,先從資料庫中先讀出優惠券的數量進行判斷,當優惠券大於 0,就進行允許領取優惠券,然後,再將優惠券數量減一後,寫回資料庫。

當時由於請求數量比較多,所以,我們使用了三台伺服器去做分流。

這個時候會出現一個問題:

如果其中一台伺服器上的 A 應用獲取到了優惠券的數量之後,由於處理相關業務邏輯,未及時更新資料庫的優惠券數量;在 A 應用處理業務邏輯的時候,另一台伺服器上的 B 應用更新了優惠券數量。那麼,等 A 應用去更新資料庫中優惠券數量時,就會把 B 應用更新的優惠券數量覆蓋掉。

看到這里,可能有人比較奇怪,為什麼這里不直接使用 SQL:

原因是這樣做,在沒有分布式鎖的協調下,優惠券數量可能直接會出現負數。因為當前優惠券數量為 1 的時候,如果兩個用戶通過兩台伺服器同時發起搶優惠券的請求,都滿足優惠券大於 0 每個條件,然後都執行這條 SQL 說了句,結果優惠券數量直接變成 -1 了。

還有人說可以用樂觀鎖,比如使用如下 SQL:

這種方式就在一定幾率下,很可能出現數據一直更新不上,導致長時間重試的情況。

所以,經過綜合考慮,我們就採用了 Redis 分布式鎖,通過互斥的方式,以防止多個客戶端同時更新優惠券數量的方案。

當時,我們首先想到的就是使用 Redis 的 setnx 命令,setnx 命令其實就是 set if not exists 的簡寫。告則

當 key 設置值成功後,則返回 1,否則就返回 0。所以,這里 setnx 設置成功可以表示成獲取到鎖,如果失敗,則說明已經有鎖,可以被視作獲取鎖失敗。

如果想要釋放鎖,執行任務 del 指令,把 key 刪除即可。

利用這個特性,我們就可以讓系統在返毀執行優惠券邏輯之前,先去 Redis 中執行 setnx 指令。再根漏友備據指令執行結果,去判斷是否獲取到鎖。如果獲取到了,就繼續執行業務,執行完再使用 del 指令去釋放鎖。如果沒有獲取到,就等待一定時間,重新再去獲取鎖。

乍一看,這一切沒什麼問題,使用 setnx 指令確實起到了想要的互斥效果。

但是,這是建立在所有運行環境都是正常的情況下的。一旦運行環境出現了異常,問題就出現了。

想一下,持有鎖的應用突然崩潰了,或者所在的伺服器宕機了,會出現什麼情況?

這會造成死鎖——持有鎖的應用無法釋放鎖,其他應用根本也沒有機會再去獲取鎖了。這會造成巨大的線上事故,我們要改進方案,解決這個問題。

怎麼解決呢?咱們可以看到,造成死鎖的根源是,一旦持有鎖的應用出現問題,就不會去釋放鎖。從這個方向思考,可以在 Redis 上給 key 一個過期時間。

這樣的話,即使出現問題,key 也會在一段時間後釋放,是不是就解決了這個問題呢?實際上,大家也確實是這么做的。

不過,由於 setnx 這個指令本身無法設置超時時間,所以一般會採用兩種辦法來做這件事:

1、採用 lua 腳本,在使用 setnx 指令之後,再使用 expire 命令去給 key 設置過期時間。

2、直接使用 set(key,value,NX,EX,timeout) 指令,同時設置鎖和超時時間。

以上兩種方法,使用哪種方式都可以。

釋放鎖的腳本兩種方式都一樣,直接調用 Redis 的 del 指令即可。

到目前為止,我們的鎖既起到了互斥效果,又不會因為某些持有鎖的系統出現問題,導致死鎖了。這樣就完美了嗎?

假設有這樣一種情況,如果一個持有鎖的應用,其持有的時間超過了我們設定的超時時間會怎樣呢?會出現兩種情況:

出現第一種情況比較正常。因為你畢竟執行任務超時了,key 被正常清除也是符合邏輯的。

但是最可怕的是第二種情況,發現設置的 key 還存在。這說明什麼?說明當前存在的 key,是另外的應用設置的。

這時候如果持有鎖超時的應用調用 del 指令去刪除鎖時,就會把別人設置的鎖誤刪除,這會直接導致系統業務出現問題。

所以,為了解決這個問題,我們需要繼續對 Redis 腳本進行改動……毀滅吧,累了……

首先,我們要讓應用在獲取鎖的時候,去設置一個只有應用自己知道的獨一無二的值。

通過這個唯一值,系統在釋放鎖的時候,就能識別出這鎖是不是自己設置的。如果是自己設置的,就釋放鎖,也就是刪除 key;如果不是,則什麼都不做。

腳本如下:

或者

這里,ARGV[1] 是一個可傳入的參數變數,可以傳入唯一值。比如一個只有自己知道的 UUID 的值,或者通過雪球演算法,生成只有自己持有的唯一 ID。

釋放鎖的腳本改成這樣:

可以看到,從業務角度,無論如何,我們的分布式鎖已經可以滿足真正的業務需求了。能互斥,不死鎖,不會誤刪除別人的鎖,只有自己上的鎖,自己可以釋放。

一切都是那麼美好!!!

可惜,還有個隱患,我們並未排除。這個隱患就是 Redis 自身。

要知道,lua 腳本都是用在 Redis 的單例上的。一旦 Redis 本身出現了問題,我們的分布式鎖就沒法用了,分布式鎖沒法用,對業務的正常運行會造成重大影響,這是我們無法接受的。

所以,我們需要把 Redis 搞成高可用的。一般來講,解決 Redis 高可用的問題,都是使用主從集群。

但是搞主從集群,又會引入新的問題。主要問題在於,Redis 的主從數據同步有延遲。這種延遲會產生一個邊界條件:當主機上的 Redis 已經被人建好了鎖,但是鎖數據還未同步到從機時,主機宕了。隨後,從機提升為主機,此時從機上是沒有以前主機設置好的鎖數據的——鎖丟了……丟了……了……

到這里,終於可以介紹 Redission(開源 Redis 客戶端)了,我們來看看它怎麼是實現 Redis 分布式鎖的。

Redission 實現分布式鎖的思想很簡單,無論是主從集群還是 Redis Cluster 集群,它會對集群中的每個 Redis,挨個去執行設置 Redis 鎖的腳本,也就是集群中的每個 Redis 都會包含設置好的鎖數據。

我們通過一個例子來介紹一下。

假設 Redis 集群有 5 台機器,同時根據評估,鎖的超時時間設置成 10 秒比較合適。

第 1 步,咱們先算出集群總的等待時間,集群總的等待時間是 5 秒(鎖的超時時間 10 秒 / 2)。

第 2 步,用 5 秒除以 5 台機器數量,結果是 1 秒。這個 1 秒是連接每台 Redis 可接受的等待時間。

第 3 步,依次連接 5 台 Redis,並執行 lua 腳本設置鎖,然後再做判斷:

再額外多說一句,在很多業務邏輯里,其實對鎖的超時時間是沒有需求的。

比如,凌晨批量執行處理的任務,可能需要分布式鎖保證任務不會被重復執行。此時,任務要執行多長時間是不明確的。如果設置分布式鎖的超時時間在這里,並沒有太大意義。但是,不設置超時時間,又會引發死鎖問題。

所以,解決這種問題的通用辦法是,每個持有鎖的客戶端都啟動一個後台線程,通過執行特定的 lua 腳本,去不斷地刷新 Redis 中的 key 超時時間,使得在任務執行完成前,key 不會被清除掉。

腳本如下:

其中,ARGV[1] 是可傳入的參數變數,表示持有鎖的系統的唯一值,也就是只有持有鎖的客戶端才能刷新 key 的超時時間。

到此為止,一個完整的分布式鎖才算實現完畢。總結實現方案如下:

這個分布式鎖滿足如下四個條件:

當然,在 Redission 中的腳本,為了保證鎖的可重入,又對 lua 腳本做了一定的修改,現在把完整的 lua 腳本貼在下面。

獲取鎖的 lua 腳本:

對應的刷新鎖超時時間的腳本:

對應的釋放鎖的腳本:

到現在為止,使用 Redis 作為分布式鎖的詳細方案就寫完了。

我既寫了一步一坑的坎坷經歷,也寫明了各個問題和解決問題的細節,希望大家看完能有所收獲。

最後再給大家提個醒,使用 Redis 集群做分布式鎖,有一定的爭議性,還需要大家在實際用的時候,根據現實情況,做出更好的選擇和取捨。

原文 https://www.cnblogs.com/siyuanwai/p/16011836.html

B. 網頁列印時出來腳本錯誤,求高手幫忙解決~~謝謝

無效過程調用或參數
在過程調用中傳遞了一個無效參數。這可能是由於參數超出范圍,或包含無效數據。另外,有可能在蠢沖不適當的時間對過程進行了調用。
要糾正該錯誤
驗證傳遞給過程的參數是有效的。
驗證在適當的時間調用函數。
溢出
試圖賦給變數的賦值太大,這是因為:
賦值,計算或者數據類型轉換結果很大以至於不能代表此種類型變數值的范圍。
屬性賦值超出了屬性所能接受的最大值。
整數類型數字圓手的計算結果大於一個整數。
要糾正該錯誤
將值賦給一個較大取值范圍的變數類型。
確保賦值符合屬性范圍。
內存不足
分配與該計算機有效內存一樣多的內存。這可能是一個動態分配數組增長得帶腔殲太大,或者是對象實例數目過多。
要糾正該錯誤
使用Erase語句來重新分配動態數組的儲存空間。
使用ReDim語句來重新分配儲存空間。
關閉任何已經打開、不必需的應用程序,文件或者源文件。
下標越界
訪問的數組中元素數目比期望的少。例如試圖從一個定義為10個元素的數組中訪問到11個元素。.
要糾正該錯誤
確保你的代碼中包含檢察元素是否越界的邊界。
重新定義一個更大的數組大小至需要的維數。
該數組為定長的或者臨時被鎖定
試圖用 ReDim 函數來改變一個定長數組的元素數目。動態數組或者 Variant 變數內的數組可以被暫時的鎖定。
要糾正該錯誤
如果在過程內部定義數組,用 ReDim 函數將其從靜態變為動態。
如果在模塊水平上說明數組,不要指定數組中元素的數目。
被零除
創建一個試圖將數字被零除的表達式。被零除得到無窮大(不可用)結果。
要糾正該錯誤
檢查表達式的輸入或大小寫錯誤。
類型不匹配
試圖比較不相容數據類型的值。例如,比較一個字元串和一個數值。
要糾正該錯誤
當進行比較時,要確保數據類型相同。
用一個的數據類型來計算另一個的值,然後重新比較。
字元串空間溢出
試圖創建字元串對象時系統內存被用盡。這可能是因為動態分配數組越來越大或對象實例的數目過大。
要糾正該錯誤
使用 Erase 語句來重新分配動態數組的儲存空間。
使用 ReDim 語句來重新分配儲存空間。
關閉任何已經打開、不必需的應用程序,文件或者源文件
無法執行請求的操作
當主機使腳本引擎中斷時無法繼續執行腳本。主機未指定明確的返回錯誤代碼。
要糾正該錯誤
該錯誤的解決與主機有關。
堆棧溢出
過程嵌套太深。每次代碼從一個過程跳到另一個過程,本地變數的內容被放到堆棧中。堆棧是一個大小隨著要求執行的腳本動態增長和縮小的內存工作區域。
要糾正該錯誤
檢查沒有嵌套很深的過程。
確保遞歸(重入)過程沒有經常的調用自身。
確保遞歸過程被正常終止。
未定義 Sub 或 Function
試圖調用一個不存在的過程。
要糾正該錯誤
檢查過程的拼寫確保輸入正確。
載入 DLL 錯誤
應用程序引用了一個無法找到的DLL,一個DLL可能引用了另一個無法找到的DLL。
要糾正該錯誤
確保DLL存在。
使用全路徑名引用DLL。
獲得被引用的DLL並使其對其他DLL有效。
內部錯誤
發生內部錯誤。
要糾正該錯誤
除非這是由Raise 方法產生,請與微軟產品服務聯系報告出現錯誤消息的情況。
未設置對象變數
試圖使用無效對象的對象屬性。如果遺漏了 Set語句,將在對象引用產生錯誤。
要糾正該錯誤
為對象變數指定一個引用。
For 循環未初始化
在腳本中執行跳到For...Next 循環中間的結果。由於For...Next 循環計數必須被初始化所以產生錯誤。下面演示了一個For...Next 循環的正確結構。
For counter = start To end [Step step] [statements] [Exit For] [statements] Next
要糾正該錯誤
移去跳轉至For...Next 循環的語句。
確保For...Next循環包含了所有必須的部分。
非法使用 Null
試圖獲得一個為Null 的Variant變數的值。你只能獲得包含有效值的Variant 變數的值。Null 是一個 Variant 一個用來指示一個數據項不包含任何有效數據的子類型。
要糾正該錯誤
確保變數包含有效數據。
需要對象
提供的對象無效(或無法認為是一個對象)。對屬性和方法的引用需要一個顯式的對象限定符。
要糾正該錯誤
提供一個對象限定符。
檢查對象限定符的拼寫。
ActiveX 部件無法創建對象
由於對象類未在系統注冊表中注冊或者是一個或多個相關的動態鏈接庫無效(DLLs), VB 5.5運行時無法初始化對象。另外一種可能情況是,由於未找到或是已經損壞,對象所需的DLL不可用。
要糾正該錯誤
確保所有相關的DLLs有效。例如,數據存取對象(DAO)所需的DLLs在不同的平台下是不同的。你可能不得不返回到安裝程序查找該對象。
Internet Explorer可能試圖創建對象,但是在Internet Explorer中沒有正確的安全許可。重置Internet Explorer 安全設置並重試。
類不支持自動化
試圖操作一個並不支持自動化的對象屬性或方法。可以創建並將指針傳遞給不支持自動化的對象,但是不能獲取它的屬性和方法。
要糾正該錯誤
查創建對象應用程序的文檔中關於該類自動化使用的限制。
注意 對象可能已經通過使用CreateObject 被創建,但可能已經通過主機對象模型被引入。
在自動化操作中未找到文件名或類名
使用GetObject 函數,但是將一個不可識別的類或文件名作為參數。GetObject 函數要求包含要獲取的對象的文件的完整的路徑和名稱,或者是在系統中注冊過的類名稱。
要糾正該錯誤
檢查名稱的拼寫錯誤,然後重試。
確保class 參數的名稱與在系統中注冊的相匹配。
對象不支持該屬性或方法
對該自動化對象指定了一個並不存在的屬性或方法。不是所有的對象都支持所有的屬性和方法。
要糾正該錯誤
檢查屬性和方法以確保沒有打字錯誤。
參見對象的文檔獲取更多的信息。
對象不支持此操作
試圖引用該對象不支持的一個方法或屬性。不是所有的對象支持所用的操作。
要糾正該錯誤
檢查屬性和方法以確保沒有打字錯誤。
參見對象的文檔獲取更多的信息。
對象不支持當前的區域設置
試圖操作一個不支持當前區域設置的對象。區域設置是和給定語言以及國家/地區相對應的一系列信息。本地影響預定義程序項的語言和本地特定設置。以下兩種情況時本地信息很重要:
code locale 影響語言項例如關鍵詞,並且定義本地特定設置例如小數和列表分割符,日期格式和字元排列順序。
system locale 影響本地相關的功能執行。例如,當顯示數字或者將字元串轉換為日期時。使用操作系統提供的控制面板工具來設定系統。
要糾正該錯誤
檢查對象支持的區域設置。
未找到命名參數
調用一個過程並指定一個特別的參數,但是過程未被定義為接受以為名稱的參數。除非在過程定義中出現,一個命名參數不能在過程調用中使用。
要糾正該錯誤
檢查參數名稱是否正確拼寫,然後再試著調用過程。
參數不可選
調用過程但是參數數量錯誤。傳遞給過程的參數的數量必須與過程定義的參數數量相同。
要糾正該錯誤
檢查函數符號確保提供了所有必須的參數。
錯誤的參數個數或無效的參數屬性值
調用過程時如果:
錯誤的過程名稱,
或者,
過程中參數數目錯誤,
或者,
參數類型錯誤。
傳遞給過程的參數數目必須與過程定義中的參數數目相符。
要糾正該錯誤
檢查以確保傳遞給過程的參數列表與過程定義或聲明中的相符。
對象不是一個集合
試圖對一個不是 Collection 類型的對象進行只對 Collection 對象有效的操作。有些屬性、方法和操作僅可應用於 Collection 對象。Collection 對象是包含一組互相關聯的對象的一種對象。一旦集合中發生了改變,一個對象在 Collection 對象中的位置也會發生改變;因此,Collection 對象中的任何一個對象的位置都可能變化。
要糾正該錯誤
檢查對象或屬性名稱的拼寫。
驗證對象是一個Collection 對象。
查看用來向集合中添加該對象的 Add 方法,確保語法正確且任何標識符的拼寫都正確。
變數使用了 VB 不支持的自動化類型
試圖使用類型庫或者對象庫中不被支持的數據類型,任何一門編程語言都不能使用類型庫或對象庫中的所有變數。
要糾正該錯誤
只使用VB識別的變數類型。
遠程伺服器不存在或者不能訪問
用CreateObject函數 來建立一個遠程機器的對象,但是調用失敗,這是因為無法訪問遠程伺服器或者沒有包含特定的類。
要糾正該錯誤
檢驗遠程伺服器的名字是否正確。
檢驗遠程伺服器的 DCOM 可用。
使用 dcomcnfg 驗證安全許可權是否允許建立對象。
無效圖片
試圖載入一個無法識別格式的圖像。有效格式包括點陣圖(*.bmp),圖標(*.ico),以及Windows 元文件(*.wmf)。
要糾正該錯誤
確保要載入的圖像文件的格式是有效的。
變數未定義
在腳本開始處用Option Explicit 語句,後來又使用一個未被說明的變數名稱。當使用Option Explicit 語句時,必須用Dim,Private,Public或者ReDim語句顯式地說明所有的變數。
要糾正該錯誤
使用Option Explicit 語句時, 確保用Dim, Private, Public, Or ReDim語句定義了所有的變數。
腳本對象不安全
試圖使用未被標識為腳本安全的對象。對象創建是否安全由主機決定。總的來說,允許不信任腳本進行有害操作(例如操作硬碟)的對象是不安全的。
例如,使用作為客戶端的Microsoft Internet Explorer 運行 FileingObject 是不安全的,但是可以在帶有Windows Host的本地機器使用該對象。
要糾正該錯誤
確保在使用一個安全的對象。
與對象開發者聯系看是否為安全版本。
閱讀對象文檔發現該對象是否安全。
對象不能安全初始化
試圖使用未被標識為初始化安全的對象。對象創建是否安全由主機決定。總的來說,允許不信任腳本進行有害操作(例如操作硬碟)的對象是不安全的。
例如,使用作為客戶端的Microsoft Internet Explorer 運行 FileingObject 是不安全的,但是可以在帶有Windows Host的本地機器使用該對象。
要糾正該錯誤
確保在使用一個安全的對象。
與對象開發者聯系看是否為安全版本。
閱讀對象文檔發現該對象是否安全。
對象不能安全創建
試圖使用一個未被標識為安全創建的對象。對象創建是否安全由主機決定。總的來說,允許不信任腳本進行有害操作(例如操作硬碟)的對象是不安全的。
例如,使用作為客戶端的Microsoft Internet Explorer 運行 FileingObject 是不安全的,但是可以在帶有Windows Host的本地機器使用該對象。
要糾正該錯誤
確保在使用一個安全的對象。
與對象開發者聯系看是否為安全版本。
閱讀對象文檔發現該對象是否安全。
無效或不合格的引用
試圖對不止一個對象使用With語句。With語句只能被非空對象使用。下面演示了一個With 塊的正確結構。
With objectstatements End With
要糾正該錯誤
為With 語句指定一個對象。
類未定義
引用未定義(通過New 或 Set語句)的類。
要糾正該錯誤
確保在引用類之前已經定義。
發生異常
腳本調用COM對象,然後產生異常。
要糾正該錯誤
除非該調用由 Raise 方法產生,請與產生錯誤的CM對象開發人員聯系。
請與微軟產品服務聯系報告出現錯誤消息的情況。
正則表達式中的語法錯誤
搜索字元串的結構違背了VB正則表達式中的一個或多個語法規則。
要糾正該錯誤
保證常規的搜索字元串的表達式符合Perlde的表達語法。
錯誤的數量詞
當構造正則表達式的搜索模式時,沒有正確的說明匹配的字元串。
要糾正該錯誤
確保搜索模式是正確構造的。
在正則表達式中需要 ']'
試圖為正則表達式匹配創建一個字元類,但未包含右括弧。將單獨的字元組合放到方括弧里可以將其裝配到字元類中。例如, /[abc]/ 匹配字母「a」,「b」,或「c」中任意一個。
要糾正該錯誤
在正則表達式中添加右括弧。
在正則表達式中需要 ')'
試圖創建常規的嵌套表達式,但未包含「)」。在正則表達式中括弧有幾個目的。首先,它將分離的項組成為單個子表達式,所以項目可以通過*,+,?等等來當作一個單元來處理。
要糾正該錯誤
在常規的嵌套表達式中添加右(閉)括弧「)」。
字元集越界
試圖使用無效字元創建正則表達式。正則表達式是由字母數字和元字元組成的。
要糾正該錯誤
僅僅使用有效正則表達式字元來組成正則表達式。

C. 使用redis實現的分布式鎖原理是什麼

一、寫在前面

現在面試,一般都會聊聊分布式系統這塊的東西。通常面試官都會從服務框架(Spring Cloud、Dubbo)聊起,一路聊到分布式事務、分布式鎖、ZooKeeper等知識。

所以咱們這篇文章就來聊聊分布式鎖這塊知識,具體的來看看Redis分布式鎖的實現原理。

說實話,如果在公司里落地生產環境用分布式鎖的時候,一定是會用開源類庫的,比如Redis分布式鎖,一般就是用Redisson框架就好了,非常的簡便易用。

大家如果有興趣,可以去看看Redisson的官網,看看如何在項目中引入Redisson的依賴,然後基於Redis實現分布式鎖的加鎖與釋放鎖。

下面給大家看一段簡單的使用代碼片段,先直觀的感受一下:

大家看到了吧,那個myLock的hash數據結構中的那個客戶端ID,就對應著加鎖的次數

(5)釋放鎖機制

如果執行lock.unlock(),就可以釋放分布式鎖,此時的業務邏輯也是非常簡單的。

其實說白了,就是每次都對myLock數據結構中的那個加鎖次數減1。

如果發現加鎖次數是0了,說明這個客戶端已經不再持有鎖了,此時就會用:

「del myLock」命令,從redis里刪除這個key。

然後呢,另外的客戶端2就可以嘗試完成加鎖了。

這就是所謂的分布式鎖的開源Redisson框架的實現機制。

一般我們在生產系統中,可以用Redisson框架提供的這個類庫來基於redis進行分布式鎖的加鎖與釋放鎖。

(6)上述Redis分布式鎖的缺點

其實上面那種方案最大的問題,就是如果你對某個redis master實例,寫入了myLock這種鎖key的value,此時會非同步復制給對應的master slave實例。

但是這個過程中一旦發生redis master宕機,主備切換,redis slave變為了redis master。

接著就會導致,客戶端2來嘗試加鎖的時候,在新的redis master上完成了加鎖,而客戶端1也以為自己成功加了鎖。

此時就會導致多個客戶端對一個分布式鎖完成了加鎖。

這時系統在業務語義上一定會出現問題,導致各種臟數據的產生。

所以這個就是redis cluster,或者是redis master-slave架構的主從非同步復制導致的redis分布式鎖的最大缺陷:在redis master實例宕機的時候,可能導致多個客戶端同時完成加鎖。

D. Redis分布式鎖的原理與面試細節

<meta name="source" content="lake">

這里就講了下怎麼加鎖的,很多原理的問題小夥伴們,可用網路下分布式鎖,看圖中我特別在加鎖與刪除鎖的時候還有倆個指向就特別說下這倆個問題

我們加鎖的時候為了防止死鎖的問題都在加鎖散鋒的時候會帶上 鎖過期時間的問題我們使用Redis提供的設置值的時候跟設置過期時間是原子性的操命令

加鎖時候的原子性問題我們解決了,我們知道分布式鎖就是只有一個線程才能搶到鎖位,那其他線程怎麼處理呢?有些文章可能都只說了一些流程卻忘記了很多坑

加鎖失敗的幾個解決辦法【這也叫鎖沖突的問題】

加鎖過程我們處理好了,那麼刪除鎖的時候呢?

刪沖宴晌除鎖的時候我們既要防止刪除是別人鎖有要當業務流程執行時間大於加鎖的時間問題

刪除鎖的原子性就我們依靠了Lua腳本來實現刪除鎖的原子性

Redis鎖超時問題呢?

使用過或者了解過Redisson的小夥伴知道Redisson框祥灶架實現分布式鎖有一個看門狗機制,當業務流程大於加鎖時間的時候,看門狗機制為在加鎖的時間上在添加10秒

我們就來看看Redisson的加鎖實現就可用到Redisson的看門狗機制跟分布式的可重入

【重點主要是依賴lua腳本的原子性,實現加鎖和釋放鎖的功能】

使用redisson實現分布式鎖的操作步驟,三部曲

第一步: 獲取鎖 RLock redissonLock = redisson.getLock(lockKey);

第二步: 加鎖,實現鎖續命功能 redissonLock.lock();

第三步:釋放鎖 redissonLock.unlock();

重點的地方我都標出來了

我們看下RedissonLock構造函數

參數:

繼續看 lockInterruptibly方法

繼續往裡面追

大流程已經梳理完了,我們看下 Long ttl = tryAcquire(leaseTime, unit, threadId); 看門狗機制了

ARGV[2] ---------> getLockName(threadId) 實現如下

這個id就是自開始實例化RedissonLock的id ,是個UUID
我們來解釋下這段lua腳本【講的可重入邏輯】

那繼續監聽時間中的 scheleExpirationRenewal(threadId); 邏輯【看門狗續命】

重點看 unlockInnerAsync(Thread.currentThread().getId())

又是lua腳本,核心就是 把value減到為0 ,刪除key

Redisson的邏輯參考

附上流程圖

E. 急求《單片機C語言程序設計實訓100例——基於8051+Proteus模擬》第三部分綜合設計C語言源代碼

這本書一共5章節,你說第三部分指的哪裡?
第五章才是綜合設計部分啊,而且這部分有好多常式,也不知道你要哪部分?
第1章 8051單片機C語言程序設計概述 1
1.1 8051單片機引腳 1
1.2 數據與程序內存 5
1.3 特殊功能寄存器 6
1.4 外部中斷、定時器/計數器及串口應用 8
1.5 有符號與無符號數應用、數位分解、位操作 9
1.6 變數、存儲類型與存儲模式 11
1.7 關於C語言運算符的優先順序 13
1.8 字元編碼 15
1.9 數組、字元串與指針 16
1.10 流程式控制制 18
1.11 可重入函數和中斷函數 19
1.12 C語言在單片機系統開發中的優勢 20
第2章 Proteus操作基礎 21
2.1 Proteus操作界面簡介 21
2.2 模擬電路原理圖設計 22
2.3 元件選擇 25
2.4 調試模擬 29
2.5 Proteus與Vision 3的聯合調試 29
2.6 Proteus在8051單片機應用系統開發的優勢 30
第3章 基礎程序設計 32
3.1 閃爍的LED 32
3.2 雙向來回的流水燈 34
3.3 花樣流水燈 36
3.4 LED模擬交通燈 38
3.5 分立式數碼管循環顯示0~9 40
3.6 集成式數碼管動態掃描顯示 41
3.7 按鍵調節數碼管閃爍增減顯示 44
3.8 數碼管顯示4×4鍵盤矩陣按鍵 46
3.9 普通開關與撥碼開關應用 49
3.10 繼電器及雙向可控硅控制照明設備 51
3.11 INT0中斷計數 53
3.12 INT0及INT1中斷計數 55
3.13 TIMER0控制單只LED閃爍 58
3.14 TIMER0控制數碼管動態管顯示 62
3.15 TIMER0控制8×8LED點陣屏顯示數字 65
3.16 TIMER0控制門鈴聲音輸出 68
3.17 定時器控制交通指示燈 70
3.18 TIMER1控制音階演奏 72
3.19 TIMER0、TIMER1及TIMER2實現外部信號計數與顯示 75
3.20 TIMER0、TIMER1及INT0控制報警器與旋轉燈 77
3.21 按鍵控制定時器選播多段音樂 79
3.22 鍵控看門狗 82
3.23 雙機串口雙向通信 84
3.24 PC與單片機雙向通信 90
3.25 單片機內置EEPROM讀/寫測試 95
第4章 硬體應用 99
4.1 74HC138解碼器與反向緩沖器控制數碼管顯示 100
4.2 串入並出晶元74HC595控制數碼管顯示四位數字 103
4.3 用74HC164驅動多隻數碼管顯示 106
4.4 並串轉換器74HC165應用 110
4.5 用74HC148擴展中斷 112
4.6 串口發送數據到2片8×8點陣屏滾動顯示 115
4.7 數碼管BCD解碼驅動器CD4511與DM7447應用 117
4.8 62256RAM擴展內存 119
4.9 用8255實現介面擴展 121
4.10 可編程介面晶元8155應用 124
4.11 串列共陰顯示驅動器控制4+2+2集成式數碼管顯示 129
4.12 14段與16段數碼管演示 133
4.13 16鍵解碼晶元74C922應用 136
4.14 1602字元液晶工作於8位模式直接驅動顯示 139
4.15 1602液晶顯示DS1302實時時鍾 148
4.16 1602液晶屏工作於8位模式由74LS373控制顯示 153
4.17 1602液晶屏工作於4位模式實時顯示當前時間 155
4.18 1602液晶屏顯示DS12887實時時鍾 159
4.19 時鍾日歷晶元PCF8583應用 167
4.20 2×20串列字元液晶屏顯示 174
4.21 LGM12864液晶屏顯示程序 177
4.22 TG126410液晶屏串列模式顯示 184
4.23 Nokia7110液晶屏菜單控製程序 192
4.24 T6963C液晶屏圖文演示 199
4.25 ADC0832 A/D轉換與LCD顯示 211
4.26 用DAC0832生成鋸齒波 215
4.27 ADC0808 PWM實驗 217
4.28 ADC0809 A/D轉換與顯示 220
4.29 用DAC0808實現數字調壓 221
4.30 16位A/D轉換晶元LTC1864應用 223
4.31 I2C介面存儲器AT24C04讀/寫與顯示 225
4.32 I2C存儲器設計的中文硬體字型檔應用 233
4.33 I2C介面4通道A/D與單通道D/A轉換器PCF8591應用 237
4.34 I2C介面DS1621溫度感測器測試 241
4.35 用兼容I2C介面的MAX6953驅動4片5×7點陣顯示器 246
4.36 用I2C介面控制MAX6955驅動16段數碼管顯示 250
4.37 I2C介面數字電位器AD5242應用 254
4.38 SPI介面存儲器AT25F1024讀/寫與顯示 257
4.39 SPI介面溫度感測器TC72應用測試 264
4.40 溫度感測器LM35全量程應用測試 268
4.41 SHT75溫濕度感測器測試 272
4.42 直流電機正、反轉及PWM調速控制 278
4.43 正反轉可控的步進電機 281
4.44 ULN2803驅動點陣屏仿電梯數字滾動顯示 284
4.45 液晶顯示MPX4250壓力值 286
4.46 12864LCD顯示24C08保存的開機畫面 289
4.47 用M145026與M145027設計的無線收發系統 293
4.48 DS18B20溫度感測器測試 296
4.49 1-Wire式可定址開關DS2405應用測試 303
4.50 MMC存儲卡測試 307
第5章 綜合設計 316
5.1 帶日歷時鍾及溫度顯示的電子萬年歷 316
5.2 用8051+1601LCD設計的整型計算器 321
5.3 電子秤模擬設計 328
5.4 1602液晶屏顯示仿手機鍵盤按鍵字元 332
5.5 用24C04與1602液晶屏設計的簡易加密電子鎖 336
5.6 1-Wire匯流排器件ROM搜索與多點溫度監測 341
5.7 高模擬數碼管電子鍾設計 356
5.8 用DS1302與12864LCD設計的可調式中文電子日歷 360
5.9 用T6963C液晶屏設計的指針式電子鍾 366
5.10 T6963C液晶屏中文顯示溫度與時間 370
5.11 T6963C液晶屏曲線顯示ADC0832兩路A/D轉換結果 372
5.12 溫度控制直流電機轉速 374
5.13 用74LS595與74LS154設計的16×16點陣屏 377
5.14 用8255與74LS154設計的16×16點陣屏 379
5.15 紅外遙控收發模擬 381
5.16 GP2D12紅外測距感測器應用 388
5.17 三端可調正穩壓器LM317應用測試 395
5.18 數碼管顯示的K型熱電偶溫度計 399
5.19 交流電壓檢測與數字顯示模擬 403
5.20 用MCP3421與RTD-PT100設計的鉑電阻溫度計 407
5.21 可接收串口信息的帶中英文硬字型檔的80×16 LED點陣屏 414
5.22 模擬射擊訓練游戲 422
5.23 GPS模擬 427
5.24 溫室監控系統模擬 431
5.25 基於Modbus匯流排的數據採集與開關控制系統設計模擬 437

建議你到腳本之家網站去搜索一下看看有沒有這本書的電子檔。

熱點內容
安卓系統密碼忘了怎麼辦 發布:2025-02-13 21:49:28 瀏覽:971
找回密碼發送信息是什麼意思 發布:2025-02-13 21:49:26 瀏覽:639
織夢通用源碼 發布:2025-02-13 21:48:41 瀏覽:438
pid演算法調速 發布:2025-02-13 21:20:31 瀏覽:686
腳本中new 發布:2025-02-13 21:00:11 瀏覽:741
什麼配置的筆記本電腦能玩神武 發布:2025-02-13 20:54:40 瀏覽:179
挑選雲伺服器需要注意什麼 發布:2025-02-13 20:53:31 瀏覽:98
加密滴膠卡 發布:2025-02-13 20:30:48 瀏覽:275
javalogin 發布:2025-02-13 20:25:48 瀏覽:427
智聯招聘無法上傳照片 發布:2025-02-13 20:16:03 瀏覽:529