Эффективно структурируйте, тестируйте, повторно тестируйте и развертывайте Google Cloud Functions

Эта статья является частью серии из 4 статей, в которых я даю различные советы по разработке Google Cloud Functions. Эта работа является результатом двухлетней ежедневной практики, развертывания и мониторинга. Некоторые из этих лучших практик взяты непосредственно из официальной документации, другие — из моего опыта, которые оказались наиболее эффективными. Для любой другой точки зрения, не стесняйтесь комментировать эту (бесплатную) статью. Спасибо!

Рекомендации по использованию облачных функций (2/4): оптимизация облачных функций ›››

Рекомендации по использованию облачных функций (3/4): защита облачных функций ›››

Рекомендации по работе с облачными функциями (4/4): отслеживание и регистрация выполнения ›››

Подготовьте среду Google Cloud Functions

Онлайн-уроки крутые, мои даже супер крутые! ;) С кучей статей каждый может узнать как использовать Secret Manager в облачных функциях Google, как защитить облачные функции Google, как ограничить их скорость, как использовать облачное хранилище, Cloud Pub /Sub и всевозможные инструменты.

Но,

У него есть большой недостаток ⇒ Учебники сделаны для одной, короткой, конкретной темы.

А бизнес-проекты совсем не короткие и конкретные.

Бизнес-проекты объединяют несколько облачных функций с использованием различных инструментов, которые необходимо опробовать, протестировать и отладить, надеюсь, эффективно.

Как это сделать, не объясняется в руководствах по отдельным функциям.

Об этом я расскажу в этой первой статье ⇒ Подготовьте среду Google Cloud Functions, чтобы обеспечить управление несколькими облачными функциями, а также эффективное тестирование и отладку.

1 функция ‹› 1 папка и 1 функция ‹› 1 файл

После нескольких месяцев использования Google Cloud Functions легко влюбиться и развернуть дюжину.

Эти GCF необходимо будет развернуть, отправить в Git, задокументировать и использовать другими пользователями.

Очень важно иметь четкую и эффективную структуру.

Неверная структура

Ошибка новичка, которую я видел несколько раз, заключается в том, чтобы поместить все облачные функции Google в одну папку, создать большой README и отправить все это в Git.

Структура будет выглядеть так (python):

Это работает! Здесь нет ничего плохого, это работает для 1-2-3 облачных функций, написанных на одном языке.

Это проблематично по трем причинам, но приемлемо для 3 функций:

  • requirements.txt будет включать в себя пакеты, которые используются всеми функциями. Если функции_2 нужен конкретный пакет, функциям_1 и функция_3 также потребуется его импортировать.
  • README.md — это документация по 3 функциям
  • невозможно иметь nodejs, python и функцию Go в одной папке

Хорошая структура

Вместо этого я предлагаю эту структуру, не имеющую ни одного из предыдущих недостатков:

  • Используйте 1 папку для каждой функции Google Cloud.
  • Добавить 1 README.md в каждую папку
  • Добавьте 1 requirements.txt или любой package.json для каждой функции Google Cloud.

Не забывайте про саму функцию ;)

Разделение кода

Несколько раз я видел функцию, разделенную на несколько файлов, файл utils, файл конфигурации… очевидно, для ясности. Почему нет. Но Google Cloud Functions были разработаны для конкретных задач и коротких функций. ⇒ Если код настолько длинный, что его нужно разделить на несколько файлов, возможно, Google Cloud Functions не подходит.

игнорировать gcloud

Если мы примем предыдущую структуру (а мы должны!) и развернем функцию с помощью командной строки, мы увидим файл README.md в Google Cloud Functions. Мы этого не хотим. Это бесполезный файл, который не нужно развертывать.

Мы можем просто добавить файл .gcloudignore в каждую папку, этот файл включает себя и файл README.

README.md
.gcloudignore

Окончательная структура выглядит так:

С помощью этого простого изменения структуры я мог:

  • Создайте js GCF и py GCF в одном репозитории Github.
  • Иметь отдельные пакеты для определенных функций
  • Имейте разные README для каждой функции

Эта структура предложена Google Cloud в их образце Google Cloud Function Репозиторий Github. Они даже создают подпапку для добавления файла функции. Честно говоря, я не знаю, почему они зашли так далеко 😀

И последнее, но не менее важное → Github

Как только эта структура настроена, легко поддаться искушению просто отправить обновление на github, например, «обновить ссылку на изображение», «обновить файл readme»…

Это то, что они делают в образце репозитория GCF Github:

No

Предложенная ранее структура смешивает множество функций и множество проектов, и такой способ коммита не помогает команде увидеть текущие проекты.

Я предлагаю включать имя функции в каждый коммит Github, например: «функция_1: добавить имя атрибута», «функция_2: рефакторинг кода»…

Таким образом, легче увидеть, что было недавно разработано, текущие проекты…

Надеюсь увидеть изменения в ваших коммитах, разработчики Google;)

Сначала не используйте облачные функции Google.

После изучения руководств по GCF нормальным рефлексом будет продолжать разработку, используя саму среду Cloud Function, развертывая ее после каждого обновления.

Это не очень хорошая идея.

Учебники делятся чистым кодом, проверенным много раз. Но когда нормальные разработчики кодируют, они ожидают, что чистый код будет работать должным образом на первой итерации… Честно говоря, такого никогда не бывает.

