觸發設備離線

業務場景

業務開發過程中,我們經常會需要判斷遠程終端是否在線,當終端離線的時候我們需要發送消息告知相應的系統,

環形隊列
?

1.創建一個index從0到30的環形隊列(本質是個數組)
2.環上每一個slot是一個Set,任務集合
3.同時還有一個Map<uid, index>,記錄uid落在環上的哪個slot里
4.啟動一個timer,每隔1s,在上述環形隊列中移動一格,0->1->2->3…->29->30->0…
5.有一個Current Index指針來標識剛檢測過的slot
6.接收到設備心跳后將尋找到原來uid的位置然后移動到當前指針的后一位,并刪除原來slot里的uid
7.這樣就可以快速獲取超時的設備uid

環形隊列實現

package com.zngx.admin.circle;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @Author : zhiying* @Date : 2022-11-22 15:17* @Desc : 環形隊列 - 設備離線判定* 1、預設一個長度為10000的數組(按實際業務定義長度)* 2、每個數組存放一個Set集合* 3、維護一個游標cur,從0到9999遞增,到達9999時,重置為0(啟動一個線程執行)* 4、維護一個map,記錄所有設備ID存放的數組位置,方便查找* 5、監聽到設備心跳時,先將原來的數據從指定位置的集合中刪除,通過計算當前游標位置和keepAlive尋找合適的位置將設備ID放入* 6、當游標指向某個位置a時,a位置的集合中的所有設備全部判定為離線,并清空該位置的集合**/public class CircleQueue<T> {//線程安全鎖Lock lock = new ReentrantLock();//初始環形隊列大小private int capacity = 10000;//當前環形隊列所在節點private volatile int currentIndex = 0;//數據所在節點private Map<T,Integer> dataIndex = new HashMap<>();//環形隊列private Set<T>[] array;public CircleQueue(){array = new HashSet[capacity];}public CircleQueue(int capacity){this.capacity = capacity;array = new HashSet[capacity];}/*** 向環形隊列中添加元素* @param t* @param offset 偏移量,基于游標*/public void add(T t, int offset){int index = currentIndex + offset;if(index >= capacity){index = index - capacity;}try {lock.lock();//判斷數據是否存在if(dataIndex.containsKey(t)){Set<T> old  =  array[dataIndex.get(t)];old.remove(t);}//獲取當前節點的隊列Set<T> set = array[index];if(null == set){set = new HashSet<>();array[index] = set;}set.add(t);//更新新的節點位置dataIndex.put(t,index);}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}/*** 下移一格,到9999重新置為0*/public void next(){int cur = currentIndex + 1;if(cur >= capacity){cur = cur - capacity;}currentIndex = cur;System.out.println("當前游標位置:" + currentIndex);}/*** 獲取當前游標指向的元素集合* @return*/public Set<T> getAndDeleteData(){Set<T> set = null;try {lock.lock();set = array[currentIndex];return set;}finally {// 將集合中所有的元素移除array[currentIndex] = new HashSet<>();if(set != null && set.size()>0){set.forEach(t -> {dataIndex.remove(t);});}lock.unlock();}}public int getIndex(T t){if(dataIndex.containsKey(t)){return dataIndex.get(t);}return -1;}
}

測試代碼?

    @Testpublic void circleTest(){CircleQueue<String> circleQueue = new CircleQueue<>();for (int i=0;i<1000;i++){String uuid = String.valueOf(i+1);int offset = (int) Math.round(Math.random()*10);circleQueue.add(uuid, offset);}checkTimeout(circleQueue);insertDataRandom(circleQueue);try {Thread.sleep(600000);}catch (Exception e){e.printStackTrace();}}private void checkTimeout(CircleQueue<String> circleQueue){service.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {Set<String> set = circleQueue.getAndDeleteData();if(set == null || set.isEmpty()) {System.out.println("本次沒有設備離線");}else{System.out.println("這些設備離線啦:" + Joiner.on(",").join(set));}circleQueue.next();}},2,1, TimeUnit.SECONDS);}private void insertDataRandom(CircleQueue<String> circleQueue){service.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {String deviceId = String.valueOf(Math.round(Math.random()*100000));int offset = (int) Math.round(Math.random()*10);circleQueue.add(deviceId, offset);System.out.println("插入設備["+deviceId+"], " + offset + "秒后離線");}},3,3, TimeUnit.SECONDS);}

