国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

微信小程序網(wǎng)站開發(fā)教程旅游seo整站優(yōu)化

微信小程序網(wǎng)站開發(fā)教程,旅游seo整站優(yōu)化,京津冀協(xié)同發(fā)展八周年,開發(fā)系統(tǒng) 平臺目錄 一、鎖的使用場景 二、如何實現(xiàn)控制? 三、單臺服務器使用鎖的場景 四、分布式鎖 五、Redis 實現(xiàn)分布式鎖及存在問題 六、Redisson 實現(xiàn)分布式鎖 七、定時任務+鎖 一、鎖的使用場景 1. 控制定時任務執(zhí)行 定時任務多次執(zhí)行浪費資源&#xff…

目錄

一、鎖的使用場景

二、如何實現(xiàn)控制?

三、單臺服務器使用鎖的場景

四、分布式鎖

五、Redis 實現(xiàn)分布式鎖及存在問題

六、Redisson 實現(xiàn)分布式鎖

七、定時任務+鎖


一、鎖的使用場景

1. 控制定時任務執(zhí)行

  • 定時任務多次執(zhí)行浪費資源:多臺服務器到同一時間都執(zhí)行緩存預熱
  • 臟數(shù)據(jù):多臺服務器重復插入數(shù)據(jù)

2. 買票場景

  • 只有一百張票,用戶買票時判斷剩余票的數(shù)量,還有剩余執(zhí)行票數(shù)減一的操作
  • 只剩一張票了,此時多個用戶來買票,判斷票都是有剩余,但是第一個用戶買完之后就沒票了,其他用戶也執(zhí)行了票數(shù)減一的操作,出現(xiàn)超賣現(xiàn)象

3. 需求:控制定時任務 / 需要加鎖的任務在同一時間只能有一臺服務器執(zhí)行

二、如何實現(xiàn)控制?

以定時任務為例

1.?分離定時任務程序和主程序,只在一臺服務器運行定時任務=>成本太大

2.?寫死配置,每個服務器都執(zhí)行定時任務,但是只有 IP?符合配置的服務器才真實執(zhí)行業(yè)務邏輯,其他的直接返回。成本最低;但是我們的 IP 可能是不固定的,把 IP 寫的太死了

3.?動態(tài)配置,配置是可以輕松的、很方便地更新的(代碼無需重啟,項目無需重新部署),但是只有 IP?符合配置的服務器才真實執(zhí)行業(yè)務邏輯。

  • 讀取數(shù)據(jù)庫中的配置

  • Redis

  • 配置中心(Nacos、Apollo、Spring Cloud Config)

  • 問題:服務器多了、IP 不可控還是很麻煩,還是要人工修改

4.?分布式鎖:只有搶到鎖的服務器才能執(zhí)行業(yè)務邏輯

  • 壞處:增加成本
  • 好處:不用手動配置,多少個服務器都一樣

三、單臺服務器使用鎖的場景

1. Java 實現(xiàn)同步鎖:synchronized 關(guān)鍵字

2. 鎖存在 JVM 中,每臺 JVM 獨立,不共享鎖,多機部署鎖會失效(多個線程都會獲取到不同 JVM 中的同一名稱的鎖)

3. 單機就會存在單點故障

四、分布式鎖

1. 為什么需要分布式鎖?

  • 普通鎖的缺點:JVM 機分配的鎖在多臺 Tomcat 中不共享,鎖只對單個服務器有效
  • 加鎖的重要性:資源有限 / 特定情況下只能有有限 / 唯一的線程獲取到鎖,執(zhí)行操作
  • 分布式鎖:多進程可見且并且互斥的鎖

2. 如何實現(xiàn)分布式鎖?

實現(xiàn)分布式鎖的核心思想 /?怎么保證同一時間只有一臺服務器能搶到鎖?

  • 先來的人先把數(shù)據(jù)改成自己的標識(服務器 IP),后來的人發(fā)現(xiàn)標識已存在,就搶鎖失敗,繼續(xù)等待
  • 等先來的人執(zhí)行方法結(jié)束,把標識清空(釋放鎖),其他的人繼續(xù)搶鎖
  • MySQL 數(shù)據(jù)庫:select for update 行級鎖(最簡單)
  • 樂觀鎖(實際上沒有加鎖):樂觀鎖認為線程安全問題只在少數(shù)情況下會發(fā)生,所以只要在數(shù)據(jù)更新時判斷是否有其他線程修改了數(shù)據(jù)
  • Redis 實現(xiàn)互斥鎖:基于內(nèi)存,讀寫速度快
    • set nx ex:原子性、設(shè)置過期時間
    • lua 腳本:保證多條語句的原子性
  • Zookeeper

