分布式鎖在分布式系統中非常重要,主要用于解決多個進程/服務并發訪問共享資源時的數據一致性問題。在日常開發中常用于:
1. 防止重復操作(冪等性控制)
場景:用戶重復提交訂單、重復支付、重復點擊等。
示例:
用戶快速點擊“提交訂單”按鈕時,用?訂單ID + 用戶ID?作為鎖的Key,確保同一訂單不會被重復處理。2. 秒殺/搶購(庫存扣減)
場景:高并發下扣減庫存,防止超賣。
3. 定時任務調度(避免多實例重復執行)
場景:集群環境下,確保定時任務(如每天報表生成)只由一個節點執行。
4. 分布式系統并發控制
場景:多個服務實例同時操作共享資源(如文件、配置、數據庫行)。
示例:
多個節點同時修改同一份配置文件時,通過分布式鎖確保串行化修改。5. 緩存擊穿保護
場景:高并發下緩存失效時,防止大量請求直接穿透到數據庫。
6. 全局唯一流水號生成
場景:分布式系統中生成唯一訂單號、交易號等。
示例:
通過鎖保護Redis/LDB的自增序列,避免號段重復。7. 分布式事務協調
場景:在Saga、TCC等分布式事務模式中,作為協調資源競爭的手段。
Redission的使用
1.引入依賴:
<!--使用redisson作為所有分布式鎖,分布式對象等功能框架-->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.0</version>
</dependency>
2.完成配置,與Redis服務器建立連接:
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;/*** @author* @Desc:redisson配置* @create: 2024-06-08 17:54**/
@Configuration
public class MyRedissonConfig {@Bean(destroyMethod = "shutdown")public RedissonClient redisson()throws IOException{Config config=new Config();config.useSingleServer().setAddress("redis://192.168.56.10:6379");return Redisson.create(config);}
}
上面代碼中@Bean(destroyMethod="shutdown"),destroyMethod="shutdown" 起到作用為:當Spring容器關閉時,會自動調用RedissonClient實例的shutdown()
方法來優雅地關閉Redisson客戶端連接,關閉與Redis服務器的連接,釋放所有相關資源,避免資源泄漏。
3.使用,在需要使用Redission的地方,使用注解完成資源注入:
@Autowiredprivate RedissonClient redissonClient;
具體使用示例:
@Autowiredprivate RedissonClient redissonClient;public static final String UPLOAD_LOCK = "seckill:upload:lock";// 每隔5秒執行一次@Scheduled(cron = "*/5 * * * * ?")public void uploadSeckillSkuLatest3Days() {log.info("上架最近三天的秒殺商品");// 加上分布式鎖,避免多個定時任務同時執行RLock lock = redissonClient.getLock(UPLOAD_LOCK);// 最多等待10秒,上鎖成功,則執行秒殺商品上架邏輯lock.lock(10, TimeUnit.SECONDS);try {seckillSkuService.uploadSeckillSkuLatest3Days();} finally {lock.unlock();}}
上面代碼中有2處需特別注意:
1.上鎖時間,等待時間,需結合業務代碼執行時間進行設置,比業務代碼執行時間多出1~2秒;
2. 在finally代碼塊中釋放鎖,無論執行成功與否或有異常產生,都要釋放鎖,防止出現死鎖。
拓展
1.技術選型建議
-
Redis(Redisson):性能高,適合大多數場景(推薦)。
-
Zookeeper:強一致性,適合對可靠性要求極高的場景。
-
數據庫樂觀鎖/悲觀鎖:簡單但性能較差,適合低頻競爭場景。
2.注意事項
-
鎖的粒度:盡量細粒度(例如按訂單ID鎖,而非全局鎖)。
-
超時時間:避免死鎖,設置合理的超時(Redisson默認30秒)。
-
可重入性:確保鎖支持同一線程重入(Redisson的
RLock
支持)。 -
容錯性:考慮Redis集群故障時的降級方案(如本地鎖+告警)。
分布式鎖是分布式系統的核心基礎組件,合理使用能有效解決并發沖突問題。