Linux中國

Up:在幾秒鐘內部署無伺服器應用程序

去年,我為 Up 規划了一份藍圖,其中描述了如何以最小的成本在 AWS 上為大多數構建塊創建一個很棒的無伺服器環境。這篇文章則是討論了 Up 的初始 alpha 版本。

為什麼關注 無伺服器 serverless ?對於初學者來說,它可以節省成本,因為你可以按需付費,且只為你使用的付費。無伺服器方式是自愈的,因為每個請求被隔離並被視作「無狀態的」。最後,它可以無限輕鬆地擴展 —— 沒有機器或集群要管理。部署你的代碼就行了。

大約一個月前,我決定開始在 apex/up 上開發它,並為動態 SVG 版本的 GitHub 用戶投票功能寫了第一個小型無伺服器示常式序 tj/gh-polls。它運行良好,成本低於每月 1 美元即可為數百萬次投票服務,因此我會繼續這個項目,看看我是否可以提供開源版本及商業的變體版本。

其長期的目標是提供「你自己的 Heroku」 的版本,支持許多平台。雖然平台即服務(PaaS)並不新鮮,但無伺服器生態系統正在使這種方案日益萎縮。據說,AWS 和其他的供應商經常由於他們提供的靈活性而被人詬病用戶體驗。Up 將複雜性抽象出來,同時為你提供一個幾乎無需運維的解決方案。

安裝

你可以使用以下命令安裝 Up,查看這篇臨時文檔開始使用。或者如果你使用安裝腳本,請下載二進位版本。(請記住,這個項目還在早期。)

curl -sfL https://raw.githubusercontent.com/apex/up/master/install.sh | sh

只需運行以下命令隨時升級到最新版本:

up upgrade

你也可以通過 NPM 進行安裝:

npm install -g up

功能

這個早期 alpha 版本提供什麼功能?讓我們來看看!請記住,Up 不是託管服務,因此你需要一個 AWS 帳戶和 AWS 憑證。如果你對 AWS 不熟悉,你可能需要先停下來,直到熟悉流程。

我遇到的第一個問題是:up(1) 與 apex(1) 有何不同?Apex 專註於部署功能,用於管道和事件處理,而 Up 則側重於應用程序、API 和靜態站點,也就是單個可部署單元。Apex 不為你提供 API 網關、SSL 證書或 DNS,也不提供 URL 重寫,腳本注入等。

單命令無伺服器應用程序

Up 可以讓你使用單條命令部署應用程序、API 和靜態站點。要創建一個應用程序,你只需要一個文件,在 Node.js 的情況下,./app.js 監聽由 Up 提供的 PORT'。請注意,如果你使用的是package.json,則會檢測並使用startbuild` 腳本。

const http = require('http')
const { PORT = 3000 } = process.env
http.createServer((req, res) => {
  res.end('Hello Worldn')
}).listen(PORT)

額外的運行時環境也支持開箱可用,例如用於 Golang 的 「main.go」,所以你可以在幾秒鐘內部署 Golang、Python、Crystal 或 Node.js 應用程序。

package main

import (
 "fmt"
 "log"
 "net/http"
 "os"
)

func main() {
 addr := ":" + os.Getenv("PORT")
 http.HandleFunc("/", hello)
 log.Fatal(http.ListenAndServe(addr, nil))
}

func hello(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "Hello World from Go")
}

要部署應用程序輸入 up 來創建所需的資源並部署應用程序本身。這裡沒有模糊不清的地方,一旦它說「完成」了那就完成了,該應用程序立即可用 —— 沒有遠程構建過程。

後續的部署將會更快,因為棧已被配置:

使用 up url --open 測試你的程序,以在瀏覽器中瀏覽它,up url --copy 可以將 URL 保存到剪貼板,或者可以嘗試使用 curl:

curl `up url`
Hello World

要刪除應用程序及其資源,只需輸入 up stack delete

例如,使用 up stagingup productionup url --open production 部署到預發布或生產環境。請注意,自定義域名尚不可用,它們將很快可用。之後,你還可以將版本「推廣」到其他環境。

反向代理

Up 的一個獨特的功能是,它不僅僅是簡單地部署代碼,它將一個 Golang 反向代理放在應用程序的前面。這提供了許多功能,如 URL 重寫、重定向、腳本注入等等,我們將在後面進一步介紹。

基礎設施即代碼

在配置方面,Up 遵循現代最佳實踐,因此對基礎設施的更改都可以在部署之前預覽,並且 IAM 策略的使用還可以限制開發人員訪問以防止事故發生。一個附帶的好處是它有助於自動記錄你的基礎設施。

以下是使用 Let's Encrypt 通過 AWS ACM 配置一些(虛擬)DNS 記錄和免費 SSL 證書的示例。