五、Redis 實現(xiàn)分布式鎖及存在問題(誤刪鎖)

1. set nx ex

2. 釋放鎖

  • 手動釋放:del lock
  • 意外:服務器宕機,手動釋放鎖還未執(zhí)行
  • 優(yōu)化:設(shè)置過期時間,若未手動釋放則等到過期時間到了就會自動釋放鎖

3. 誤刪鎖

  • 線程 A 在執(zhí)行時阻塞,過了鎖的過期時間,鎖自動釋放
  • 線程 B 嘗試獲取鎖,獲取成功,執(zhí)行業(yè)務
  • A 阻塞之后繼續(xù)執(zhí)行,執(zhí)行結(jié)束,釋放當前正在被線程 B 占有的鎖
  • 線程 C 嘗試獲取鎖,獲取成功,執(zhí)行業(yè)務
  • 出現(xiàn)線程 B 和線程 C 并發(fā)執(zhí)行的情況

4. 解決誤刪鎖

  • 判斷當前鎖的占有線程是不是本線程
  • 如果不是自己占有的鎖,就不去釋放(別人的鎖)

5. 改進鎖之后仍然存在問題:判斷鎖和釋放鎖的原子性問題

  • 判斷鎖時是自己正在占有鎖
  • 判斷鎖標識后,執(zhí)行釋放鎖之前,線程出現(xiàn)了阻塞,鎖到了過期時間,自動釋放
  • 其他線程嘗試獲取鎖,獲取成功
  • 阻塞之后執(zhí)行釋放鎖,還是把別人的鎖給釋放了
  • 需要保證判斷鎖和釋放鎖操作的原子性:Lua 腳本

六、Redisson 實現(xiàn)分布式鎖

Github:https://github.com/redisson/redisson

官網(wǎng):Redisson: Easy Redis Java client with features of In-Memory Data Grid

1. 定義

  • Redisson 是一個在 Redis 基礎(chǔ)上實現(xiàn)的 Java 駐內(nèi)存數(shù)據(jù)網(wǎng)格
  • 提供了一系列分布式的 Java 常用對象,還提供了許多分布式服務(各種分布式鎖的實現(xiàn))

2. 自己編寫 Redisson 的配置,創(chuàng)建 RedissonClient

  • 不推薦使用 spring-boot-starter 整合的 Redisson,版本迭代較快,容易發(fā)生沖突
  • 創(chuàng)建 config 對象,添加 Redis 配置:讀取 application.yml 中的配置信息
  • 創(chuàng)建 Redisson 實例,返回 Redisson 客戶端實例