Не рекомендуется развертывать GCF для каждого изменения кода, потому что развертывание GCF занимает время, до 2 минут. Плюс время тестирования, плюс время ожидания появления логов, от обновления до результата легко проходит 5 минут, это огромно!

Хороший разработчик всегда забудет [, или “, или галочку. Нет ничего более неприятного, чем «Ошибка KeyValue» после нескольких минут ожидания.

Развертывание должно использоваться только в самом конце, когда GCF готов к развертыванию. Когда все было проверено на месте.

Что я всегда делаю, когда начинаю новый проект для облачной функции, так это открываю Jupyter Notebook, кодирую все, структурирую свой код, выполняю все необходимые тесты и проверки.

Как только я смогу выполнить весь мой код в одной ячейке блокнота…

Не время развертывать…

Время для…

Во-вторых, используйте functions-framework

Код чист, пора запускать функцию. Но перед его развертыванием Google предоставляет эмулятор для локального запуска функции.

Functions-framework — это фреймворк, который запускает локальный сервер разработки для быстрого тестирования.

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

Когда запускается команда functions-framework, она имитирует сервер и дает локальный адрес для вызова функции.

Позвольте мне объяснить процесс для Python GCF:

  • Сначала в репозитории GCF установите functions_framework:
pip install functions-framework
  • Во-вторых, создайте папку test_functions_framework и включите в нее все файлы, о которых мы говорили ранее, папка теперь имеет следующую структуру:
.
├── .gcloudignore
├── README.md
├── main.py
└── requirements.txt
  • В requirements.txt добавьте эту строку:
flask
  • В main.py добавьте этот простой код:
from flask import Response
import uuid

def main(request):

    try:

        print("I was called !", uuid.uuid4())

        return Response(response = 'ok', status = 200)
                
    except Exception as e:
        print("ERROR ", e)
        return Response(response = 'AN ERROR OCCURED', status = 400)
  • В папке test_functions_framework мы можем запустить functions-framework с помощью этой команды:
functions-framework --target=main --debug
  • Он дает нам адрес локального хоста, который мы можем просто пропинговать, он напрямую дает все журналы и результат, как если бы он был развернут в сети.

Все готово к развертыванию!

Последняя причина сбоя

Функция чиста и протестирована, работа почти завершена, но все еще есть вероятность, что она выйдет из строя после развертывания.

Из-за аутентификации.

Есть вероятность, что ваша функция взаимодействует с объектами Google Cloud (Secret Manager, Pub/Sub, Bigquery…)

Во время разработки вы, вероятно, использовали учетную запись службы или собственные учетные данные для доступа к этим службам.

Но после развертывания облачные функции не имеют такого же доступа.

Есть две возможности:

Во время развертывания вы можете указать учетную запись службы, которая должна использоваться функциями

Если нет, Cloud Functions использует учетную запись службы по умолчанию в качестве идентификатора для выполнения функции:

  • Облачные функции (1-го поколения) используют учетную запись службы App Engine по умолчанию, [email protected].
  • Облачные функции (2-го поколения) используют учетную запись службы вычислений по умолчанию — [email protected].

Убедитесь, что эти учетные записи служб имеют доступ к ресурсам, необходимым для функции.

Теперь нет причин для сбоя функции. Если он разбился, оставьте комментарий и укажите причину.

Ты готов к развертыванию, падаван!

Наконец, разверните! С помощью командной строки!

Я бы сказал, что более 80% руководств по Google Cloud Functions объясняют, как развернуть экземпляр с помощью пользовательского интерфейса.

Оно работает.

Но если вы дошли до этого момента, вы сейчас осваиваете Google Cloud Functions и у вас нет времени нажимать 3-4 кнопки, ждать загрузки пользовательского интерфейса и развертывания функции.

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

"Жизнь слишком коротка, чтобы учить немецкий и разворачивать функцию вручную". однажды сказал великий человек

Потратьте 5 минут на установку gcloud SDK и запустите команду развертывания из терминала.

Развёртывание займёт 2 минуты, а пока можно 50 раз хлопнуть этой статье ;)

Не забудьте сохранить код перед запуском команды deploy! ;)

Развертывание функций, инициируемых функциями http (python)

gcloud functions deploy your-function  --region=us-central1  --entry-point main --runtime python310 --trigger-http --no-allow-unauthenticated

Развертывание функций, запускаемых Pub/Sub (узлы с более длительным временем ожидания)

gcloud functions deploy your-function  --runtime nodejs14 --memory=128MB --timeout=200s --region=europe-west2 --trigger-topic=your-function

Чтобы увидеть больше, проверьте документацию по развертыванию

Еще один хороший совет — автоматизировать развертывание из исходного репозитория: каждый раз, когда вы отправляете на GitHub, функция развертывается в Cloud Functions.

Бон… Мне это не очень нравится, потому что это означает отправку кода на Github, который не был протестирован вживую.

Следующие части:

Рекомендации по использованию облачных функций (2/4): оптимизация облачных функций ›››

Рекомендации по использованию облачных функций (3/4): защита облачных функций ›››

Рекомендации по работе с облачными функциями (4/4): отслеживание и регистрация выполнения ›››

Спасибо, что читаете, спасибо, что аплодируете мне, спасибо, что следите за мной!

Не забывайте быть крутым.