将 Cloud SQL for PostgreSQL 与 Rails 5 搭配使用

开始开发在 App Engine 柔性环境中运行的 Ruby on Rails 应用。您创建的应用将在支持所有 Google 产品的同一基础架构上运行,因此您可以放心,这些应用能顺畅扩容,以满足所有用户(无论是几个还是几百万个)的需求。

本教程假设您熟悉 Rails 网页开发,并将引导您在新的 Rails 应用中设置 Cloud SQL for PostgreSQL。此外,本教程还提供了有关如何将现有 Rails 应用配置为使用 Cloud SQL for PostgreSQL 的参考信息。

本教程需要 Ruby 2.6 或 2.7

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Cloud SQL Admin API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  8. 确保您的 Google Cloud 项目已启用结算功能

  9. 启用 Cloud SQL Admin API。

    启用 API

  10. 安装 Google Cloud CLI。
  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init

准备 Cloud SQL for PostgreSQL 实例

为本教程设置 Cloud SQL for PostgreSQL 实例。

  1. 创建 PostgreSQL 实例。 在本教程中,该实例的名称为 rails-cloudsql-instance

  2. 在该实例中创建数据库。 在本教程中,生产数据库的名称为 cat_list_production

  3. 为实例设置 postgres 用户密码

为 Rails 设置本地环境

要为本教程设置本地环境,请执行以下操作:

  1. 安装 Ruby 2.6 版或 2.7 版。

  2. 安装 Rails 5 gem。

  3. 安装 Bundler gem。

如需详细了解如何安装 Rails 及其依赖项,请参阅官方《Rails 使用入门》指南。

满足前提条件后,使用 Cloud SQL for PostgreSQL 创建和部署 Rails 应用。以下几个部分将指导您配置、连接到 Cloud SQL for PostgreSQL 以及部署应用。

创建新应用以列出猫咪

  1. 运行 rails new 命令以创建新的 Rails 应用。此应用将在 Cloud SQL for PostgreSQL 中存储一个猫咪列表。

    rails new cat_sample_app
    
  2. 转到包含生成的 Rails 应用的目录。

    cd cat_sample_app
    

在本地运行应用

要在本地计算机上运行新 Rails 应用,请执行以下操作:

  1. 使用 Bundler 安装依赖项。

    bundle install
    
  2. 启动本地网络服务器:

    bundle exec bin/rails server
    
  3. 在浏览器中,转到 http://localhost:3000/

打开的页面中随即会显示来自应用的耶!您正在使用 Rails!消息。

新 Rails 应用运行的屏幕截图

为猫咪列表生成基架

为名为 Cat 的资源生成基架,该资源用于生成一个猫咪列表,其中包含猫咪的名字和年龄。

  1. 生成基架。

    bundle exec rails generate scaffold Cat name:string age:integer
    

    该命令会为 Cat 资源生成模型、控制器和视图。

    invoke  active_record
    create    db/migrate/20170804210744_create_cats.rb
    create    app/models/cat.rb
    invoke    rspec
    create      spec/models/cat_spec.rb
    invoke  resource_route
    route    resources :cats
    invoke  scaffold_controller
    create    app/controllers/cats_controller.rb
    invoke    erb
    create      app/views/cats
    create      app/views/cats/index.html.erb
    create      app/views/cats/edit.html.erb
    create      app/views/cats/show.html.erb
    create      app/views/cats/new.html.erb
    create      app/views/cats/_form.html.erb
    invoke    jbuilder
    create      app/views/cats/index.json.jbuilder
    create      app/views/cats/show.json.jbuilder
    create      app/views/cats/_cat.json.jbuilder
    invoke  assets
    invoke    js
    create      app/assets/javascripts/cats.js
    invoke    scss
    create      app/assets/stylesheets/cats.scss
    invoke  scss
    create    app/assets/stylesheets/scaffolds.scss
    
  2. 打开文件 config/routes.rb 可查看以下生成的内容。

    Rails.application.routes.draw do
      resources :cats
      get 'cats/index'
      # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
    
    end
  3. root 'cats#index' 添加到文件中。

    Rails.application.routes.draw do
      resources :cats
      get 'cats/index'
    
      # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
      root 'cats#index'
    end
  4. 保存文件并关闭。

  5. 按照之前所述的方式对 Rails 应用进行测试。

将 Cloud SQL for PostgreSQL 与 App Engine 搭配使用

Cloud SQL for PostgreSQL 是一种全托管式数据库服务,用于在 Google Cloud 中设置、维护、管理和控制关系型 PostgreSQL 数据库。您可以在 Rails 应用中象使用其他任何关系型数据库一样使用 Cloud SQL。

设置 Cloud SQL for PostgreSQL

要开始在您的生产环境 Rails 应用中使用 Cloud SQL,请执行以下操作:

  1. pgappengine gem 添加到 Gemfile 文件中。

    bundle add pg
    bundle add appengine
    

    Rails Gemfile 包含以下额外的 gem 条目:

    gem "appengine", "~> 0.6"
    gem "pg", "~> 1.2"
  2. 打开 config/database.yml 文件,以将 Rails 应用配置为连接到 Cloud SQL。系统将显示 SQLite 的以下样板数据库设置:

    # SQLite version 3.x
    #   gem install sqlite3
    #
    #   Ensure the SQLite 3 gem is defined in your Gemfile
    #   gem 'sqlite3'
    #
    default: &default
      adapter: sqlite3
      pool: 5
      timeout: 5000
    
    development:
      <<: *default
      database: db/development.sqlite3
    
    # Warning: The database defined as "test" will be erased and
    # re-generated from your development database when you run "rake".
    # Do not set this db to the same as development or production.
    test:
      <<: *default
      database: db/test.sqlite3
    
    production:
      <<: *default
      database: db/production.sqlite3
  3. 为 App Engine 生产环境配置 Cloud SQL 实例连接名称。

    1. 检索实例连接名称。

      gcloud sql instances describe rails-cloudsql-instance
      
    2. 复制 connectionName 旁边的值。

  4. database.yml 生产数据库配置修改为以下内容:

    production:
      adapter: postgresql
      encoding: unicode
      pool: 5
      timeout: 5000
      username: "[YOUR_POSTGRES_USERNAME]"
      password: "[YOUR_POSTGRES_PASSWORD]"
      database: "cat_list_production"
      host:   "/cloudsql/[YOUR_INSTANCE_CONNECTION_NAME]"

    其中:

    • [YOUR_POSTGRES_USERNAME] 表示您的 Cloud SQL for PostgreSQL 实例用户名。
    • [YOUR_POSTGRES_PASSWORD] 表示您的 Cloud SQL for PostgreSQL 实例密码。
    • [YOUR_INSTANCE_CONNECTION_NAME] 表示您在上一步中复制的实例连接名称。

Rails 应用现已设置为在部署到 App Engine 柔性环境时使用 Cloud SQL。

将应用部署到 App Engine 柔性环境

App Engine 柔性环境使用名为 app.yaml 的文件来描述应用的部署配置。如果此文件不存在,则 gcloud CLI 会尝试推测部署配置。但是,我们建议您定义该文件,以提供所需的 Rails 密钥和 Cloud SQL 配置设置。

如需配置示例应用以便将其部署到 App Engine 中,请在 Rails 应用目录的根目录下创建一个名为 app.yaml 的新文件,并添加以下内容:

entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: ruby

app.yaml 文件中配置 Rails 密钥

将 Rails 应用部署到 production 环境时,请将 SECRET_KEY_BASE 环境变量设置为用于保护用户会话数据的密钥。此环境变量是从 Rails 应用中的 config/secrets.yml 文件中读取的。

  1. 生成新的密钥。

    bundle exec bin/rails secret
    
  2. 复制生成的密钥。

  3. 打开先前创建的 app.yaml 文件,然后添加 env_variables 部分。env_variables 将定义 App Engine 柔性环境中的环境变量。app.yaml 文件的内容应类似于如下示例,其中 [SECRET_KEY] 应替换为您的密钥。

    entrypoint: bundle exec rackup --port $PORT
    env: flex
    runtime: ruby
    
    env_variables:
      SECRET_KEY_BASE: [SECRET_KEY]

app.yaml 文件中配置 Cloud SQL 实例

接下来,您需要通过在 app.yaml 配置文件中提供 Cloud SQL 实例连接名称,将 App Engine 柔性环境配置为使用指定的 Cloud SQL 实例。

  1. 打开 app.yaml 文件,然后添加一个名为 beta_settings 的新部分。

  2. 定义一个嵌套参数 cloud_sql_instances,并将其值设置为实例连接名称。

    app.yaml 应类似如下所示:

    entrypoint: bundle exec rackup --port $PORT
    env: flex
    runtime: ruby
    
    env_variables:
      SECRET_KEY_BASE: [SECRET_KEY]
    
    beta_settings:
      cloud_sql_instances: [YOUR_INSTANCE_CONNECTION_NAME]