/*** Redisson 配置* @author 樂小鑫* @version 1.0* @Date 2024-01-21-15:44*/
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {private String host;private String port;private String password;@Beanpublic RedissonClient getRedissonClient() {// 1. 創(chuàng)建配置Config config = new Config();String redisAddress = String.format("redis://%s:%s", host, port);config.useSingleServer().setAddress(redisAddress).setPassword(password).setDatabase(3);// 2. 創(chuàng)建 Redisson 客戶端實例并返回RedissonClient redisson = Redisson.create(config);return redisson;}
}

3. 測試 Redisson 的功能實現(xiàn)

/*** @author 樂小鑫* @version 1.0* @Date 2024-01-21-15:53*/
@SpringBootTest
public class RedissonTest {@Resourceprivate RedissonClient redissonClient;@Testvoid test() {// listList<String> list = new ArrayList<>();list.add("ghost");System.out.println("List:" + list.get(0));RList<Object> rList = redissonClient.getList("test-list");rList.add("ghost");System.out.println("rList:" + rList.get(0));}
}

4. 看門狗機制的原理

  • 監(jiān)聽當前線程,當前線程沒有執(zhí)行結(jié)束就每十秒續(xù)期一次
  • 如果線程掛了(注意 Debug 模式時斷點過久也會被當成服務器宕機來處理),看門狗機制失效,則不會續(xù)期
  • 參考文章:Redisson 分布式鎖的watch dog自動續(xù)期機制_redisson續(xù)期-CSDN博客

七、定時任務+鎖

1. getLock():獲取 Redisson 的鎖對象,需要指定鎖的名稱

2. tryLock():嘗試獲取鎖(分布式鎖),獲取成功返回 true,可以指定重試獲取鎖的等待時間和鎖的釋放時間

  • waitTime 設(shè)置為 0:嘗試獲取鎖獲取失敗,等待時間為 0,直接放棄獲取鎖(只嘗試一次),因為這里是用戶推薦列表的緩存預熱定時任務,如果獲取鎖失敗,說明已經(jīng)有服務器去執(zhí)行定時任務了,只要執(zhí)行一次就好了,所以不用再去嘗試獲取鎖

3. unlock():釋放鎖,放到 finally 語句塊中執(zhí)行,如果 try 語句塊中的內(nèi)容出現(xiàn)異常,也會釋放鎖,避免發(fā)生死鎖的情況

/*** 緩存預熱定時任務* @author 樂小鑫* @version 1.0*/
@Component
@Slf4j
public class PreCacheUser {@Resourceprivate RedisTemplate redisTemplate;@Resourceprivate UserService userService;@Resourceprivate RedissonClient redissonClient;List<Long> mainUserList = Arrays.asList(3L);// 重要用戶列表,為該列表的用戶開啟緩存預熱@Scheduled(cron = "0 59 21 ? * * ")// 每天 21:59 執(zhí)行定時任務進行用戶數(shù)據(jù)緩存預熱public void doPreCacheUser() {// 獲取鎖對象RLock lock = redissonClient.getLock("langhua:precachejob:doprecache:lock");try {if (lock.tryLock(0,30000L,TimeUnit.MILLISECONDS)) {log.info("get redisson lock" + Thread.currentThread().getId());// 查出用戶存到 Redis 中for (Long userId : mainUserList) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();Page<User> userPage = userService.page(new Page<>(1, 20), queryWrapper);// 查詢所有用戶String key = String.format("langhua:user:recommend:%s", userId);ValueOperations valueOperations = redisTemplate.opsForValue();// 將查詢出來的數(shù)據(jù)寫入緩存try {valueOperations.set(key,userPage,24, TimeUnit.HOURS);} catch (Exception e) {log.error("redis key set error", e);}}}} catch (InterruptedException e) {log.error("redisson precache user error", e);} finally {// 釋放鎖log.info("redisson unlock" + Thread.currentThread().getId());lock.unlock();}}
}
http://aloenet.com.cn/news/28268.html

相關(guān)文章:

  • 蘇州專業(yè)網(wǎng)站建設(shè)開發(fā)網(wǎng)站seo快速排名優(yōu)化的軟件
  • 一個內(nèi)部網(wǎng)站如何做外網(wǎng)映射百度的推廣廣告
  • 南陽做網(wǎng)站多少錢seo優(yōu)化培訓班
  • iis 做網(wǎng)站百度賬號管理中心
  • 網(wǎng)站開發(fā)和美工的區(qū)別國內(nèi)做網(wǎng)站的公司
  • 時間軸網(wǎng)站湖南網(wǎng)站seo公司
  • 自問自答網(wǎng)站怎么做推廣方式
  • 網(wǎng)站開發(fā)后端怎么開發(fā)帶傭金的旅游推廣平臺有哪些
  • wordpress 導入網(wǎng)站seo大牛
  • 訪問網(wǎng)站出現(xiàn)目錄seo是什么專業(yè)的課程
  • 可以做宣傳的網(wǎng)站交易鏈接
  • 國內(nèi)做的好的網(wǎng)站短視頻剪輯培訓班速成
  • 百度推廣競價技巧seo的優(yōu)化原理
  • 男女做的那些事情的網(wǎng)站最近七天的新聞重點
  • 12306鐵路網(wǎng)站開發(fā)語言電商怎么做推廣
  • asp.net做報名網(wǎng)站seo矩陣培訓
  • 北京附近做網(wǎng)站的公司有哪些網(wǎng)絡(luò)營銷經(jīng)典失敗案例
  • 貴陽百度公司建網(wǎng)站電話公司企業(yè)網(wǎng)站建設(shè)方案
  • 記事本做網(wǎng)站怎么加背景圖佛山做網(wǎng)站推廣的公司
  • 鄭州seo網(wǎng)站排名優(yōu)化公司蘇州網(wǎng)站建設(shè)開發(fā)公司
  • 優(yōu)化是企業(yè)通過網(wǎng)站來做嗎天津seo關(guān)鍵詞排名優(yōu)化
  • 嘉興的信息公司網(wǎng)站怎么做網(wǎng)站平臺
  • 企業(yè)網(wǎng)站的需求分析精準客戶數(shù)據(jù)采集軟件
  • 做文案用什么網(wǎng)站宣傳推廣方式有哪些
  • 做網(wǎng)站解析要多久百度應用商店app下載安裝
  • php做視頻網(wǎng)站有哪些軟件下載方象科技的企業(yè)愿景
  • 臨沂網(wǎng)站建設(shè)有哪些啥是網(wǎng)絡(luò)推廣
  • 專業(yè)地推團隊seo百度快速排名軟件
  • 沒有網(wǎng)站限制的瀏覽器臺州網(wǎng)站建設(shè)
  • 汕頭網(wǎng)絡(luò)公司網(wǎng)站建設(shè)朝陽網(wǎng)站seo