设备在线/离线状态的缓存方案

简介: 很多场景中,我们都需要查询设备是否在线,但POP API的访问频次受限,需要我们自己系统缓存设备状态

设备在线/离线状态缓存

很多场景中,我们都需要查询设备是否在线,但POP API的访问频次受限,需要我们自己系统缓存设备状态

技术方案

  1. 配置规则引擎监听设备状态变更消息,流转到函数计算FC
  2. 由于消息乱序,在函数计算对比表格存储/Redis中设备状态和当前状态的lastTime,存储最新的数据
  3. 业务系统从表格存储/Redis中快速查询设备当前在线/离线状态

1.设备在线/离线状态变更消息

当设备连接到IoT物联网平台,设备离线,在线状态变更会生成特定topic的消息,我们服务端可以通过订阅这个topic获得设备状态变更信息。

**

设备的在线/离线状态流转的Topic格式:

/as/mqtt/status/{productKey}/{deviceName}

payload数据格式:

{
    "status":"online|offline",
    "productKey":"pk13543",
    "deviceName":"dn1234",
    "time":"2018-08-31 15:32:28.205",
    "utcTime":"2018-08-31T07:32:28.205Z",
    "lastTime":"2018-08-31 15:32:28.195",
    "utcLastTime":"2018-08-31T07:32:28.195Z",
    "clientIp":"123.123.123.123"
}

参数说明:

参数 类型 说明
status String 设备状态,online上线,offline离线
productKey String 设备所属产品的唯一标识
deviceName String 设备名称
time String 此条消息发送的时间点,
lastTime String 状态最后变更时间
注:需要根据此时间排序,判断设备最终状态
clientIp String 设备公网出口IP

2.通过规则引擎流转设备状态

image.png


2.1 配置数据源

创建数据源

image.png

添加指定产品下全量设备的状态变化通知

image.png

配置完成

image.png


2.2 配置数据目的地:函数计算FC

创建目的地-数据流转函数计算操作界面

image.png

2.3 创建规则引擎,配置解析器脚本

创建云产品流转解析器

image.png

关联数据源

image.png

image.png


2.4 函数计算FC实现

nodejs实现代码参考:

由于消息乱序,需要对比表格存储/Redis中已存储的设备状态和当前状态的lastTime,找出最新状态存储到缓存中。

var TableStore = require('tablestore');
var options = {
    accessKeyId: '你的accessKeyId',
    accessKeySecret: '你的accessKeySecret',
}
var otsClient = new TableStore.Client({
    accessKeyId: options.accessKeyId,
    secretAccessKey: options.accessKeySecret,
    endpoint: '你的endpoint',
    instancename: '你的instancename',
    maxRetries: 20 //默认20次重试,可以省略这个参数。
});
var response = {
    isBase64Encoded: false,
    statusCode: 200
};
module.exports.handler = function(event, context, callback) {
    var eventJson = JSON.parse(event.toString());
    var deviceId = eventJson.deviceName;
    var productKey = eventJson.productKey;
    var lastTime = new Date(eventJson.lastTime);
    var params = {
        tableName: "device_status_table",
        primaryKey: [{ 'deviceId': deviceId },{'productKey': productKey}],
        maxVersions: 1
    };
    try {
        otsClient.getRow(params, function(err, data) {
            if (err) {
                response.body = { msg: 'error', code: 404 };
                callback(null, response);
                return;
            }
            //有数据,拿出来比较lastTime
            if (data.row.primaryKey) {
                var attributes = data.row.attributes;
                var dbTime = '';
                attributes.forEach(function(item) {
                    if (item.columnName == 'lastTime') {
                        dbTime = new Date(item.columnValue);
                    }
                })
                //转换成毫秒进行比较
                if (lastTime.getTime() < dbTime.getTime()) {
                    return;
                }
            }
            var iot_data = {
                tableName: "device_status_table",
                condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
                primaryKey: [{ "deviceId": deviceId },{'productKey': productKey}],
                attributeColumns: [
                    { 'lastTime': eventJson.lastTime },
                    { 'clientIp': eventJson.clientIp },
                    { 'status': eventJson.status }
                ],
                returnContent: { returnType: TableStore.ReturnType.Primarykey }
            }
            otsClient.putRow(iot_data, function(err, data) {
                if (err) {
                    response.body = { msg: 'error', code: 404 };
                    callback(null, response);
                    return;
                }
                response.body = { msg: 'ok', code: 200 };
                callback(null, response);
                return;
            });
        });
    } catch (err) {
        response.body = { msg: 'error', code: 404 };
        callback(null, response);
    }
};

2.4 表格存储OTS

在device_status_table表中,查看设备上下线情况


【往期回顾】

1、IoT 设备发送 MQTT 请求的曲折经历

2、20元体 Arduino 环境监测仪开发

3、智能手持测温枪开发实践

4、JMeter 压测 MQTT 服务性能实战

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
2月前
|
缓存 NoSQL Java
SpringBoot实现缓存预热的几种常用方案
SpringBoot实现缓存预热的几种常用方案
|
2月前
|
缓存 NoSQL Java
聊聊分布式应用中的缓存方案(一)
聊聊分布式应用中的缓存方案(一)
75 0
|
20天前
|
缓存 NoSQL Java
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
62 5
|
19天前
|
缓存 监控 NoSQL
SpringBoot配置第三方专业缓存技术jetcache方法缓存方案
SpringBoot配置第三方专业缓存技术jetcache方法缓存方案
50 1
|
2月前
|
缓存 数据库 NoSQL
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?--主从切换方案
【5月更文挑战第16天】该方案提出了解决Redis缓存穿透、击穿和雪崩问题的策略。通过使用两个或多个互为备份的Redis集群,确保在单个集群故障时,另一个可以接管。在故障发生时,业务会与备用集群保持心跳检测,并根据业务重要性分批转移流量,逐步增加对备用集群的依赖,同时监控系统稳定性。对于成本敏感的小型公司,可以采用低成本的单机或小规模自建Redis备份。此方案强调渐进式流量转移,以保护系统免受突然压力冲击。
31 1
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?--主从切换方案
|
19天前
|
存储 缓存 NoSQL
SpringBoot配置第三方专业缓存技术jetcache远程缓存方案和本地缓存方案
SpringBoot配置第三方专业缓存技术jetcache远程缓存方案和本地缓存方案
23 0
|
1月前
|
canal 缓存 关系型数据库
高并发场景下,6种方案,保证缓存和数据库的最终一致性!
在解决缓存一致性的过程中,有多种途径可以保证缓存的最终一致性,应该根据场景来设计合适的方案,读多写少的场景下,可以选择采用“Cache-Aside结合消费数据库日志做补偿”的方案,写多的场景下,可以选择采用“Write-Through结合分布式锁”的方案,写多的极端场景下,可以选择采用“Write-Behind”的方案。
208 0
|
2月前
|
存储 缓存 NoSQL
【技术分享】求取列表需求的redis缓存方案
【技术分享】求取列表需求的redis缓存方案
53 0
|
2月前
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
42 0
|
2月前
|
缓存 NoSQL 前端开发
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
78 0