?測試結果

148aed53-a083-40a6-82d3-ede14e5e39c9初始時間1585571543739
當前位置:0數據大小:0
當前位置:1數據大小:0
當前位置:2數據大小:0
當前位置:3數據大小:0
當前位置:4數據大小:0
148aed53-a083-40a6-82d3-ede14e5e39c9不移動位置29
當前位置:5數據大小:0
當前位置:6數據大小:0
當前位置:7數據大小:0
當前位置:8數據大小:0
當前位置:9數據大小:0
當前位置:10數據大小:0
當前位置:11數據大小:0
當前位置:12數據大小:0
當前位置:13數據大小:0
當前位置:14數據大小:0
148aed53-a083-40a6-82d3-ede14e5e39c9不移動位置29
當前位置:15數據大小:0
當前位置:16數據大小:0
當前位置:17數據大小:0
當前位置:18數據大小:0
當前位置:19數據大小:0
當前位置:20數據大小:0
當前位置:21數據大小:0
當前位置:22數據大小:0
當前位置:23數據大小:0
當前位置:24數據大小:0
148aed53-a083-40a6-82d3-ede14e5e39c9不移動位置29
當前位置:25數據大小:0
當前位置:26數據大小:0
當前位置:27數據大小:0
當前位置:28數據大小:0
148aed53-a083-40a6-82d3-ede14e5e39c9過期
超時時間30005

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161027.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161027.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161027.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python 執行系統命令

subprocess 模塊和 os.system 或 os.popen 等函數相比&#xff0c;功能更為強大和靈活&#xff0c;是 Python 官方推薦的執行系統命令的方法。主要的優勢包括&#xff1a; 更強的錯誤處理&#xff1a;subprocess 模塊可以更精細地控制錯誤輸出和錯誤代碼&#xff0c;而 os.syst…

自定義springboot的生命周期函數在項目啟動完成后去取配置文件中的值

主要是實現smartLifecycle類 package com.ruoyi.workflow.util;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springfr…

MYSQL索引使用注意事項

索引使用注意事項&#xff1a; 1.索引列運算 不要在索引列上進行運算操作&#xff0c;否則索引將失效&#xff1b; 2.字符串不加引號 字符串類型使用時&#xff0c;不加引號&#xff0c;否則索引將失效&#xff1b; 3.模糊查詢 如果僅僅是尾部模糊匹配&#xff0c;索引將不會失…

防火墻暴露端口

如果你想開通防火墻上的端口&#xff0c;具體的操作方式可能會取決于你所使用的操作系統。以下是一些常見操作系統的步驟&#xff1a; 1. Linux&#xff08;例如&#xff0c;Ubuntu 或 CentOS&#xff09;: 使用 ufw&#xff08;適用于 Ubuntu&#xff09;&#xff1a; # 開…

RK平臺查看板子上的dts信息

簡介 dts文件描述了硬件每個模塊的信息&#xff0c;我們嵌入式軟件的調試很多時候都是在改dts文件&#xff0c;有時候我們不確定板子上的固件是否已經更新了我們的修改&#xff0c;這時候我們可以直接讀取板子上的dts信息&#xff0c;下面來演示一下。 進入uboot命令行模式 …

關于軟raid的實現及常見問題

RAID概念 磁盤陣列&#xff08;Redundant Arrays of Independent Disks&#xff0c;RAID&#xff09;&#xff0c;有“獨立磁盤構成的具有冗余能力的陣列”之意。 磁盤陣列是由很多價格較便宜的磁盤&#xff0c;以硬件&#xff08;RAID卡&#xff09;或軟件&#xff08;MDADM&…

關于用css設置input輸入框hover的時候的樣式以及當input為disabled的時候,不要讓hover樣式生效

