所在的公司是物聯網公司,涉及到向設備發送指令,如今的問題是在和天貓語音對接的一個產品線上出現了一個bugphp
啓用組合指令模式,例如一個情景模式,一、開臥室燈、2開走廊燈、3開客廳燈
開關面板
,面板上面是一個三路開關
,也就是每個燈對應一個開關,以下圖:
當天貓精靈一條控制指令發送過來,我在將指令發送給設備,流程圖以下
上面能夠看到整個流程,包括天貓語音觸發應用雲到下發控制指令的過程,
那幾乎能夠把重點鎖定在下發參數上面redis
1 1 1
二進制位,公司最可能是8路開關0 0 0 0 0 1 0 0
上面也看到了,在下發控制指令的時候會將 其餘開關位的狀態也帶上。緩存
會去查下其餘開關位的狀態
到這裏來看,幾乎也不會出現啥問題,接下來咱們就要直面真正遇到的問題
上面的例子都是單次請求,由於同一個面板的不一樣開關位雖然會依賴設備更新緩存,可是單次控制佔時仍是沒有問題的,也就是用戶觸發天貓控制燈的時候都是一個一個控制的併發
可是如今引入了場景,也就是天貓精靈上面有場景模式,例如設置場景
回家了
,那麼就是三路開關上全部的燈都要打開全部的燈,!並且天貓精靈是併發處理的,也就是會把三個請求同時發送到應用雲上,而後應用雲在下發控制指令。
那麼問題來了,三次請求之間都是有依賴關係的
也就是不用去查詢設備的緩存,直接採用臨時緩存 ,時間1-2s,當併發的三個請求同時到來時,直接存儲一個臨時值,告訴其餘請求針對要控制的面板有其餘開關在控制
服務端採用的sowole進程模型 //採用hash結構,每個案件對應一個key值, //每個按鍵的請求到來時更新hashkey時間爲1s $redis->hset("concurrent_control_hash_off".$devSn,$keynum,1); $redis->expire("concurrent_control_hash_off".$devSn,1); //直接從臨時緩存裏獲取,若是沒有在去設備緩存裏獲取 $res = $redis->hGetAll("concurrent_control_hash_off".$devSn);
也就是當併發請求的時候每條redis指令沒有順序
$redis->multi(); $redis->hset("concurrent_control_hash_on".$devSn,$keynum,1); $redis->expire("concurrent_control_hash_on".$devSn,1); $redis->hGetAll("concurrent_control_hash_on".$devSn); $res = $redis->exec(); $concurrentArr = $res[2];
保持原子操做,效果到如今爲止要好了些高併發
即便上面根據流程作了屢次修改,已經對接流程的修改,總之沒有絕對的狀況,都須要進行優化,併發測試測試