创建 App Engine 柔性环境应用

如果这是您第一次部署应用,则需要创建 App Engine 柔性环境应用,并选择要在其中运行 Rails 应用的区域。

  1. 创建 App Engine 应用。

    gcloud app create
    
  2. 选择支持 App Engine Ruby 柔性环境以运行 Ruby 应用的区域。如需了解更多信息,请参阅区域和地区

部署新版本

接下来,通过运行以下命令,部署 app.yaml 文件中描述的新版 Rails 应用,而不重定向来自当前默认服务版本的流量:

gcloud app deploy --no-promote

完成部署可能需要几分钟的时间,请等待系统返回成功消息。您可以在 App Engine 版本列表中查看已部署的版本。

部署完新版本后,如果您尝试访问该版本,将会看到以下错误消息,因为您尚未执行数据库迁移。

新 Rails 应用错误消息的屏幕截图

授予 appengine gem 需要的权限

接下来,您需要向 cloudbuild 服务帐号授予相关访问权限,以使其能够通过 appengine gem 运行生产数据库迁移。

  1. 列出可用项目。

    gcloud projects list
    
  2. 在输出中,找到要用于部署应用的项目,然后复制项目编号。

  3. 在您的项目 IAM 政策中添加一个角色为 roles/editor 的新成员,以运行数据库迁移。将 [YOUR-PROJECT-ID] 替换为您的 Google Cloud 项目 ID,并将 [PROJECT_NUMBER] 替换为您在上一步中复制的项目编号。

    gcloud projects add-iam-policy-binding [YOUR-PROJECT-ID] \
      --member=serviceAccount:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com \
      --role=roles/editor
    

迁移您的 Rails 数据库

使用 Rails 数据库迁移,您无需直接使用 SQL 语法即可更新数据库架构。接下来需要迁移 cat_list_production 数据库。

appengine gem 提供了 Rake 任务 appengine:exec,用于对在 App Engine 柔性生产环境中最新部署的应用版本运行命令。

  1. 在生产环境中迁移 Cloud SQL for PostgreSQL cat_list_production 数据库。

    bundle exec rake appengine:exec -- bundle exec rake db:migrate
    

    您应看到如下输出:

    ---------- EXECUTE COMMAND ----------
    bundle exec rake db:migrate
    Debuggee gcp:787021104993:8dae9032f8b02004 successfully registered
    == 20170804210744 CreateCats: migrating =======================================
    -- create_table(:cats)
       -> 0.0219s
    == 20170804210744 CreateCats: migrated (0.0220s) ==============================
    
    ---------- CLEANUP ----------
    
  2. 要验证数据库迁移,请在浏览器中输入以下网址:

    https://VERSION_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com

    替换以下内容:

    • VERSION_ID:您之前部署的应用的新版本。 要获取版本列表,请使用 gcloud app versions list。最后一个默认服务版本项是最新部署。
    • PROJECT_ID:您的 Google Cloud 项目 ID
    • REGION_IDApp Engine 分配给您的应用的代码

如果部署成功,您将看到以下内容:

新 Rails 应用运行的屏幕截图

将流量迁移到新版本

最后,您需要使用以下命令将流量定向到新部署的版本:

gcloud app services set-traffic default --splits [YOUR-VERSION]=1

现在可以通过以下网址访问应用的新版本:

https://PROJECT_ID.REGION_ID.r.appspot.com

读取 App Engine 日志

部署 Rails 应用后,您可能需要读取日志。您可以使用 Google Cloud Console 中的日志浏览器读取应用日志。

如需了解详情,请参阅使用 gcloud CLI 读取日志

清理资源

完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍了如何删除或关停这些资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

要删除项目,请执行以下操作:

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除 App Engine 版本

要删除应用版本,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到 App Engine 的版本页面。

    转到“版本”

  2. 选中要删除的非默认应用版本对应的复选框。
  3. 如需删除应用版本,请点击删除

删除 Cloud SQL 实例

要删除 Cloud SQL 实例,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到实例页面。

    转到“实例”

  2. 点击要删除的 SQL 实例。
  3. 如需删除实例,请点击删除,然后按照说明操作。

后续步骤