{
  "name": "app",
  "dns": {
    "myapp.com": [
      {
        "name": "myapp.com",
        "type": "A",
        "ttl": 300,
        "value": ["35.161.83.243"]
      },
      {
        "name": "blog.myapp.com",
        "type": "CNAME",
        "ttl": 300,
        "value": ["34.209.172.67"]
      },
      {
        "name": "api.myapp.com",
        "type": "A",
        "ttl": 300,
        "value": ["54.187.185.18"]
      }
    ]
  },
  "certs": [
    {
      "domains": ["myapp.com", "*.myapp.com"]
    }
  ]
}

當你首次通過 up 部署應用程序時,需要所有的許可權,它為你創建 API 網關、Lambda 函數、ACM 證書、Route53 DNS 記錄等。

ChangeSets 尚未實現,但你能使用 up stack plan 預覽進一步的更改,並使用 up stack apply 提交,這與 Terraform 非常相似。

詳細信息請參閱配置文檔

全球部署

regions 數組可以指定應用程序的目標區域。例如,如果你只對單個地區感興趣,請使用:

{
  "regions": ["us-west-2"]
}

如果你的客戶集中在北美,你可能需要使用美國和加拿大所有地區:

{
  "regions": ["us-*", "ca-*"]
}

最後,你可以使用 AWS 目前支持的所有 14 個地區:

{
  "regions": ["*"]
}

多區域支持仍然是一個正在進行的工作,因為需要一些新的 AWS 功能來將它們結合在一起。

靜態文件服務

Up 默認支持靜態文件服務,並帶有 HTTP 緩存支持,因此你可以在應用程序前使用 CloudFront 或任何其他 CDN 來大大減少延遲。

typestatic 時,默認情況下的工作目錄是 .,但是你也可以提供一個 static.dir

{
  "name": "app",
  "type": "static",
  "static": {
    "dir": "public"
  }
}

構建鉤子

構建鉤子允許你在部署或執行其他操作時定義自定義操作。一個常見的例子是使用 Webpack 或 Browserify 捆綁 Node.js 應用程序,這大大減少了文件大小,因為 node 模塊是很大的。

{
  "name": "app",
  "hooks": {
    "build": "browserify --node server.js > app.js",
    "clean": "rm app.js"
  }
}

腳本和樣式表插入

Up 允許你插入腳本和樣式,無論是內聯方式或聲明路徑。它甚至支持一些「罐頭」腳本,用於 Google Analytics(分析)和 Segment,只需複製並粘貼你的寫入密鑰即可。

{
  "name": "site",
  "type": "static",
  "inject": {
    "head": [
      {
        "type": "segment",
        "value": "API_KEY"
      },
      {
        "type": "inline style",
        "file": "/css/primer.css"
      }
    ],
    "body": [
      {
        "type": "script",
        "value": "/app.js"
      }
    ]
  }
}

重寫和重定向

Up 通過 redirects 對象支持重定向和 URL 重寫,該對象將路徑模式映射到新位置。如果省略 status 參數(或值為 200),那麼它是重寫,否則是重定向。

{
  "name": "app",
  "type": "static",
  "redirects": {
    "/blog": {
      "location": "https://blog.apex.sh/",
      "status": 301
    },
    "/docs/:section/guides/:guide": {
      "location": "/help/:section/:guide",
      "status": 302
    },
    "/store/*": {
      "location": "/shop/:splat"
    }
  }
}

用於重寫的常見情況是 SPA(單頁面應用程序),你希望不管路徑如何都提供 index.html,當然除非文件存在。

{
  "name": "app",
  "type": "static",
  "redirects": {
    "/*": {
      "location": "/",
      "status": 200
    }
  }
}

如果要強制實施該規則,無論文件是否存在,只需添加 "force": true

環境變數

密碼將在下一個版本中有,但是現在支持純文本環境變數:

{
  "name": "api",
  "environment": {
    "API_FEATURE_FOO": "1",
    "API_FEATURE_BAR": "0"
  }
}

CORS 支持

CORS 支持允許你指定哪些(如果有的話)域可以從瀏覽器訪問你的 API。如果你希望允許任何網站訪問你的 API,只需啟用它:

{
  "cors": {
    "enable": true
  }
}

你還可以自定義訪問,例如僅將 API 訪問限制為你的前端或 SPA。

{
  "cors": {
    "allowed_origins": ["https://myapp.com"],
    "allowed_methods": ["HEAD", "GET", "POST", "PUT", "DELETE"],
    "allowed_headers": ["Content-Type", "Authorization"]
  }
}

日誌

對於 $0.5/GB 的低價格,你可以使用 CloudWatch 日誌進行結構化日誌查詢和跟蹤。Up 實現了一種用於改進 CloudWatch 提供的自定義查詢語言,專門用於查詢結構化 JSON 日誌。

你可以查詢現有日誌:

up logs

跟蹤在線日誌:

up logs -f