效果如果&#xff1a; 編輯狀態下的時候&#xff1a; 只讀狀態下的時候&#xff1a; 代碼如圖&#xff1a; <input type"text" name"dataForm.exportCode" id"exportCodeItem" required :disabled"editDisabled" />input:not(…

【前端學java】語法練習-工具類的封裝(13)

往期回顧&#xff1a; 【前端學java】JAVA開發的依賴安裝與環境配置 &#xff08;0&#xff09;【前端學 java】java的基礎語法&#xff08;1&#xff09;【前端學java】JAVA中的packge與import&#xff08;2&#xff09;【前端學java】面向對象編程基礎-類的使用 &#xff08…

java.net.UnknownHostException: eureka

java.net.UnknownHostException: eureka 哦。HOST漏了 #linux /etc/hosts #windows C:\Windows\System32\drivers\etc\hosts 127.0.0.1 eureka7000 127.0.0.1 eureka7001 127.0.0.1 eureka7002

maven打包可執行jar含依賴lib

修改pom.xml <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!-- jdk8可用&#xff0c;其他jdk版本可能需改插件版本 --><version>2.3.7.RE…

sql調優

慢查詢 SQL 治理方案 一、SQL 性能下降的原因 在對 SQL 進行分析之前&#xff0c;需要明確可能導致 SQL 執行性能下降的原因進行分析&#xff0c;執行性能下降可以體現在很多方面&#xff1a; 查詢語句寫的爛索引沒加好表數據過大數據庫連接數不夠查詢的數據量過大被其他慢s…

MyBatisPlus代碼生成

基礎依賴 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…

visual studio 如何建立 C 語言項目

安裝這個 模塊。 新建 空項目 創建完成 寫demo 點擊運行&#xff1a;

【1day】泛微e-office OA系統user_page接口未授權訪問漏洞學習

注:該文章來自作者日常學習筆記,請勿利用文章內的相關技術從事非法測試,如因此產生的一切不良后果與作者無關。 目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現

Web項目從Tomcat遷移到TongWeb

注意事項 1. 使用JNDI方式獲取數據源&#xff1a; ①在TongWeb創建JDBC連接池; ②修改Web項目數據源配置. #spring.datasource.urljdbc:mysql://127.0.0.1:3306/demo #spring.datasource.usernametest #spring.datasource.passwordspring.datasource.jndi-namedemo2. 修…

Spring cloud - Hystrix源碼

其實只是Hystrix初始化部分&#xff0c;我們從源碼的角度分析一下EnableCircuitBreaker以及HystrixCommand注解的初始化過程。 從EnableCircuitBreaker入手 我們是通過在啟動類添加EnableCircuitBreaker注解啟用Hystrix的&#xff0c;所以&#xff0c;源碼解析也要從這個注解…

最新PHP熊貓頭圖片表情斗圖生成源碼

這是一款能生成熊貓頭表情斗圖的自適應系統源碼&#xff0c;無論是在電腦還是手機上都可以正常使用&#xff01;這個源碼集成了搜狗搜索圖片接口&#xff0c;可以輕松地一鍵搜索數百萬張圖片&#xff0c;并且還包含了表情制作等功能模塊。對于一些新站來說&#xff0c;這是一個…

Cloud微服務

當我們談論“云微服務”時&#xff0c;通常是指基于云計算和微服務架構的應用程序開發和部署模型。以下是關于云微服務的一些詳細信息&#xff1a; 微服務架構&#xff1a; 微服務架構是一種軟件設計和開發模式&#xff0c;將應用程序劃分為一組小型、獨立的服務單元。每個服…

c++ LRU(最近最少使用)緩存機制

// LRU(最近最少使用)緩存機制 #ifndef _ZD_LRU_CACHE_H_ #define _ZD_LRU_CACHE_H_#include <unordered_map> #include <list> #include <mutex>class ZDLRUCahce { public:ZDLRUCahce(int capacity): m_capacity(capacity){}~ZDLRUCahce(){}// 1.key不存在…