Up:在幾秒鐘內部署無伺服器應用程序
去年,我為 Up 規划了一份藍圖,其中描述了如何以最小的成本在 AWS 上為大多數構建塊創建一個很棒的無伺服器環境。這篇文章則是討論了 Up 的初始 alpha 版本。
為什麼關注 無伺服器 ?對於初學者來說,它可以節省成本,因為你可以按需付費,且只為你使用的付費。無伺服器方式是自愈的,因為每個請求被隔離並被視作「無狀態的」。最後,它可以無限輕鬆地擴展 —— 沒有機器或集群要管理。部署你的代碼就行了。
大約一個月前,我決定開始在 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,則會檢測並使用
start和
build` 腳本。
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 staging
或 up production
和 up 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 來大大減少延遲。
當 type
為 static
時,默認情況下的工作目錄是 .
,但是你也可以提供一個 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 或 5xx5xx.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
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive