JavaScript >> Javascript 文檔 >  >> Node.js

在 Google App Engine 上部署 Node.js 應用

簡介

TL;DR; 在本文中,我們將在 Google App Engine 上部署一個 Node.js 應用,並在此過程中看看它是如何完成的。

這將是一個從設置我們的 Google App Engine 環境到部署的分步演示。

注意 :本教程需要對 JavaScript、Node.js、MongoDB、NPM 和 Express.js 有基本的了解。

您可以在此處獲取已完成應用的源代碼。

什麼是 Google App Engine?

Google App Engine 是 Google 於 2008 年 4 月 7 日發布的 (PaaS) 雲計算平台,使用 C++、PHP、Node.js 和 Python 編寫。

Google App Engine 為開發人員和組織提供了一個理想的環境來託管他們的應用程序,而無需考慮基礎架構、停機時間或擴展到十億用戶。 Google App Engine 提供了所有這些,事實上,您不必擔心服務器,只需部署,Google App Engine 將處理大部分其他事情。當請求和需求很大時,Google App Engine 會自動擴展並為您的應用分配更多資源。

Google App Engine 是一個雲運行時環境,可讓您輕鬆部署和運行標準網絡應用程序。它提供了用於監控、擴展和負載平衡基礎架構的工具,因此您可以專注於構建您的 Web 應用程序,而不是運行它們的服務器。

創建一個 Google App Engine 實例(第二代實例 )

要開始使用 Google App Engine,我們將設置一個 Google Cloud Platform 項目:

  1. 登錄您的 Google 帳戶。如果您還沒有,您應該註冊。
  2. 轉到 App Engine 網站
  3. 可能會出現要求使用 Google Cloud Console 應用版本的對話框:“使用應用”或“現在不使用”。您可以自行選擇,但最好點擊“不是現在”繼續。
  4. 在顯示的屏幕上,它將顯示兩個選項:“創建”或“選擇”。對於本教程,我們正在創建一個新項目,單擊“創建”按鈕。如果您已超過 GCP 項目配額的最大數量,您應該“選擇”一個項目。
  5. 在“項目名稱”文本字段中輸入您的項目名稱,文本字段下方將是 GCP 根據您的項目名稱生成的項目 ID。完成後點擊“創建”按鈕。
  6. 幾秒鐘後,屏幕會顯示“選擇位置”。在“選擇區域”下拉小部件上,單擊它以選擇您的首選區域,然後單擊“下一步”。
  7. 下一個屏幕顯示“啟用結算”。點擊“設置結算”。
  8. 出現一個模式對話框,點擊“創建結算帳戶”。
  9. 在下一個窗口中輸入您首選的結算帳戶名稱,或者您可以使用默認名稱。
  10. 選擇您所在的國家/地區,默認貨幣已選擇美元,點擊“確認”按鈕。
  11. 在下一個窗口中,填寫您的詳細信息,包括個人和銀行賬戶詳細信息
  12. 點擊“提交並啟用結算”按鈕。現在,我們創建了一個啟用了結算功能的 Google Cloud 項目。

現在,我們完成了!

安裝谷歌云工具(雲 SDK)

谷歌云工具是一袋實用程序,在設置和訪問谷歌云產品時非常有用:谷歌 Kubernetes、谷歌應用引擎、終端上的谷歌大查詢。要開始安裝 Cloud SDK,請轉到 Google Cloud SDK,然後為您的操作系統下載 SDK 安裝程序。

Google Cloud SDK 包含 gcloud 等工具 , 和 gsutil ,但我們將使用 gcloud 工具來初始化和部署我們的應用程序。

