gatewayworker中需要定時(shí)給設(shè)備發(fā)送modbus命令讀取數(shù)據(jù),一個(gè)柜子下理論最多有255個(gè)探頭,我現(xiàn)在的思路是把所有探頭根據(jù)參數(shù)生成命令存放在session中,每個(gè)柜子一個(gè)定時(shí)器定時(shí)遍歷發(fā)送命令
因?yàn)閙odbus下存在一種寄變模式,根據(jù)返回的值無法確定這包數(shù)據(jù)是屬于哪個(gè)探頭的,所以需要延時(shí)等待結(jié)果,完成一個(gè)過一個(gè),但框架不能用sleep
我現(xiàn)在有三個(gè)解決思路:
1,用globaldata組件共享數(shù)據(jù),專門寫一個(gè)worker來處理定時(shí)發(fā)送命令,里面使用sleep[有個(gè)疑問?這里使用sleep只是對應(yīng)的這個(gè)worker進(jìn)程不能處理其他請求,還是整個(gè)框架都進(jìn)入睡眠停止工作,比如負(fù)責(zé)連接設(shè)備的gateway進(jìn)程會(huì)不會(huì)受影響];
2,用http把參數(shù)傳出去用網(wǎng)頁那邊發(fā)送命令;
3,遍歷生成定時(shí)器,每個(gè)定時(shí)器執(zhí)行時(shí)間岔開固定時(shí)間,也可以實(shí)現(xiàn)延時(shí)發(fā)送效果;
因?yàn)橐陨先齻€(gè)思路存在額外開銷或者需要生成最大大于原思路200倍以上的定時(shí)器數(shù)量,比較擔(dān)心性能和穩(wěn)定性,如果拋開以上三個(gè)思路,您有更好的思路推薦嗎?或者沒有其他更好的思路,以上三個(gè)思路您推薦哪個(gè),非常感謝
如果你的設(shè)備不支持同時(shí)處理多個(gè)探頭數(shù)據(jù)(因?yàn)榉祷亟Y(jié)果無法確定是哪個(gè)探頭的結(jié)果),那么就需要把數(shù)據(jù)存儲(chǔ)成一個(gè)類似隊(duì)列的存儲(chǔ)結(jié)構(gòu)里,比如存在mysql里,每條數(shù)據(jù)需要標(biāo)記是否發(fā)送給了設(shè)備,發(fā)送時(shí)間,是否返回了結(jié)果,返回結(jié)果時(shí)間。設(shè)備上線后從數(shù)據(jù)庫里讀一個(gè)這個(gè)設(shè)備未收到回復(fù)的請求,然后發(fā)送。服務(wù)端onMessage收到回復(fù)后標(biāo)記收到回復(fù)及時(shí)間,然后再查一遍是否有下個(gè)等待發(fā)送的請求,有的話繼續(xù)。
以上邏輯不需要什么延遲等待結(jié)果。但是需要考慮一些極端情況,比如發(fā)給設(shè)備請求后,設(shè)備一直沒返回響應(yīng),那么如何處理?比如斷開連接,讓設(shè)備重連重新發(fā)送?還是直接重新發(fā)送,如果直接重新發(fā)送會(huì)不會(huì)得到2個(gè)響應(yīng),導(dǎo)致錯(cuò)誤標(biāo)記到下一條請求被響應(yīng)? 建議弄個(gè)定時(shí)任務(wù),查詢超時(shí)的請求,然后斷開對應(yīng)的連接。
老大,我可能邏輯沒說清楚,場景是這樣的,柜子負(fù)責(zé)聯(lián)網(wǎng)并轉(zhuǎn)發(fā)服務(wù)器指令到對應(yīng)的探頭,探頭反饋結(jié)果也會(huì)經(jīng)由柜子中轉(zhuǎn)發(fā)送給服務(wù)器,它們使用MODBUS RTU協(xié)議,柜子充當(dāng)一個(gè)終端設(shè)備,它底下可能拖了N+<255個(gè)探頭,探頭與服務(wù)器是通過柜子中繼通訊的,服務(wù)器需要周期性的不停發(fā)送讀取指令給每個(gè)探頭,探頭反饋的數(shù)據(jù)存放在Session中并不斷更新,我會(huì)寫另一個(gè)定時(shí)器去周期性讀取該數(shù)據(jù)進(jìn)行存儲(chǔ),也可以通過gatewayclient去獲取,這是業(yè)務(wù)主邏輯
讀取指令是當(dāng)柜子上線后實(shí)時(shí)算出來的,比如A柜子下有三個(gè)探頭,那么我便存三條命令到session中,周期性發(fā)送,不用數(shù)據(jù)庫存儲(chǔ)是因?yàn)槊看喂褡由暇€需要做的準(zhǔn)備工作中有足夠的因素實(shí)時(shí)計(jì)算出讀取指令,這樣即可以保證準(zhǔn)確性也避免了多余的數(shù)據(jù)庫讀操作
而前面提到的需要延遲等待是因?yàn)?探頭因?yàn)楦鞣N原因,工作環(huán)境,本身的配置及網(wǎng)絡(luò)等因素影響,未必能快速及時(shí)的反饋結(jié)果,而且無間隔發(fā)送指令會(huì)導(dǎo)致卡頓或認(rèn)為是無效指令進(jìn)行丟棄,畢竟那里面只是一個(gè)單片機(jī)和計(jì)算機(jī)比簡直天淵之別,所以需要服務(wù)器這邊控制好發(fā)送間隔
為保證穩(wěn)定我打算每條指令之間延遲2s,我已經(jīng)寫完設(shè)備匹配部分了,大致思路和你寫的一樣,因?yàn)槠ヅ湓诰W(wǎng)頁中進(jìn)行那邊是接口操作,可以進(jìn)行sleep,通過gatewayclient發(fā)送讀取指令,在發(fā)送讀取指令前,updateSession把讀取的設(shè)備編號(hào)存進(jìn)去,gateway拿到數(shù)據(jù)更新并清空上一步傳過來的編號(hào),進(jìn)入下一個(gè)邏輯循環(huán)往復(fù)就可以了,現(xiàn)在的問題是框架中不能sleep所以才遇到問題,因?yàn)榭紤]的東西比較多,主要是性能,所以走的思路和您的不太一樣,如果是這樣的情況,您推薦怎么做,謝謝指點(diǎn)~
用sleep會(huì)導(dǎo)致進(jìn)程睡眠,會(huì)影響當(dāng)前進(jìn)程的其它業(yè)務(wù)處理。如果這個(gè)進(jìn)程只負(fù)責(zé)一個(gè)柜子,那么沒有什么影響。
workerman的定時(shí)器也有延遲的效果,我覺得每個(gè)柜子一個(gè)定時(shí)器簡單些。如果你的定時(shí)器是動(dòng)態(tài)創(chuàng)建的,比如在柜子連接上來的時(shí)候創(chuàng)建,記得在連接斷開的時(shí)候刪除定時(shí)器。否則只創(chuàng)建定時(shí)器又不刪除會(huì)不斷占用內(nèi)存,導(dǎo)致內(nèi)存泄漏。