ПР. Проверка доступности
Кратко:
- Создание функции для проверки доступности сайта ya.ru и измерения времени ответа.
- Подключение к управляемой базе данных PostgreSQL через функцию Cloud Functions.
- Создание таблицы для хранения результатов проверки доступности сайта.
- Подключение к базе данных PostgreSQL через подключение к функции Cloud Functions.
- Создание триггера-таймера для проверки доступности сайта с помощью cron-выражения.
- Удаление триггера-таймера после завершения практической работы.
- Использование созданного кластера PostgreSQL для последующих практических работ.
Практическая работа. Проверка доступности
На этом практическом занятии вы создадите функцию для проверки доступности сайта ya.ru, которая будет измерять время ответа. Результаты работы функции будут передаваться в базу данных сервиса Yandex Managed Service for PostgreSQL с использованием подключения к управляемой БД из функции. Также вы запустите триггер-таймер, который будет регулярно производить опрос сайта ya.ru.
Шаг 1. Дополнительная роль для сервисного аккаунта
В предыдущих практических работах вы создали сервисный аккаунт с именем
service-account-for-cf
, назначили ему роли editor
и storage.editor
и создали ключ доступа. Чтобы подключаться к управляемым БД из функции, нужно добавить сервисному аккаунту роль serverless.mdbProxies.user
.Для этого выполните следующую команду:
yc resource-manager folder add-access-binding $FOLDER_ID \
--role serverless.mdbProxies.user \
--subject serviceAccount:$SERVICE_ACCOUNT_ID
Шаг 2. Создание базы данных
Создание кластера PostgreSQL
Конечно, кластер PostgreSQL можно создать с помощью консоли управления, но в этой практической работе мы используем CLI. Прежде всего, давайте определим подсеть, в которой будет расположен кластер. Разместим кластер в зоне
ru-central1-c
и с помощью следующей команды узнаем идентификатор(ID
) соответствующей подсети:
yc vpc subnet list
Создадим кластер версии PostgreSQL
15
с именем my-pg-database
. Установим тип хоста burstable c3-c2-m4
— это самый дешёвый и простой вариант хоста. Из-за невысокой производительности он подходит только для тестовых целей. Используем для хоста жёсткий диск (HDD) размером 10 ГБ.Сразу создадим пользователя с именем
user1
и паролем user1user1
, а также базу данных db1
. Для удобства администрирования откроем доступ из консоли управления. Используйте опцию websql-access
— это позволит выполнять SQL-запросы прямо в консоли управления. Чтобы открыть возможность подключения к PostgreSQL из функции, необходимо подключить опцию serverless-access
.Следующая команда за несколько минут создаст кластер PostgreSQL (не забудьте подставить идентификатор вашей подсети):
yc managed-postgresql cluster create \
--name my-pg-database \
--description 'For Serverless' \
--postgresql-version 15 \
--environment production \
--network-name default \
--resource-preset c3-c2-m4 \
--host zone-id=ru-central1-c,subnet-id=<идентификатор_подсети> \
--disk-type network-hdd \
--disk-size 10 \
--user name=user1,password=user1user1 \
--database name=db1,owner=user1 \
--websql-access \
--serverless-access
После успешного создания кластера проверьте результат:
yc managed-postgresql cluster list
yc managed-postgresql cluster get <имя или идентификатор кластера>
Создание таблицы для хранения данных
При создании кластера мы использовали опцию
websql-access
, что открывает нам возможности по исполнению SQL-команд в консоли управления. Воспользуемся этим и сделаем таблицу в созданной нами базе данных. В эту таблицу мы будем складывать результаты выполнения функции. В консоли управления перейдите в каталог, в котором создан кластер PostgreSQL. Откройте сервис Managed Service for PostgreSQL и перейдите в кластер my-pg-database
.В боковом меню перейдите на вкладку SQL. Для базы данных
db1
введите имя user1
и пароль user1user1
, нажмите кнопку Подключиться.
В открывшемся окне введите SQL-запрос и исполните его:
CREATE TABLE measurements (
result integer,
time float
);

Успешное выполнение команды создаст таблицу, куда мы будем складывать результаты.
Шаг 3. Подключение к управляемой БД из функции
Создание подключения
В консоли управления перейдите в каталог, в котором хотите создать подключение. Откройте сервис Cloud Functions. В боковом меню перейдите на вкладку Подключения к БД. Нажмите кнопку Создать подключение.

- Введите имя, описание подключения и в выпадающем списке выберите тип подключения —
PostgreSQL
. - Укажите кластер —
my-pg-database
. - Укажите базу данных —
db1
. - Введите данные пользователя БД: имя
user1
и парольuser1user1
. - Нажмите кнопку Создать.

