1. Прежде чем начать
Query Insights for Cloud SQL помогает обнаруживать, диагностировать и предотвращать проблемы с производительностью запросов к базам данных Cloud SQL. Он обеспечивает самообслуживание, интуитивно понятный мониторинг и диагностическую информацию, выходящую за рамки обнаружения, и помогает вам определить основную причину проблем с производительностью.
В этой лабораторной работе вы узнаете, как настроить экземпляр Cloud SQL для PostgreSQL, развернуть приложение Node.js, чтобы использовать экземпляр Cloud SQL в качестве внутреннего хранилища, а затем использовать Query Insights для просмотра и мониторинга запросов.
Предварительные условия
- Базовое знание языка программирования и инструментов Node.js.
Что ты будешь делать
- Используйте Cloud SQL в приложении Node.js.
- Включите SQL Commenter в приложении Node.js.
- Используйте Query Insights для Cloud SQL, чтобы отслеживать и исследовать производительность запросов.
Что вам понадобится
- Учетная запись Google Cloud, в которой у вас есть разрешения на включение API и создание сервисов.
2. Настройка и требования
Самостоятельная настройка среды
- Войдите в Cloud Console и создайте новый проект или повторно используйте существующий. (Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .)
Запомните идентификатор проекта, который вы используете. Позже в этой лаборатории он будет называться PROJECT-ID
.
- Далее вам необходимо включить биллинг в Cloud Console, чтобы использовать ресурсы Google Cloud.
Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Обязательно следуйте всем инструкциям в разделе «Очистка и дополнительная информация», в котором рассказывается, как отключить ресурсы, чтобы не взимать плату за вычеты, выходящие за пределы этого руководства. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .
Активировать Cloud Shell
- В Cloud Console нажмите «Активировать Cloud Shell» .
Если вы никогда раньше не запускали Cloud Shell, вам будет представлен промежуточный экран (ниже сгиба) с описанием того, что это такое. В этом случае нажмите «Продолжить» (и вы больше никогда его не увидите). Вот как выглядит этот одноразовый экран:
Подготовка и подключение к Cloud Shell займет всего несколько минут.
Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию.
- Выполните следующую команду в Cloud Shell, чтобы убедиться, что вы используете правильный проект:
После подключения к Cloud Shell вы увидите, что вы уже прошли аутентификацию и что для проекта уже установлен идентификатор вашего проекта.
Выполните следующую команду, чтобы убедиться, что вы используете правильный проект.
gcloud config list project
Если вы хотите использовать проект, отличный от того, который вы выбрали при открытии Cloud Shell, вы можете создать новый, выполнив:
gcloud config set project <PROJECT-ID>;
3. Настройте экземпляр Cloud SQL для PostgreSQL с включенной функцией Query Insights.
- После запуска Cloud Shell вы можете использовать командную строку для создания нового экземпляра Cloud SQL с именем
my-instance
с включенной функцией Query Insights:
gcloud sql instances create my-instance --tier db-f1-micro --database-version=POSTGRES_12 --region=us-central --root-password=<PASSWORD> --insights-config-query-insights-enabled --insights-config-record-application-tags --insights-config-record-client-address
Вот краткое объяснение флагов и их значения:
- Флаг
--tier db-f1-micro
указывает тип машины с минимальными ресурсами, поскольку это предназначено для целей разработки, и вам не нужно много ресурсов для лаборатории кода. Подробнее об уровнях можно узнать здесь . - Флаг
--database-version=POSTGRES_12
создает экземпляр PostgreSQL версии 12. - Флаг
--region=us-central
указывает регион, в котором будет создан экземпляр. - Флаг
--root-password=<PASSWORD>
позволяет указать пароль для root-пользователяpostgres
. Обязательно замените <ПАРОЛЬ> паролем по вашему выбору. - Флаг
--insights-config-query-insights-enabled
включает Query Insights в вашем экземпляре. - Флаг
--insights-config-record-application-tags
позволяет записывать теги приложения. Подробнее о тегах приложений вы узнаете в следующих разделах. - Флаг
--insights-config-record-client-address
позволяет записывать IP-адреса клиентов с помощью Query Insights.
Вам может быть предложено включить API sqladmin.googleapis.com для вашего проекта. Если вам будет предложено, выберите y
чтобы включить API.
Создание экземпляра займет несколько минут. После завершения этой операции ваш экземпляр будет готов к использованию.
- Теперь создайте базу данных, которую вы будете использовать для примера приложения:
gcloud sql databases create votesdb --instance my-instance
Вы также можете получить доступ к экземпляру и настроить его через Cloud Console .
- Получите имя подключения экземпляра в формате
PROJECT-ID:ZONE-ID:INSTANCE-ID
выполнив следующую команду. Вы будете использовать это позже при настройке приложения Node.js.
gcloud sql instances describe my-instance | grep connectionName
4. Создайте учетную запись службы для использования с приложением.
Учетные записи служб используются для предоставления разрешений на использование различных служб в вашем проекте GCP. Для этой лаборатории кода вам понадобится один из них, чтобы предоставить прокси-серверу Cloud SQL разрешение на подключение к вашему экземпляру Cloud SQL.
Создайте учетную запись службы в консоли.
- Перейдите на страницу учетных записей службы IAM и нажмите кнопку кнопка вверху страницы.
- Присвойте своей учетной записи службы уникальное имя и идентификатор и нажмите СОЗДАТЬ .
- На следующей странице щелкните раскрывающийся список «Выберите роль». Отфильтруйте «Cloud SQL» и выберите роль Cloud SQL Client. Нажмите ПРОДОЛЖИТЬ , а затем нажмите ГОТОВО .
- После создания учетной записи службы щелкните три точки в разделе «Действия для вашей новой учетной записи службы» и выберите «Управление ключами». На следующей странице выберите «ДОБАВИТЬ КЛЮЧ» , а затем «Создать новый ключ» . JSON будет выбран; сохраните это значение по умолчанию и нажмите CREATE . Будет загружен файл закрытого ключа .json. Нажмите ЗАКРЫТЬ .
- В Cloud Shell щелкните три точки в меню «Дополнительно» и выберите «Загрузить файл» . Перейдите к файлу .json, который вы скачали на свой локальный компьютер, и выберите его. При этом файл .json будет загружен в ваш домашний каталог Cloud Shell.
5. Установите и запустите прокси-сервер Cloud SQL.
Вы будете использовать прокси-сервер Cloud SQL для связи между приложением и экземпляром базы данных.
- Загрузите прокси-сервер Cloud SQL. В Cloud Shell вы можете запустить:
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && chmod +x cloud_sql_proxy
- Запустите прокси-сервер следующим образом, заменив
<INSTANCE_CONNECTION_NAME>
именем подключения экземпляра, которое вы скопировали со страницы обзора экземпляра Cloud SQL.
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:5432 &
Если это удалось, вы должны увидеть несколько строк вывода, заканчивающихся сообщением Ready for new connections
.
6. Клонируйте и протестируйте приложение локально.
- Клонируйте репозиторий примера приложения и установите пакеты, необходимые для запуска приложения.
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples/ cd nodejs-docs-samples/cloud-sql/postgres/knex npm install
- Установите следующие переменные среды:
export INSTANCE_CONNECTION_NAME='<PROJECT-ID>:<ZONE-ID>:<INSTANCE-ID>'
export DB_HOST='127.0.0.1:5432'
export DB_USER='postgres'
export DB_PASS='<PASSWORD>'
export DB_NAME='votesdb'
- Запустите пример приложения.
npm start
- Нажмите «Просмотр в Интернете». в Cloud Shell, затем выберите «Предварительный просмотр на порту 8080» .
В вашем браузере вы должны увидеть приложение для голосования Tabs vs Spaces, как показано здесь:
- Нажимайте кнопки, чтобы проголосовать и сохранить данные в базе данных.
7. Добавьте страницу для просмотра всех голосов.
Поскольку этот пример приложения очень прост, вы добавите дополнительную страницу, на которой будут отображаться все голоса. Основная причина этого заключается в том, что у вас будет больше данных для просмотра при дальнейшем использовании Query Insights.
- Введите
Ctrl+c
в Cloud Shell, чтобы остановить пример приложения. - В Cloud Shell нажмите кнопку Кнопка для запуска редактора Cloud Shell.
- В проводнике найдите
nodejs-docs-samples/cloud-sql/postgres/knex/server.js
и щелкните его, чтобы загрузить файлserver.js
в редактор.
Добавьте следующий код после определения функции getVotes
:
/**
* Retrieve all vote records from the database.
*
* @param {object} pool The Knex connection object.
* @returns {Promise}
*/
const getAllVotes = async pool => {
return await pool
.select('candidate', 'time_cast')
.from('votes')
.orderBy('time_cast', 'desc');
};
- Добавьте следующий код для маршрута
'/getAllVotes'
ниже, где определены другие маршруты:
app.get('/getAllVotes', async (req, res) => {
pool = pool || createPool();
try {
// Query all votes from the database.
const votes = await getAllVotes(pool);
res.render('allvotes.pug', {
votes: votes,
});
} catch (err) {
console.error(err);
res
.status(500)
.send('Unable to load page; see logs for more details.')
.end();
}
});
- Создайте новый файл в каталоге
nodejs-docs-samples/cloud-sql/postgres/knex/views
с именемallvotes.pug
. Вставьте следующий код:
doctype html
html(lang="en")
head
title Tabs VS Spaces
link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css")
link(rel="stylesheet", href="https://fonts.googleapis.com/icon?family=Material+Icons")
script(src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js")
body
nav(class="red lighten-1")
div(class="nav-wrapper")
a(href="#" class="brand-logo center") Tabs VS Spaces
div(class="section")
h4(class="header center") Recent Votes
ul(class="container collection center")
each vote in votes
li(class="collection-item avatar")
if vote.candidate.trim() === 'TABS'
i(class="material-icons circle green") keyboard_tab
else
i(class="material-icons circle blue") space_bar
span(class="title") A vote for <b>#{vote.candidate}</b>
p was cast at #{vote.time_cast}.
- Нажмите кнопку кнопку, чтобы вернуться в Cloud Shell и выполнить:
npm start
- Откройте приложение из веб-просмотра, чтобы убедиться, что оно работает. Добавьте
/getAllVotes
к URL-адресу в браузере, чтобы просмотреть добавленную вами новую страницу.
8. Включите SQL Commenter в приложении.
Теперь вы установите и включите SQL Commenter , библиотеку с открытым исходным кодом, которая позволяет ORM дополнять операторы SQL комментариями перед выполнением. SQLcommenter поддерживает несколько ORM и платформ, включая ту, которую использует пример приложения: Knex.js. Query Insights использует информацию в этих комментариях, чтобы предоставить ориентированное на приложение представление о производительности базы данных и определить, какой код приложения вызывает проблемы. Ожидается, что накладные расходы на производительность будут небольшими. См. документацию Query Insights .
- Введите
Ctrl+c
в Cloud Shell, чтобы остановить пример приложения. - Запустите следующую команду, чтобы установить пакеты, необходимые SQLcommenter:
npm install @google-cloud/sqlcommenter-knex @opencensus/nodejs @opencensus/propagation-tracecontext @opentelemetry/api @opentelemetry/core --save
- В Cloud Shell нажмите кнопку Кнопка для запуска редактора Cloud Shell.
- В проводнике найдите
nodejs-docs-samples/cloud-sql/postgres/knex/server.js
и щелкните его, чтобы загрузить файлserver.js
в редактор. - Найдите этот код в файле:
const process = require('process');
Под ним добавьте следующий код:
const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
- Найдите этот код в файле:
// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
res.set('Content-Type', 'text/html');
next();
});
Под ним добавьте следующий код:
app.use(wrapMainKnexAsMiddleware(Knex, {
traceparent: true,
tracestate: true,
route: true,
db_driver: true
}));
Как только это будет сделано, ваш код должен выглядеть примерно так:
...
// Require process, so we can mock environment variables.
const process = require('process');
const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
const express = require('express');
const Knex = require('knex');
const fs = require('fs');
const app = express();
app.set('view engine', 'pug');
app.enable('trust proxy');
// Automatically parse request body as form data.
app.use(express.urlencoded({extended: false}));
// This middleware is available in Express v4.16.0 onwards
app.use(express.json());
// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
res.set('Content-Type', 'text/html');
next();
});
app.use(wrapMainKnexAsMiddleware(Knex, {
traceparent: true,
tracestate: true,
route: true,
db_driver: true
}));
...
- Нажмите кнопку кнопку, чтобы вернуться в Cloud Shell и выполнить:
npm start
- В приложении «Табуляция против пробелов» нажимайте кнопки, чтобы проголосовать еще раз и добавить больше данных в базу данных.
9. Используйте Insights для просмотра производительности запросов и сквозной трассировки.
Панель мониторинга Query Insights помогает устранять неполадки с запросами Cloud SQL и выявлять проблемы с производительностью. Чтобы получить доступ к статистике, выберите «Информация о запросах» на левой панели навигации для вашего экземпляра Cloud SQL.
Загрузка базы данных — график всех запросов
На панели мониторинга Query Insights верхнего уровня отображается график загрузки базы данных — все запросы .
График содержит информацию о мощности ЦП, ожидании ЦП и ЦП, ожидании ввода-вывода и ожидании блокировки. Подробнее о том, что означают эти метрики, где хранятся метрики, а также посмотреть несколько примеров того, как выглядит этот график для проблемных запросов, можно узнать в документации . В случае с этим примером приложения нагрузка на запросы к базе данных невелика, поэтому на графике нет больших пиков.
Какие запросы несут наибольшую нагрузку?
Под графиком вы найдете таблицу QUERIES, содержащую нормализованные запросы для выбранного вами диапазона времени. Запросы в таблице отсортированы по общему времени выполнения.
Вы можете щелкнуть отдельный запрос, чтобы просмотреть подробную информацию о запросе, такую как загрузка базы данных для этого конкретного запроса, задержка запроса, образцы плана запроса и основные пользователи. Если приложение создано с использованием ORM, как в случае с примером приложения, вы можете не знать, какая часть приложения отвечает за какой запрос. Раздел «Популярные теги» поможет вам в этом разобраться.
Откуда в приложении исходит загрузка запросов?
Переключитесь с таблицы QUERIES на таблицу TAGS, чтобы увидеть список запросов, помеченных бизнес-логикой, что дает вам более ориентированное на приложение представление.
В таблице TAGS вы можете увидеть загрузку базы данных с разбивкой по тому маршруту, который генерировал загрузку. На снимке экрана выше вы можете видеть, что маршрут '/getAllVotes'
имеет более высокое среднее время выполнения и в среднем возвращает больше строк. Хотя время выполнения, которое мы видим в таблице, в данном случае не является проблемой, давайте все равно щелкнем строку '/getAllVotes'
, чтобы просмотреть данные более подробно.
Почему запросы выполняются медленно?
Нажмите точку на графике образцов плана запроса , чтобы просмотреть план запроса.
Планы запросов показывают, как PostgreSQL скрытно выполняет запрос, что упрощает определение наличия операций, приводящих к замедлению.
Какой код приложения способствует замедлению?
Query Insights также обеспечивает контекстную визуализацию сквозной трассировки, что может быть полезно для дальнейшего изучения того, какие части приложения генерируют медленные запросы.
Щелкните вкладку END TO END, чтобы просмотреть контекстную трассировку.
10. Наведите порядок и узнайте больше
Вы узнали, как использовать Query Insights для мониторинга и исследования производительности запросов с помощью приложения Node.js и базы данных Cloud SQL PostgreSQL!
Очистка
Если вы не хотите, чтобы экземпляр Cloud SQL продолжал работать, вы можете удалить его сейчас.
gcloud sql instances delete my-instance