Cloud SQL Insights 可帮助您检测、诊断和阻止 Cloud SQL 数据库的查询性能问题。它提供自助式、直观的监控和诊断信息,不仅仅是检测,可帮助您找出导致性能问题的根本原因。
在此 Codelab 中,您将学习如何设置 Cloud SQL for PostgreSQL 实例,部署 Node.js 应用以将 Cloud SQL 实例用作后端存储,然后使用 Cloud SQL Insights 查看和监控查询。
前提条件
- 基本了解 Node.js 编程语言和工具
您将执行的操作
- 在 Node.js 应用中使用 Cloud SQL。
- 在 Node.js 应用中启用 SQL Commenter。
- 使用 Cloud SQL Insights 监控和调查查询性能。
所需条件
- 您有权启用 API 和创建服务的 Google Cloud 帐号
自定进度的环境设置
- 登录 Cloud Console,然后创建一个新项目或重复使用现有项目。(如果您还没有 Gmail 或 Google 工作区帐号,则必须先创建一个。)
请记住您正在使用的项目的 ID。此 Codelab 稍后将在 PROJECT-ID
中引用它。
- 接下来,您需要在 Cloud Console 中启用结算功能才能使用 Google Cloud 资源。
运行此 Codelab 不会产生任何费用(如果有)。请务必按照“清理并了解详情”部分中的说明操作,其中介绍了如何关停资源,这样您就不会在本教程之外产生费用。Google Cloud 的新用户均有资格申请 $300 美元免费试用计划。
激活 Cloud Shell
- 在 Cloud Console 中,点击激活 Cloud Shell。
如果您以前从未启动过 Cloud Shell,将看到一个中间屏幕(在折叠下面),描述它是什么。如果是这种情况,请点击继续(您将永远不会再看到它)。一次性屏幕如下所示:
预配和连接到 Cloud Shell 只需花几分钟时间。
这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。
- 在 Cloud Shell 中运行以下命令,确认您使用的是正确的项目:
在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:
运行以下命令以确认您使用的项目正确无误。
gcloud config list project
如果您要使用的项目与打开 Cloud Shell 时选择的项目不同,则可以通过运行以下命令来设置新项目:
gcloud config set project <PROJECT-ID>;
- Cloud Shell 启动后,您可以使用命令行创建一个名为
my-instance
的新 Cloud SQL 实例,并启用 Cloud SQL 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
标志指定了具有最少资源的机器类型,因为它用于开发,您无需为 Codelab 投入大量资源。如需详细了解层级,请点击此处。--database-version=POSTGRES_12
标志将创建将使用 PostgreSQL 版本 12 的实例。--region=us-central
标志指定要在其中创建实例的区域。--root-password=<PASSWORD>
标志可用于指定根postgres
用户的密码。请务必将 <PASSWORD> 替换为您选择的密码。--insights-config-query-insights-enabled
标志会为您的实例启用 Cloud SQL Insights。--insights-config-record-application-tags
标志允许记录应用标记。您可以在后面的部分中了解有关应用标记的详情。--insights-config-record-client-address
标志允许由 Cloud SQL Insights 记录客户端 IP 地址。
系统可能会提示您为项目启用 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
服务帐号用于授予在 GCP 项目中使用不同服务的权限。对于此 Codelab,您需要 Cloud SQL 代理连接 Cloud SQL 实例所需的权限。
在控制台中创建服务帐号
- 转到 IAM 服务帐号页面,然后点击页面顶部的 按钮。
- 为您的服务帐号指定一个唯一名称和 ID,然后点击创建。
- 在下一页中,点击“选择角色”下拉列表。过滤“Cloud SQL”,然后选择 Cloud SQL 客户角色。点击继续,然后点击完成。
- 创建服务帐号后,点击新服务帐号的操作下的三个点,然后选择“创建密钥”。选择 JSON;保留该默认设置,然后点击创建。系统会下载一个 .json 私钥文件。点击关闭。
- 在 Cloud Shell 中,点击“更多”菜单上的三个点,然后选择上传文件。浏览到您下载到本地机器上的 .json 文件并选择该文件。此操作会将 .json 文件上传到 Cloud Shell 中的主目录。
您将使用 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
- 如需运行代理,请使用您从 Cloud SQL 实例详情复制的实例连接名称来替换
<INSTANCE_CONNECTION_NAME>
。对于凭据文件,请输入您在上一步中上传的文件的路径。
./cloud_sql_proxy -credential_file=/path/to/credential_file.json -instances=<INSTANCE_CONNECTION_NAME>=tcp:5432 &
如果成功,您应该看到几行输出,以 Ready for new connections
消息结尾。
- 克隆示例应用的代码库,并安装运行应用所需的软件包。
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples/ cd nodejs-docs-samples/cloud-sql/postgres/knex npm install
- 设置以下环境变量:
export CLOUD_SQL_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'
- 运行 createTable.js 以创建应用所需的数据库表,并确保数据库已正确配置,然后启动示例应用。
node createTable.js $DB_USER $DB_PASS $DB_NAME $CLOUD_SQL_CONNECTION_NAME votes $DB_HOST npm start
- 点击 Cloud Shell 中的网页预览,然后选择在端口 8080 上预览。
您应该在浏览器中看到“标签页与空间”投票应用,如下所示:
- 点击这些按钮进行投票,并将一些数据保存到数据库。
由于此示例应用非常简单,因此您将额外添加一个显示所有投票的网页。这样做的主要目的是让您后续使用 Cloud SQL Insights 时有更多数据可供选择。
- 在 Cloud Shell 中输入
Ctrl+c
以停止示例应用。 - 在 Cloud Shell 中,点击 按钮启动 Cloud Shell Editor。
- 在文件资源管理器中,找到
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
可查看您添加的新页面。
现在,您将安装并启用 SQL Commenter,这是一个开源库,它使 ORM 能够在执行之前扩充包含注释的 SQL 语句。SQL Commenter 支持多种 ORM 和框架,包括示例应用使用的 ORM:Knex.js。Cloud SQL Insights 会根据这些注释中的信息,提供以应用为中心的数据库性能详细信息,并确定哪个应用代码会引发问题。性能开销预计应该很小,您可以在文档中了解有关性能的更多信息。
- 在 Cloud Shell 中输入
Ctrl+c
以停止示例应用。 - 运行以下命令以安装 SQL commenter 所需的软件包:
npm install @google-cloud/sqlcommenter-knex @opencensus/nodejs @opencensus/propagation-tracecontext @opentelemetry/api @opentelemetry/core --save
- 在 Cloud Shell 中,点击 按钮启动 Cloud Shell Editor。
- 在文件资源管理器中,找到
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 bodyParser = require('body-parser');
const Knex = require('knex');
const app = express();
app.set('view engine', 'pug');
app.enable('trust proxy');
// Automatically parse request body as form data.
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.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
- 在“标签页与空间”应用中,点击相应按钮将更多投票项添加到数据库中。
查询数据分析信息中心可帮助您排查 Cloud SQL 查询问题,以查找性能问题。
数据库负载 - 所有查询图
顶级 Query Insights 信息中心显示“数据库负载 - 所有热门查询”图表。
该图包含 CPU 容量、CPU 和 CPU 等待情况、IO 等待和锁定等待的信息。如需详细了解这些指标的含义,了解指标的存储位置,并参阅文档中有关问题查询的图表示例。在此示例应用中,数据库查询负载较低,因此图表上没有任何大峰值。
哪些查询带来的负载最高?
在图表下方,您可以看到包含选定时间段内的标准化查询的 QUERIES 表。表中的查询按总执行时间排序。
您可以点击单个查询来查看该查询的详细信息,例如这一特定查询的数据库负载、查询延迟时间、查询计划示例和热门用户。如果应用是使用 ORM 构建的,就像示例应用的情况一样,您可能无法知道该应用的哪个部分负责查询。“热门标记”部分可以帮助您判断这一点。
应用的加载查询在哪里?
从 QUERIES 表切换到 TAGS 表,可查看业务逻辑标记的查询列表,从而获得更有针对性的应用视图。
在 TAGS 表中,您可以看到按负载生成的路由的数据库负载。在上面的屏幕截图中,您可以看到 '/getAllVotes'
路由的平均执行时间较长,平均返回更多行。虽然我们在表中看到的执行时间没有问题,但我们仍然点击 '/getAllVotes'
的行以查看更详细的数据。
为什么查询运行缓慢?
点击“查询计划示例”图表中的点可查看查询计划。
查询计划显示 PostgreSQL 如何在封面内执行查询,从而更轻松地确定是否存在会导致操作速度变慢的操作。
哪种应用代码会导致速度变慢?
Cloud SQL Insights 还提供对端到端跟踪的上下文可视化,有助于进一步调查应用的哪些部分产生慢的查询。
点击端到端标签页以查看上下文跟踪。
您已经了解了如何使用 Cloud SQL Insights 来监控和调查 Node.js 应用和 Cloud SQL PostgreSQL 数据库的查询性能!
清理
如果您不想让 Cloud SQL 实例保持运行,现在可以将其删除。
gcloud sql instances delete my-instance