我是Google Cloud Platform的初学者,并且正在使用iot-core,pub / sub并可以运行。我想为通过pub / sub将消息发送到云的设备创建一个简单的故障检测器。
为简单起见,我想直接将遥测技术用作心跳,但将所有这些放在一起会遇到一些麻烦。
我已草绘了此代码,这是错误的,但希望可以帮助您了解我要执行的操作。 这个想法是捕获遥测消息并在每次新消息到来时保存相应的ID。然后,每隔10分钟检查一下以前是否还活着。
/* devices on system */
var alive = [1,2];
/* heartbeats */
var received = [];
/**
* Triggered from a message on a Cloud Pub/Sub topic.
*
* @param {!Object} event Event payload.
* @param {!Object} context Metadata for the event.
*/
exports.messagePubSub = (event, context) => {
// extract device id from message
const payload = Buffer.from(event.data, 'base64').toString();
const info = JSON.parse(payload);
const device = info.id;
// heartbeat
if (!received.includes(device){
received.push(device);
console.log('${device} is alive');
}
};
/**
* Triggered every 10 minutes
*/
exports.scheduledFunctionCrontab =
functions.pubsub.schedule('*/10 * * * *').onRun((context) => {
const topicName = "..."
// find dead devices
var deads = [];
for (i = 0; i < alive.length; i++) {
if (!received.includes(alive[i])){
deads.push(alive[i]);
delete alive[i];
}
}
// restore device
for (i = 0; i < received.length; i++) {
if (!alive.includes(received[i])){
alive.push(received[i]);
}
}
// build payload
const messageObj = {
data: {
deads: deads
}
};
const messageBuffer = Buffer.from(JSON.stringify(messageObj), 'utf8');
console.log(messageObj);
// publish failures
try {
await pubSubClient.topic(topicName).publisher().publish(messageBuffer);
console.log("Message sent!")
} catch (err) {
console.error(err);
return Promise.reject(err);
}
// reset
received = []
});
谢谢!
答案 0 :(得分:0)
在GCP上考虑无服务器时,请考虑无状态:您的实例可以随时删除,并且并非所有请求都将落在同一个Cloud Functions实例上(与Cloud Run和App Engine相同)。
这是一个常见的错误,我们曾经在永久性而非临时性的VM上部署工作负载
因此,您的问题是您不能依赖于全局变量。首先,您有2个功能
在任何情况下,它都不会是同一实例,因为它不是同一服务(相同的Cloud Functions)。因此,今天的结果应该是:所有设备都关闭了,对吧?
要解决这个问题,您必须将数据保留在某个地方。
使用日志和数据库一样,您只需查询哪些设备已发送消息,并将其与设备列表进行比较以检测哪些设备已死。