детектор отказов gcp с облачными функциями - PullRequest
0 голосов
/ 04 августа 2020

Я новичок в облачной платформе Google, играю с iot-core, pub / sub и могу функционировать. Я хотел бы сделать простой детектор отказов для устройств, которые отправляют сообщения в облако с помощью pub / sub.

Для простоты я хотел бы напрямую использовать телеметрию в качестве контрольного сигнала, но у меня возникли некоторые проблемы собрать все вместе.

Я набросал этот код, что неверно, но я надеюсь, что это поможет понять, что я пытаюсь сделать. Идея состоит в том, чтобы захватывать сообщение телеметрии и сохранять соответствующий идентификатор каждый раз, когда приходит новое. Затем каждые 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 голосов
/ 05 августа 2020

Когда вы думаете о бессерверности в GCP, подумайте о без сохранения состояния: ваш экземпляр можно удалить в любое время, и не все запросы будут попадать в один и тот же экземпляр Cloud Functions (то же самое с Cloud Run и App Engine).

Это распространенная ошибка. Мы использовали для развертывания рабочей нагрузки постоянную, а не временную виртуальную машину.

Итак, ваша проблема в том, что вы не можете полагаться на свои глобальные переменные. Во-первых, у вас есть 2 функции

  • Одна запланирована каждые 10 минут
  • Одна, которая принимает сообщения IoT

В любом случае, это никогда не будет тот же экземпляр, потому что это не тот же сервис (те же облачные функции). Итак, результат сегодня должен быть следующим: все устройства не работают, верно?

Чтобы решить эту проблему, вам нужно где-то сохранить свои данные.

  • Сохраните данные в базе данных. Firestore или Datastore - хороший выбор, если количество устройств и сообщений ограничено: у вас есть бесплатные уровни 30 КБ записи в день (50 КБ чтения). Если у вас огромное количество устройств и сообщений, рекомендуется использовать BigTable. В середине вы можете использовать BigQuery для потоковой записи.
  • Просто регистрирует обмен данными с устройством.

В журнале, как и в случае с базой данных, вам просто нужно запросить, какие устройства имеют отправил сообщение и сравните его с вашим списком устройств, чтобы определить, какие из них не работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...