gcloud 工具包含各種命令,使用戶能夠對 Google Cloud 項目執行不同的操作:

  • gcloud 信息 :顯示有關您的 Cloud SDK、系統、登錄用戶和當前活動項目的信息。
  • gcloud 授權列表 :顯示 Cloud SDK 中活躍的 Google 帳戶列表。
  • gcloud 初始化 :初始化一個谷歌云項目。
  • gcloud 幫助 :顯示 gcloud 中可用的命令 及其用法。
  • gcloud 配置列表 顯示 gcloud 的列表 配置。

好的,我們離題了一點,讓我們回到我們手頭的內容,下載 Cloud SDK 安裝程序後,啟動安裝程序並按照提示進行操作,確保檢查顯示的相關選項。安裝完成後,安裝程序將啟動命令 gcloud init 在終端窗口中。

該命令將帶您完成一系列配置。它將為您提供一個登錄選項:

You must log in to continue. Would you like to log in (Y/n)?

鍵入“Y”並按 Enter 鍵。它將啟動您的默認網絡瀏覽器,您將在其中選擇您喜歡的 Google 帳戶。之後,它將顯示在您的 Google 項目的終端列表中:

You are logged in as [YOUR_GOOGLE_ACCOUNT_EMAIL]:

pick cloud project to use:
 [1] [YOUR_PROJECT_NAME]
 [2] Create a new project
Please enter numeric choice or text value (must exactly match list item):

注意 :gcloud 如果您只有一個項目,將自動選擇。

接下來,系統會提示您選擇默認的 Compute Engine 區域:

Which Google Compute Engine zone would you like to use project default:
 [1] asia-east1-a
 ...
 [16] us-east1-b
 ...
 [25] Do not select default zone
Please enter numeric choice or text value (must exactly match list item):

選擇默認區域後,gcloud 進行一系列檢查並打印出來:

Your project default Compute Engine zone has been set to [YOUR_CHOICE_HERE]
You can change it by running [gcloud config set compute/zone NAME]

Your project default Compute Engine region has been set to [YOUR_CHOICE_HERE]
You can change it by running [gcloud config set compute/region NAME]

您的 Google Cloud SDK 已配置好,可以使用了!

設置我們的 Node.js 應用

現在,我們的 Google Cloud 項目已經配置完成。讓我們設置我們的 Node.js 應用程序。我們將為電影 Black Panther 創建一個 RESTful API .嗚!!!這會很棒。 2018 年 2 月 16 日,第一部漫威黑人超級英雄電影在全球電影院首映,截至撰寫本文時,票房收入高達 9.03 億美元,成為有史以來票房第 45 位和票房最高的電影2018 年。

讓我們構建一個返回 Black Panther 角色的 API .

API 端點

  1. 字符 - 這個資源是關於黑豹角色的。

    • POST - /blackpanther/ 創建一個新的 Black Panther 實例。
    • GET - /blackpanthers/ 返回所有黑豹角色。
    • GET - /blackpanther/<id> 返回指定的黑豹角色 id。
    • PUT - /blackpanther/<id> 更新黑豹角色屬性。
    • 刪除 - /blackpanther/<id> 刪除黑豹角色。

黑豹角色模型結構

{
    "alias": String,
    "occupation": String,
    "gender": String,
    "place_of_birth": String,
    "abilities": String,
    "played_by": String,
    "image_path": String
}

為 Black Panther API 創建 API 端點

首先,讓我們從創建項目文件夾開始,打開終端並運行以下命令:

$ mkdir _nodejs_gae

接下來,進入文件夾:

$ cd _nodejs_gae

Node.js 應用程序使用 npm init 進行初始化 命令。現在,我們在我們的項目文件夾中,運行以下命令來實例化一個 Node.js 應用程序:

$ npm init -y

此命令使用您預先配置的憑據創建一個 Node.js 應用程序。現在您的文件夾將如下所示:

|- _nodejs_gae
    |- package.json

為了遵循最佳實踐,我們將把我們的應用程序劃分為控制器、模型和路由。是的,我知道這對於這個演示應用來說有點矯枉過正,但做對了總是好的。

