所在的公司是物联网公司,涉及到向设备发送指令,如今的问题是在和天猫语音对接的一个产品线上出现了一个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];
保持原子操做,效果到如今为止要好了些高并发
即便上面根据流程作了屡次修改,已经对接流程的修改,总之没有绝对的状况,都须要进行优化,并发测试测试