具有云功能的gcp故障检测器

时间:2020-08-04 19:11:57

标签: google-cloud-platform google-cloud-functions

我是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 = []
});

谢谢!

1 个答案:

答案 0 :(得分:0)

在GCP上考虑无服务器时,请考虑无状态:您的实例可以随时删除,并且并非所有请求都将落在同一个Cloud Functions实例上(与Cloud Run和App Engine相同)。

这是一个常见的错误,我们曾经在永久性而非临时性的VM上部署工作负载

因此,您的问题是您不能依赖于全局变量。首先,您有2个功能

  • 每10分钟安排一次
  • 一个接收物联网消息的人

在任何情况下,它都不会是同一实例,因为它不是同一服务(相同的Cloud Functions)。因此,今天的结果应该是:所有设备都关闭了,对吧?

要解决这个问题,您必须将数据保留在某个地方。

  • 将数据存储在数据库中。如果设备和消息的数量有限,则Firestore或Datastore是一个不错的选择:您有一个免费的层,每天写入30k(读取50k)。如果您有大量的设备和消息,BigTable将是推荐的解决方案。在中间,您可以在流式写入中使用BigQuery。
  • 仅记录设备通信。

使用日志和数据库一样,您只需查询哪些设备已发送消息,并将其与设备列表进行比较以检测哪些设备已死。