讓我們創建我們的 index.js 文件(我們的服務器入口點) - touch index.js

創建以下文件夾:

  • mkdir routes
  • mkdir ctrls
  • mkdir models

我們現在有 routes , ctrls , 和 models 文件夾。

  • 路線 :將保存我們 API 中定義的所有路由,並將調用分配給匹配 HTTP 請求的控制器函數。
  • ctrls :將持有從模型中獲取請求數據的操作。
  • 型號 :將保存我們 API 的數據庫模型。

我們將有一個路由、一個模型和一個與我們的 API 關聯的控制器。運行以下命令創建文件:

  • touch routes/route.js
  • touch ctrls/ctrl.js
  • touch models/Character.js

我們的文件夾結構現在應該是這樣的:

|- _nodejs_gae
    |- routes/
        |- route.js
    |- ctrls/
        |- ctrl.js
    |- models/
        |- Character.js
    |- index.js
    |- package.json

好的,讓我們安裝我們的依賴項:

  • npm i express -S
  • npm i mongoose -S
  • npm i body-parser -S

我們現在,打開我們的 Character.js 並將以下代碼粘貼到其中:

const mongoose = require('mongoose')

let Character = new mongoose.Schema({
    alias: String,
    occupation: String,
    gender: String,
    place_of_birth: String,
    abilities: String,
    played_by: String,
    image_path: String
})
module.exports = mongoose.model('Character', Character)

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

在這裡,我們聲明了我們的模型模式 Character 使用 mongoose 架構類。我們的模型是導出的,因此我們可以在應用程序的任何地方導入和使用 Schema。

好的,讓我們將代碼添加到我們的 ctrl.js 文件:

const Character = require('./../models/Character')

module.exports = {
    getCharacter: (req, res, next) => {
        Character.findById(req.params.id, (err, Character) => {
            if (err)
                res.send(err)
            else if (!Character)
                res.send(404)
            else
                res.send(Character)
            next()
        })
    },
    getAllCharacters: (req, res, next) => {
        Character.find((err, data) => {
            if (err) {
                res.send(err)
            } else {
                res.send(data)
            }
            next()
        })
    },
    deleteCharacter: (req, res, next) => {
        Character.findByIdAndRemove(req.params.id, (err) => {
            if (err)
                res.send(err)
            else
                res.sendStatus(204)
            next()
        })
    },
    addCharacter: (req, res, next) => {
        (new Character(req.body)).save((err, newCharacter) => {
            if (err)
                res.send(err)
            else if (!newCharacter)
                res.send(400)
            else
                res.send(newCharacter)
            next()
        })
    },
    updateCharacter: (req, res, next) => {
        Character.findByIdAndUpdate(req.params.id, req.body, (err, updatedCharacter) => {
            if (err)
                res.send(err)
            else if (!updatedCharacter)
                res.send(400)
            else
                res.send(req.body)
            next()
        })
    }
}

在這裡,聲明了我們的 4 CRUD y 函數:getCharacter , deleteCharacter , getAllCharaccters , 和 updateCharacter .就像他們的名字暗示他們執行 CREATE , READ , UPDATEDELETE 對我們的黑豹採取的行動 API。

OK,讓我們打開route.js 文件並在其中粘貼以下代碼:

const ctrl = require('./../ctrls/ctrl')

module.exports = (router) => {

    /** get all Black Panther characters */
    router
        .route('/blackpanthers')
        .get(ctrl.getAllCharacters)

    /** save a Black Panther character */
    router
        .route('/blackpanther')
        .post(ctrl.addCharacter)

    /** get a Black Panther character */
    router
        .route('/blackpanther/:id')
        .get(ctrl.getCharacter)

    /** delete a Black Panther character */
    router
        .route('/blackpanther/:id')
        .delete(ctrl.deleteCharacter)

    /** update a Black Panther character */
    router
        .route('/blackpanther/:id')
        .put(ctrl.updateCharacter)
}

