Статьи

Начало работы с облачными функциями Google и MongoDB

Эта статья была первоначально опубликована на Code Barbarian . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

Безсерверные архитектуры становятся все более популярными, и на то есть веские причины. По моему опыту, основанные на контейнерах структуры оркестровки имеют крутую кривую обучения и являются излишними для большинства компаний, работающих с потребителями. В архитектуре FaaS , такой как AWS Lambda и Azure Functions , теоретически единственными разработчиками, которые вам нужны, является пакетирование и загрузка вашего приложения.

В этой статье вы узнаете, как настроить облачную функцию Google в Node.js, которая подключается к MongoDB. Однако одним из основных ограничений функций без сохранения состояния является необходимость устанавливать отдельное соединение с базой данных каждый раз, когда выполняется функция без сохранения состояния, что влечет за собой значительное снижение производительности. К сожалению, я не смог выяснить, как повторно использовать соединение с базой данных в Google Cloud Functions, трюк, который работает для IBM Cloud , Azure Functions и AWS Lambda , не работает для Google Cloud Functions.

«Привет, мир» в облачных функциях Google

Перейдите на целевую страницу Google Cloud Functions и нажмите «Попробовать бесплатно».

Нажмите на значок гамбургера в левом верхнем углу и найдите ссылку «Облачные функции» на боковой панели, затем нажмите «Создать функцию».

Назовите вашу функцию «hello-world» и оставьте остальные параметры в форме «Create function» без изменений. Оставьте «Function to execute» как «helloWorld», потому что это должно соответствовать имени функции, которую экспортирует ваш код. Ниже приведен код, который вы должны ввести, чтобы вы могли подтвердить, на какой версии Node.js работает ваша функция.

exports.helloWorld = (req, res) => {
  res.send('Hello from Node.js ' + process.version);
};

Нажмите «Создать» и подождите, пока Google развернет вашу облачную функцию. Как только ваша функция развернута, нажмите на нее, чтобы отобразить детали функции.

Нажмите на вкладку «Триггер», чтобы найти URL своей облачной функции.

Скопируйте URL и используйте curl для запуска облачной функции.

 $ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Hello from Node.js v6.11.5
$

Облачные функции Google не дают вам никакого контроля над тем, какую версию Node.js вы используете, в настоящее время они запускают Node.js v6.11.5. Вы не можете использовать async / await изначально в облачных функциях Google на момент написания этой статьи.

Подключение к MongoDB Atlas

Нажмите на вкладку «Источник» в деталях функции и нажмите кнопку «Редактировать». Вы заметите, что в вашем исходном коде есть 2 файла, один из которых — package.json Отредактируйте package.json

 {
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
    "co": "4.6.0",
    "mongodb": "3.x"
  }
}

После повторного развертывания Google Cloud автоматически установит для вас зависимости npm. Теперь измените ваш index.jsuriMongoDB Atlas .

 const co = require('co');
const mongodb = require('mongodb');

const uri = 'ATLAS_URI_HERE';

exports.helloWorld = (req, res) => {
  co(function*() {
    const client = yield mongodb.MongoClient.connect(uri);

    const docs = yield client.db('test').collection('tests').find().toArray();
    res.send('Result: ' + JSON.stringify(docs));
  }).catch(error => {
    res.send('Error: ' + error.toString());
  });
};

Нажмите «Сохранить», чтобы развернуть вашу функцию. После развертывания вы сможете свернуть свою облачную функцию и получить документ из MongoDB Atlas .

 $ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}]
$

На этом этапе вы попытаетесь повторно использовать соединение с базой данных, используя тот же трюк с глобальным состоянием, который работает в AWS Lambda и других поставщиках облачных функций.

 const co = require('co');
const mongodb = require('mongodb');

const uri = 'ATLAS_URI_HERE';

// Other cloud providers would retain this, but not Google Cloud
let client = null;

exports.helloWorld = (req, res) => {
  co(function*() {
    const reusedConnection = client != null;
    if (client == null) {
      client = yield mongodb.MongoClient.connect(uri);   
    }

    const docs = yield client.db('test').collection('tests').find().toArray();
    res.send('Result: ' + JSON.stringify(docs) + ', Reused: ' + reusedConnection);
  }).catch(error => {
    res.send('Error: ' + error.toString());
  })
};

К сожалению, глобальная уловка состояния не работает в Google Cloud.

 $ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}], Reused: false
$
$ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}], Reused: false
$

Двигаться дальше

FaaS — это мощная парадигма, но функции, не имеющие состояния, страдают от ограничений производительности при работе с базами данных, поскольку создание нового подключения к базе данных является дорогостоящим. Большинство поставщиков облачных функций имеют механизм для сохранения соединений с базами данных между вызовами функций, но, очевидно, Google Cloud Functions этого не делает. Это серьезно ограничивает возможности Google Cloud Functions служить заменой обычного веб-сервера.