Выберите созданное подключение. На вкладке Обзор скопируйте параметры
Идентификатор
и Точка входа
. Они будут использованы в функции на следующем шаге.
Шаг 4. Создание функции
Перед созданием функции определите переменные для инициации подключения:
CONNECTION_ID
— идентификатор подключения, DB_USER
— имя пользователя БД, DB_HOST
— точка входа. Используйте следующие команды:
echo "export CONNECTION_ID=<CONNECTION_ID>" >> ~/.bashrc && . ~/.bashrc
echo "export DB_USER=<DB_USER>" >> ~/.bashrc && . ~/.bashrc
echo "export DB_HOST=<DB_HOST>" >> ~/.bashrc && . ~/.bashrc
Они будут использованы в функции
function-for-postgresql.py
. Код функции:
import datetime
import logging
import requests
import os
#Эти библиотеки нужны для работы с PostgreSQL
import psycopg2
import psycopg2.errors
CONNECTION_ID = os.getenv("CONNECTION_ID")
DB_USER = os.getenv("DB_USER")
DB_HOST = os.getenv("DB_HOST")
# Настраиваем функцию для записи информации в журнал функции
# Получаем стандартный логер языка Python
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Вычитываем переменную VERBOSE_LOG, которую мы указываем в переменных окружения
verboseLogging = eval(os.environ['VERBOSE_LOG']) ## Convert to bool
#Функция log, которая запишет текст в журнал выполнения функции, если в переменной окружения VERBOSE_LOG будет значение True
def log(logString):
if verboseLogging:
logger.info(logString)
#Запись в базу данных
def save(result, time, context):
connection = psycopg2.connect(
database=CONNECTION_ID, # Идентификатор подключения
user=DB_USER, # Пользователь БД
password=context.token["access_token"],
host=DB_HOST, # Точка входа
port=6432,
sslmode="require")
cursor = connection.cursor()
postgres_insert_query = """INSERT INTO measurements (result, time) VALUES (%s,%s)"""
record_to_insert = (result, time)
cursor.execute(postgres_insert_query, record_to_insert)
connection.commit()
# Это обработчик. Он будет вызван первым при запуске функции
def entry(event, context):
#Выводим в журнал значения входных параметров event и context
log(event)
log(context)
# Тут мы запоминаем текущее время, отправляем запрос к ya.ru и вычисляем время выполнения запроса
try:
now = datetime.datetime.now()
#здесь указано два таймаута: 1c для установки связи с сервисом и 3 секунды на получение ответа
response = requests.get('https://ya.ru', timeout=(1.0000, 3.0000))
timediff = datetime.datetime.now() - now
#сохраняем результат запроса
result = response.status_code
#если в процессе запроса сработали таймауты, то в результат записываем соответствующие коды
except requests.exceptions.ReadTimeout:
result = 601
except requests.exceptions.ConnectTimeout:
result = 602
except requests.exceptions.Timeout:
result = 603
log(f'Result: {result} Time: {timediff.total_seconds()}')
save(result, timediff.total_seconds(), context)
#возвращаем результат запроса
return {
'statusCode': result,
'headers': {
'Content-Type': 'text/plain'
},
'isBase64Encoded': False
}
Перейдем в директорию с кодом функции и создадим нашу функцию
function-for-postgresql
. При этом сразу зададим все необходимые переменные и сервисный аккаунт:
yc serverless function create \
--name function-for-postgresql \
--description "function for postgresql"
yc serverless function version create \
--function-name=function-for-postgresql \
--memory=256m \
--execution-timeout=5s \
--runtime=python37 \
--entrypoint=function-for-postgresql.entry \
--service-account-id $SERVICE_ACCOUNT_ID \
--environment VERBOSE_LOG=True \
--environment CONNECTION_ID=$CONNECTION_ID \
--environment DB_USER=$DB_USER \
--environment DB_HOST=$DB_HOST \
--source-path function-for-postgresql.py
Проверим работоспособность функции:
yc serverless function version list --function-name function-for-postgresql
yc serverless function invoke --name function-for-postgresql
Успешный вызов функции приведёт к измерению времени ответа сайта и формированию записи в базе данных.
Шаг 5. Создание триггера
Создание триггера-таймера
Проверять доступность сайта лучше в автоматическом режиме через равные промежутки времени. Для этой задачи создайте триггер-таймер. Он будет использовать cron-выражения:
yc serverless trigger create timer \
--name trigger-for-postgresql \
--invoke-function-name function-for-postgresql \
--invoke-function-service-account-id $SERVICE_ACCOUNT_ID \
--cron-expression '* * * * ? *'
Cron-выражение
* * * * ? *
означает вызов функции function-for-postgresql
один раз в минуту. Успешное выполнение функции раз в минуту будет создавать запись в базе данных, в чём вы можете убедиться, просмотрев записи в таблице.Убедились? Поздравляем: вы успешно создали функцию, которая через заданный промежуток времени выполняется по триггеру, чтобы проверить доступность ya.ru и записать результат проверки в базу данных.
Удаление триггера-таймера
После завершения практической работы не забудьте удалить созданный триггер
trigger-for-postgresql
, иначе он будет продолжать работать:
yc serverless trigger delete trigger-for-postgresql
Поздравляем, вы успешно закончили вторую тему. Пройдите короткий тест — и мы перейдём к изучению сервиса API Gateway.
Не удаляйте созданный кластер PostgreSQL, он понадобится для следующей практической работы.