上面我們定義了兩條基本路由(/blackpanther , 和 /blackpanther/:id ) 用不同的方法。

如我們所見,我們需要控制器,以便每個路由方法都可以調用其各自的處理函數。

最後,我們打開我們的 index.js 文件。在這裡,我們將組件綁定為一個。我們導入 routes/route.js 中暴露給我們的 routes 函數 ,我們通過 express.Router() 作為我們 routes 的參數 功能。接下來,我們連接到 MongoDB 實例,然後調用 app.listen() 啟動服務器的方法。

const express = require('express')
const mongoose = require('mongoose')
const bodyParser = require('body-parser')

const app = express()
const router = express.Router()
const routes = require('./routes/route')

const url = process.env.MONGODB_URI || "mongodb://localhost:27017/blackpanther"

mongoose.connect(url, {
    //useMongoClient: true
})

routes(router)
app.use(bodyParser.json())
app.use('/api/v1', router)

const port = process.env.PORT || 1000

app.listen(port, () => {
    console.log(`Black Panther API v1: ${port}`)
})

將 mLab 數據存儲添加到我們的 API 端點

一直以來,我們一直在使用 MongoDB 數據存儲的本地實例。我們將在雲計算基礎架構上部署和訪問我們的應用程序,因此不會存在本地數據存儲。為了持久化我們的數據,我們將選擇數據即服務 (DaaS) 平台 mLab。

  • 轉到 mLab
  • 如果您還沒有帳戶,請創建一個帳戶
  • 轉到您的儀表板,創建一個新數據庫
  • 複製數據庫連接 URL

現在我們有了我們的 mLab 連接 URL 字符串,我們現在將修改 index.js 文件:

...
const url = process.env.MONGODB_URI || "mongodb://<DB_USER>:<DB_PASSWORD>@<MLAB_URL>.mlab.com:<MLAB_PORT>/<DB_NAME>"
...

通過 cURL 在本地測試我們的應用程序

在我們的本地機器上測試我們的應用程序。運行以下命令啟動服務器:

$ node .

它會在你的終端上顯示如下內容:

$ node .
Black Panther API v1: 1000

好的,現在我們的黑豹 API 已啟動並運行,我們可以使用 cURL 測試 API。在這裡,我們將 POST 到 API 以創建一個新的 Black Panther 人物:

curl --request POST \
  --url http://localhost:1000/api/v1/blackpanther \
  --header 'content-type: application/json' \
  --data '{"alias":"tchalla","occupation":"King of Wakanda","gender":"male","place_of_birth":"Wakanda","abilities":"enhanced strength","played_by":"Chadwick Boseman"}'

作為讀者的任務,您應該繼續編寫 cURL 其他 API 端點的命令也是如此。

部署我們的應用

現在,我們的 nodejs 應用程序已準備好部署,但在此之前,我們必須調整和添加一些配置。首先,我們將創建一個 app.yaml 文件到我們的項目中。

app.yaml 文件是 App Engine 環境的運行時配置。 app.yaml 使我們能夠在部署之前配置我們的 App Engine 環境(Node.js、GO、PHP、Ruby、Python、.NET 或 Java Runtime)。

使用 app.yaml 文件,我們可以執行以下操作:

  • 分配網絡和磁盤資源
  • 選擇柔性環境
  • 選擇要分配的 CPU 核數
  • 指定 memory_gb (RAM) 大小

清單很長,你可以去資源Configuring your app with app.yaml 查看由 Google 策劃的完整配置設置。

好的,讓我們創建 app.yaml 我們項目中的文件:

touch app.yaml

打開app.yaml 文件,並添加以下內容:

runtime: nodejs
env: flex

manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

查看上面的配置,我們告訴 App Engine 我們的應用將運行在 Node.js 運行時環境中,並且環境應該設置為靈活。