或者對其中任一個進行過濾,例如只顯示耗時超過 5 毫秒的 200 個 GET/HEAD 請求:

up logs 'method in ("GET", "HEAD") status = 200 duration >= 5'

查詢語言是非常靈活的,這裡有更多來自於 up help logs 的例子

### 顯示過去 5 分鐘的日誌
$ up logs

### 顯示過去 30 分鐘的日誌
$ up logs -s 30m

### 顯示過去 5 小時的日誌
$ up logs -s 5h

### 實時顯示日誌
$ up logs -f

### 顯示錯誤日誌
$ up logs error

### 顯示錯誤和致命錯誤日誌
$ up logs 'error or fatal'

### 顯示非 info 日誌
$ up logs 'not info'

### 顯示特定消息的日誌
$ up logs 'message = "user login"'

### 顯示超時 150ms 的 200 響應
$ up logs 'status = 200 duration > 150'

### 顯示 4xx 和 5xx 響應
$ up logs 'status >= 400'

### 顯示用戶郵件包含 @apex.sh 的日誌
$ up logs 'user.email contains "@apex.sh"'

### 顯示用戶郵件以 @apex.sh 結尾的日誌
$ up logs 'user.email = "*@apex.sh"'

### 顯示用戶郵件以 tj@ 開始的日誌
$ up logs 'user.email = "tj@*"'

### 顯示路徑 /tobi 和 /loki 下的錯誤日誌
$ up logs 'error and (path = "/tobi" or path = "/loki")'

### 和上面一樣,用 in 顯示
$ up logs 'error and path in ("/tobi", "/loki")'

### 更複雜的查詢方式
$ up logs 'method in ("POST", "PUT") ip = "207.*" status = 200 duration >= 50'

### 將 JSON 格式的錯誤日誌發送給 jq 工具
$ up logs error | jq

請注意,and 關鍵字是暗含的,雖然你也可以使用它。

冷啟動時間

這是 AWS Lambda 平台的特性,但冷啟動時間通常遠遠低於 1 秒,在未來,我計劃提供一個選項來保持它們在線。

配置驗證

up config 命令輸出解析後的配置,有默認值和推斷的運行時設置 - 它也起到驗證配置的雙重目的,因為任何錯誤都會導致退出狀態 > 0。

崩潰恢復

使用 Up 作為反向代理的另一個好處是執行崩潰恢復 —— 在崩潰後重新啟動伺服器,並在將錯誤的響應發送給客戶端之前重新嘗試該請求。

例如,假設你的 Node.js 程序由於間歇性資料庫問題而導致未捕獲的異常崩潰,Up 可以在響應客戶端之前重試該請求。之後這個行為會更加可定製。

適合持續集成

很難說這是一個功能,但是感謝 Golang 相對較小和獨立的二進位文件,你可以在一兩秒中在 CI 中安裝 Up。

HTTP/2

Up 通過 API 網關支持 HTTP/2,對於服務很多資源的應用和站點可以減少延遲。我將來會對許多平台進行更全面的測試,但是 Up 的延遲已經很好了:

錯誤頁面

Up 提供了一個默認錯誤頁面,如果你要提供支持電子郵件或調整顏色,你可以使用 error_pages 自定義。

{
  "name": "site",
  "type": "static",
  "error_pages": {
    "variables": {
      "support_email": "support@apex.sh",
      "color": "#228ae6"
    }
  }
}

默認情況下,它看上去像這樣:

如果你想提供自定義模板,你可以創建以下一個或多個文件。特定文件優先。

  • error.html – 匹配任何 4xx 或 5xx
  • 5xx.html – 匹配任何 5xx 錯誤
  • 4xx.html – 匹配任何 4xx 錯誤
  • CODE.html – 匹配一個特定的代碼,如 404.html

查看文檔閱讀更多有關模板的信息。

伸縮和成本

你已經做了這麼多,但是 Up 怎麼伸縮?目前,API 網關和 AWS 是目標平台,因此你無需進行任何更改即可擴展,只需部署代碼即可完成。你只需按需支付實際使用的數量並且無需人工干預。

AWS 每月免費提供 1,000,000 個請求,但你可以使用 http://serverlesscalc.com 來插入預期流量。在未來 Up 將提供更多的平台,所以如果一個成本過高,你可以遷移到另一個!

未來

目前為止就這樣了!它可能看起來不是很多,但它已經超過 10,000 行代碼,並且我剛剛開始開發。看看這個問題隊列,假設項目可持續發展,看看未來會有什麼期待。

如果你發現這個免費版本有用,請考慮在 OpenCollective 上捐贈我,因為我沒有任何工作。我將在短期內開發早期專業版,對早期用戶有年費優惠。專業或企業版也將提供源碼,因此可以進行內部修復和自定義。

via: https://medium.freecodecamp.org/up-b3db1ca930ee

作者:TJ Holowaychuk 譯者:geekpi 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國