1. Введение



Eventarc упрощает подключение сервисов Cloud Run к событиям из различных источников. Он позволяет создавать управляемые событиями архитектуры, в которых микросервисы слабо связаны и распределены. Он позаботится о приеме событий, их доставке, безопасности, авторизации и обработке ошибок.
Рабочие процессы — это полностью управляемая платформа оркестрации, которая выполняет службы в заданном вами порядке: рабочий процесс. Эти рабочие процессы могут сочетать сервисы, размещенные в Cloud Run или Cloud Functions, облачные сервисы Google, такие как Cloud Vision AI и BigQuery, а также любой API на основе HTTP.
В этой лаборатории кода вы создадите управляемую событиями оркестрацию микросервисов для обработки изображений. Вы будете использовать рабочие процессы для координации порядка, входных и выходных данных 4 облачных функций обработки изображений. Затем вы включите оркестрацию для реагирования на события облачного хранилища, слабо связанную с Eventarc.
В конечном итоге вы получите гибкую, но структурированную бессерверную архитектуру для обработки изображений.

Что вы узнаете
- Обзор Eventarc и рабочих процессов
- Как развернуть сервисы облачных функций
- Как организовать сервисы с помощью рабочих процессов
- Как заставить рабочие процессы реагировать на события облачного хранилища с помощью Eventarc
2. Настройка и требования
Самостоятельная настройка среды
- Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .



- Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы можете обновить его в любое время.
- Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (нельзя изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Альтернативно, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага, и он останется в силе на протяжении всего проекта. - К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
- Далее вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить весь проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .
Запустить Cloud Shell
Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.
В Google Cloud Console щелкните значок Cloud Shell на верхней правой панели инструментов:

Подготовка и подключение к среде займет всего несколько минут. Когда все будет готово, вы должны увидеть что-то вроде этого:

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лаборатории кода можно выполнять в браузере. Вам не нужно ничего устанавливать.
Настройка gcloud
В Cloud Shell укажите идентификатор проекта и регион, в котором вы хотите развернуть приложение. Сохраните их как переменные PROJECT_ID и REGION . Доступные регионы см. в разделе «Местоположения облачных функций» .
PROJECT_ID=your-project-id gcloud config set project $PROJECT_ID
Получить исходный код
Исходный код приложения находится в папке processing-pipelines репозитория eventarc-samples .
Клонировать репо:
git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git
Перейдите в папку eventarc-samples/processing-pipelines :
cd eventarc-samples/processing-pipelines
3. Обзор архитектуры
Архитектура приложения следующая:

- Изображение сохраняется во входном сегменте, который генерирует событие создания Cloud Storage.
- Событие создания Cloud Storage считывается Eventarc через триггер Cloud Storage и передается в рабочие процессы как CloudEvent.
- На первом этапе рабочего процесса Filter , служба облачных функций, использует Vision API, чтобы определить, безопасно ли изображение. Если изображение безопасно, рабочие процессы продолжают выполнение следующих шагов.
- На втором этапе рабочего процесса Labeler , служба облачных функций, извлекает метки изображения с помощью Vision API и сохраняет метки в выходной сегмент.
- На третьем этапе Resizer , еще один сервис облачных функций, изменяет размер изображения с помощью ImageSharp и сохраняет изображение с измененным размером в выходной сегмент.
- На последнем этапе Watermarker , еще один сервис облачных функций, добавляет водяной знак меток из Labeler к изображению с измененным размером с помощью ImageSharp и сохраняет изображение в выходной сегмент.
Приложение запускается событием Cloud Storage, поэтому оно управляемо событиями. Обработка изображений происходит в рамках рабочего процесса, следовательно, это оркестровка. В конце концов, это управляемая событиями оркестровка для гибкой, но структурированной бессерверной архитектуры для обработки изображений.
4. Создайте сегменты
Создайте входную корзину, в которую пользователи смогут загружать изображения, и выходную корзину для конвейера обработки изображений, чтобы сохранять обработанные изображения.
Запустите в Cloud Shell следующее:
REGION=us-central1 BUCKET1=$PROJECT_ID-images-input BUCKET2=$PROJECT_ID-images-output gsutil mb -l $REGION gs://$BUCKET1 gsutil mb -l $REGION gs://$BUCKET2
5. Развертывание службы фильтрации
Начнем с развертывания первого сервиса. Этот сервис облачных функций получает информацию о сегменте и файле, определяет, безопасно ли изображение с помощью Vision API, и возвращает результат.
Сначала включите необходимые сервисы для Cloud Functions gen2 и Vision API:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ run.googleapis.com \ vision.googleapis.com
Внутри папки processing-pipelines верхнего уровня разверните службу:
SERVICE_NAME=filter gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --entry-point Filter.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp
После развертывания функции установите URL-адрес службы в переменной, он понадобится нам позже:
FILTER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
6. Развертывание службы маркировки
Второй сервис Cloud Functions получает информацию о сегменте и файле, извлекает метки изображения с помощью Vision API и сохраняет метки в выходной сегмент.
Внутри папки processing-pipelines верхнего уровня разверните службу:
SERVICE_NAME=labeler gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Labeler.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp
После развертывания функции установите URL-адрес службы в переменной, он понадобится нам позже:
LABELER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
7. Развертывание службы изменения размера
Этот сервис облачных функций получает информацию о сегменте и файле, изменяет размер изображения с помощью ImageSharp и сохраняет изображение в выходной сегмент.
Внутри папки processing-pipelines верхнего уровня разверните службу:
SERVICE_NAME=resizer gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Resizer.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp \ --timeout=120s
Обратите внимание на значение timeout , равное 2 минутам, чтобы дать функции изменения размера дополнительное время для обработки.
После развертывания функции установите URL-адрес службы в переменной, он понадобится нам позже:
RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
8. Развертывание службы водяных знаков
Эта служба облачных функций получает информацию о сегменте, файле и метках, считывает файл, добавляет метки в качестве водяного знака к изображению с помощью ImageSharp и сохраняет изображение в выходной сегмент.
Внутри папки processing-pipelines верхнего уровня разверните сервис:
SERVICE_NAME=watermarker gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Watermarker.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp
После развертывания функции установите URL-адрес службы в переменной, он понадобится нам позже:
WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
На этом этапе все четыре облачные функции должны быть развернуты и запущены:

9. Определите и разверните рабочий процесс
Используйте рабочие процессы, чтобы объединить службы фильтров, маркировки, изменения размера и водяных знаков в один рабочий процесс. Рабочие процессы будут организовывать вызов этих служб в том порядке и с заданными нами параметрами.
Сначала включите необходимые службы для рабочих процессов:
gcloud services enable \ workflows.googleapis.com \ workflowexecutions.googleapis.com
Определять
Рабочие процессы получают CloudEvent в качестве параметра. Это будет получено от Eventarc, как только мы создадим триггер. На первых двух шагах Workflows регистрирует событие и извлекает из него информацию о сегменте и файле:
main:
params: [event]
steps:
- log_event:
call: sys.log
args:
text: ${event}
severity: INFO
- extract_bucket_and_file:
assign:
- bucket: ${event.data.bucket}
- file: ${event.data.name}
На этапе filter рабочие процессы вызывают службу фильтрации, которую мы развернули ранее. Затем он регистрирует и проверяет безопасность файла:
- filter:
call: http.post
args:
url: FILTER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: filterResponse
- log_safety:
call: sys.log
args:
text: ${filterResponse.body.safe}
severity: INFO
- check_safety:
switch:
- condition: ${filterResponse.body.safe == true}
next: label
next: end
На этапе label рабочие процессы вызывают службу разметки и записывают ответ (3 верхних метки):
- label:
call: http.post
args:
url: LABELER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: labelResponse
На этапе resize рабочие процессы вызывают службу изменения размера и захватывают ответ (корзину и файл изображения с измененным размером):
- resize:
call: http.post
args:
url: RESIZER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: resizeResponse
На этапе watermark рабочие процессы вызывают службу водяных знаков с изображением измененного размера и метками и фиксируют результат (изображение с измененным размером и водяным знаком):
- watermark:
call: http.post
args:
url: WATERMARKER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${resizeResponse.body.bucket}
file: ${resizeResponse.body.file}
labels: ${labelResponse.body.labels}
result: watermarkResponse
На final этапе рабочие процессы возвращают код состояния HTTP от служб маркировки, изменения размера и водяных знаков:
- final:
return:
label: ${labelResponse.code}
resize: ${resizeResponse.code}
watermark: ${watermarkResponse.code}
Развертывать
Перед развертыванием рабочего процесса убедитесь, что URL-адреса служб заменены URL-адресами развернутых функций вручную или с помощью sed :
Внутри папки processing-pipelines верхнего уровня перейдите в папку image-v3 , где находится файл workflows.yaml :
cd image-v3/
Запустите sed , чтобы заменить URL-адреса-заполнители фактическими URL-адресами развернутых служб:
sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml
sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml
sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml
sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml
Разверните рабочий процесс:
WORKFLOW_NAME=image-processing
gcloud workflows deploy $WORKFLOW_NAME \
--source=workflow.yaml \
--location=$REGION
Через несколько секунд вы увидите рабочий процесс, развернутый в консоли:

10. Создать триггер
Теперь, когда рабочий процесс развернут, последним шагом является подключение его к событиям Cloud Storage с помощью триггера Eventarc.
Одноразовая настройка
Сначала включите необходимые службы для Eventarc:
gcloud services enable \ eventarc.googleapis.com
Создайте учетную запись службы, которую вы будете использовать в триггере Eventarc.
SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name="Eventarc trigger image processing service account"
Предоставьте роль workflows.invoker , чтобы учетную запись службы можно было использовать для вызова рабочих процессов из Eventarc:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/workflows.invoker \ --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
Предоставьте роль eventarc.eventReceiver , o учетную запись службы можно будет использовать в
Триггер облачного хранилища:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/eventarc.eventReceiver \ --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
Предоставьте роль pubsub.publisher учетной записи службы Cloud Storage. Это необходимо для триггера облачного хранилища Eventarc:
STORAGE_SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_ID)"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:$STORAGE_SERVICE_ACCOUNT \
--role roles/pubsub.publisher
Создавать
Выполните следующее, чтобы создать триггер. Этот триггер фильтрует события создания новых файлов из входного сегмента Cloud Storage и передает их в рабочий процесс, который мы определили ранее:
TRIGGER_NAME=trigger-image-processing gcloud eventarc triggers create $TRIGGER_NAME \ --location=$REGION \ --destination-workflow=$WORKFLOW_NAME \ --destination-workflow-location=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET1" \ --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
Вы можете видеть, что триггер создан и готов в разделе Eventarc Cloud Console:

11. Проверьте конвейер
Конвейер обработки изображений готов получать события из Cloud Storage. Чтобы протестировать конвейер, загрузите изображение во входной сегмент:
gsutil cp beach.jpg gs://$BUCKET1
Как только вы загрузите изображение, вы должны увидеть выполнение рабочих процессов в активном состоянии:

Примерно через минуту вы увидите, что выполнение выполнено успешно. Вы также можете увидеть ввод и вывод рабочего процесса:

Если вы перечислите содержимое выходного сегмента, вы должны увидеть изображение с измененным размером, изображение с измененным размером и водяным знаком, а также метки изображения:
gsutil ls gs://$BUCKET2 gs://$PROJECT_ID-images-output/beach-400x400-watermark.jpeg gs://$PROJECT_ID-images-output/beach-400x400.png gs://$PROJECT_ID-images-output/beach-labels.txt
Чтобы еще раз проверить, вы можете открыть изображение с измененным размером и водяным знаком, чтобы увидеть результат:

12. Поздравления
Поздравляем, вы завершили работу над кодом!
Что мы рассмотрели
- Обзор Eventarc и рабочих процессов
- Как развернуть сервисы облачных функций
- Как организовать сервисы с помощью рабочих процессов
- Как заставить рабочие процессы реагировать на события облачного хранилища с помощью Eventarc