在靈活的環境中運行會產生成本,因此我們通過以下方式縮小規模以降低成本:

...
manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

在這裡,我們只指定一個實例、一個 CPU 內核、0.5G RAM 和 10G 磁盤大小。

這是測試目的的理想選擇,不適合生產使用。

接下來,我們要添加一個 startscripts 我們的 package.json 部分 ,Node.js 運行時使用它來在部署時啟動我們的應用程序。

沒有 start 屬性,Node.js 運行時檢查器會拋出“應用程序檢測失敗:錯誤:nodejs 檢查器:在 package.json 的腳本部分中啟動和 server.js 均未找到”錯誤。

讓我們打開package.json 並添加 startscripts 關鍵:

...
    "scripts": {
        "start": "node .",
        "test": "echo \"Error: no test specified\" && exit 1"
    },
...

在此之後,我們現在都準備好部署了。要部署我們的應用,請運行以下命令:

$ gcloud app deploy

使用 cURL 測試我們部署的應用程序

為了測試我們部署的 Node.js 應用 API,我們需要使用 target url Google App Engine 給了我們。

curl --request POST \
  --url http://YOUR_TARGET_URL.appspot.com/api/v1/blackpanther \
  --header 'content-type: application/json' \
  --data '{"alias":"tchalla","occupation":"King of Wakanda","gender":"male","place_of_birth":"Wakanda","abilities":"enhanced strength","played_by":"Chadwick Boseman"}'

使用 cURL 我們發送了一個 POST 請求和黑豹 使用 target url 到我們部署的 Node.js 應用程序的字符有效負載 作為我們的 url 參數。

我們的 API 端點執行 POST 函數,將有效負載保存到我們的 mLab 數據庫並將結果發回給我們:

{
    "alias":"tchalla",
    "occupation":"King of Wakanda",
    "gender":"male",
    "place_of_birth":"Wakanda",
    "abilities":"enhanced strength",
    "played_by":"Chadwick Boseman","_id":"5aa3a3905cd0a90010c3e1d9",
    "__v":0
}

恭喜!我們已經成功地將我們的第一個 Node.js 應用部署到了 Google App Engine。

結論

我們在本文中看到,Google App Engine 讓我們的生活變得輕鬆無壓力。此外,如何僅通過幾個命令設置強大的運行時引擎並在其上部署您的應用程序。無需考慮擴展、資源、帶寬等。

App Engine 為您代勞。

勾選 Google App Engine 為我們提供的好處:

  1. 不錯的錯誤報告
  2. 簡化 API 安全性
  3. 可靠性和支持
  4. 免費應用的使用配額

如果您有任何問題或意見,請隨時在評論部分提出。


Tutorial JavaScript 教程
  1. 視頻教程:如何為 reactjs 添加谷歌登錄

  2. 如何整合tailwind、react和webpack

  3. 構建看板風格的待辦事項應用程序

  4. 帶有反應的網絡字體加載器

  5. Summarizer - 將任何視頻/音頻轉換為摘要文本

  6. 僅反應一次 useEffect

  7. 如何在我無法更改其聲明的函數中將對像作為單個參數傳播?

  1. 從集合 firebase angular/typescript 中獲取所有文檔 [關閉]

  2. Fabric.js:高級

  3. JavaScript Countdown,就這麼簡單嗎?

  4. 使用 Docker 和 MySQL 設置 Adonis.js

  5. 搜索功能 .match() 區分大小寫

  6. Livewire v 1.2.0 中的文件上傳

  7. 狀態機出現:Baby 的第一個帶有 XState 的狀態機(3/24)

  1. Javascript for...of 循環運行一個太多次的對像數組

  2. 如何使用 Next.js 處理 JWT 和 Http-Only Cookies 身份驗證

  3. 像 pro 一樣使用 Javascript 控制台

  4. 帶有 DOMContentLoaded 的異步加載腳本或未調用加載事件處理程序?