通向Golang的捷径【20. 使用 Go 语言的 GAE】
20.1 GAE 介紹
GAE 即為谷歌 App 引擎 (Google App Engine), 是一種云計算的解決方案, 它可執行用戶的 web 應用, 并將用戶數據保存到 Google 架設的大量設備中, 而無須考慮服務器, 網絡連接, 操作系統和數據存儲等問題, 云端通常會被視為一個資源集合, 但它的維護只會交由 Google 來完成, 因此你只需開發自己的應用, 云端會將你的應用發送給用戶, 并會在連接到網絡的某臺設備上, 運行你的應用, 同時你的軟件只需支付一些資源使用費(比如 CPU 的處理時間, 網絡帶寬, 磁盤用量, 內存用量等), 當出現瞬間峰值時, 云平臺可自動為應用程序增加資源, 當附加的資源不再需要時, 可減少附加的資源, 因此伸縮性是云計算的優勢之一, 協同應用 (多人創建的不同應用需一起運行, 不同應用之間需共享數據以及通訊), 可向用戶提供服務的應用, 以及執行大量計算的應用, 應當優先選擇云計算平臺, 同時云端應用的典型用戶接口, 即為瀏覽器.
CAE 發布于 2008 年, 并支持 Python 應用,2009 年增加了 Java 應用的支持,2011 年增加了 Go 應用的支持,它的官方主頁為 http://code.google.com/appengine/.
GAE 為構建和部署 web 應用, 提供了一種可靠的具有伸縮性的簡單方式, 保守估計有一百萬個應用被保存在appspot.com 站點上 (每個應用都有自己的特定域名), 它們都在使用 App 引擎, 這是一種服務平臺環境, 它比云架構 (比如 Amazon EC2) 更高級, 可實現資源共享的最高效率.
Sandbox
如果你的應用運行在一個安全環境 Sandbox 中, 它可限制來自于底層操作系統的訪問, 同時允許 App 引擎將web 請求在多個服務器之間進行分發, 而起始服務器和終點服務器需要滿足一些傳輸要求.sandbox 可將你的應用, 封閉在一個安裝可靠的環境中, 同時它與硬件, 操作系統以及 web 服務器的位置無關, 當然也存在以下限制:
? web 應用不能將數據, 寫入服務器的文件系統, 同時應用只能讀取更新文件, 應用必須使用 App 引擎的
數據集, 內存緩沖或其他服務, 來處理請求中包含的所有數據.
? 運行代碼只能為一個 web 請求, 或是一個隊列任務, 又或是一個調度任務, 提供所需的響應, 同時響應必須在 60s 內產生, 一個請求處理器不能產生一個子進程, 或是在響應發送后, 依然在執行.
? 基于網絡連接, 應用只能通過 URL 地址或是郵件服務, 實現其他 PC 機的訪問, 而其他 PC 機也只能通
過標準端口的 HTTP(或 HTTPS) 請求, 與 web 應用進行交互.
web 應用可使用的服務
? 基于 Google 提供的 Bigtable, 數據可保存在 GAE 的數據集中, 這是一個分布式的數據存儲服務, 它可
提供一個查詢引擎和傳輸功能, 并能隨著數據的增加, 而使存儲區自動增加, 所以它并不是一個傳統的關
系數據庫, 在經典 SQL 數據庫中, 上述的添加方式不被允許, 但是 GAE 提供了一種類 SQL 的查詢語言
GQL, 其中的數據對象被稱為 entity(實體), 它可包含一個類型和一組屬性, 基于一個特定的種類, 可查詢和獲取數據庫的實體, 同時也可保存實體的屬性, 同時實體的屬性值也應當符合所支持的數值類型, 實體可進行編組, 編組可視為傳輸任務的一個單元, 因此一次傳輸中必須包含一個實體編組, 所以在應用中,無須給出數據庫的處理, 但是必須提供實體所包含的所有數據, 同時可使用優化的并發控制進行更新, 以便獲得最新的數據更新.
? 使用集成的 Google Account, 可為 app 進行用戶驗證.
? URL 獲取功能, 使用該服務, 可使 app 可訪問互聯網資源, 比如 web 或其他數據.
? app 可使用內建的郵件服務.
? memcache(內存緩存) 是一種高性能的內存緩沖 (使用鍵值對), 適合于短期使用且無須保存到數據集的
數據, 比如臨時數據, 或是來自于數據集的數據副本 (以實現高速訪問).
? 圖片的維護功能
? 任務調度和任務隊列: 除了響應 web 請求之外,app 還可執行其他任務, 并能在一個配置好的調度規則中,運行不同的任務, 比如每天的調度或每小時的調度, 也可選擇將任務, 添加到應用的隊列中, 比如處理請求的后臺任務.
20.2 Go 云處理
在 2010 年 5 月 10 日的 Google I/O 大會上, 發布了支持 Go 語言的 GAE 版本, 這是一個實驗版本, 只提供給已注冊的測試者, 而第一個正式版本發布于 2011 年 7 月 21 日, 在本書的編寫時間 (2012 年 1 月) 下,Go App引擎 SDK 的最新版本為 1.6.1(發布于 20111-12-13), 它支持 Linux 和 Mac OS X(10.5 或更高版本) 系統, 并同時支持 32bit 和 64bit 系統, 所使用的 Go 工具鏈版本為 r60.3, 其中給出的一些修改, 無法完全實現向后兼容,SDK API 的版本為 3.
在 App 引擎中運行的 Go app, 可使用 64bit x86 編譯器 (6g) 進行編譯, 由于樣機中只能運行一個線程, 因此所有的并發協程將運行在一個操作系統的線程中, 所以面對客戶端請求不會出現 CPU 的并行.
Go 語言是 App 引擎支持的首個可編譯語言, 與其他兩種語言相比,Go 具備一些優勢, 如下:
? 與 Java 相比: Go 具有更快的啟動時間, 以及更好的并發性能
? 與 Python 相比: Go 具有更好的執行性能
20.3 安裝 GAE SDK
20.3.1 安裝
在 Google App Engine 官網 (http://code.google.com/appengine/downloads.html) 上, 找到與目標平臺相符的GAE SDK 壓縮 (zip) 安裝包. 如果目標平臺為 Ubuntu11.10(64bit Linux), 可下載go_appengine_sdk_linux_amd64-1.6.1.zip. 在所需的目錄下 (比如 home 目錄), 解壓該文件, 其中將包含一個目錄google_appengine, 它包含了 Go 開發環境所需的完整 App Engine.
在google_appengine 目錄下, 包含了開發, 構建和測試本地 app 的所有工具, 其中將給出一個AppEngine服務器 (可用于測試), 同時還包含了一個數據集, 可用于數據存儲, 也就是在云端的AppEngine服務器上, app的執行也需要進行數據存儲, 同時其他 API 和工具允許你模擬一個 AppEngine, 以實現 app 的開發和測試, 在支持 Go 語言的 AppEngine 環境中, 也包含了 Go 語言的編譯器, 包和附帶工具.
GAE-Go 與 Go 的區別
在 GAE-Go 中包含了完整的 Go 系統, 幾乎所有的標準庫, 因此只有少數任務, 無法在 AppEngine 環境中實現, 如下:
? 只包含穩定包, 同時 syscall 包已被剔除
? 不支持 cgo(與 c 庫的交互功能), 在 GAE 項目中, 無法使用二進制庫 (Go 語言或其他語言), 因此 GAE
項目需要編譯和鏈接所有源碼
? 不支持 go install
? CAE 的發布時間通常慢于 Go 語言
另外 Sandbox 環境 (參見 20.1 節) 的限制必須考慮, 否則打開一個 socket 或是寫入文件時, 將返回一個
os.EINVAL 錯誤. 同時 GAE-Go 和 Go 的附帶工具是彼此獨立的, 如果只需在 GAE 中進行開發, 則不要
使用 Go 的附帶工具.
在google_appengine 目錄下, 還包含了少量的 Python 腳本, 它將完成 GAE 所需的基本任務, 首先需確認這些腳本可以執行 (如果無法執行, 可使用命令chmod +x *.py), 同時需將該目錄加入到 PATH 環境變量中, 以便在調用這些腳本時, 無須指定它們的路徑, 比如 bash shell, 可在.bashrc 或.profile 文件中, 加入以下命令:
其他細節
? 如果已配置了一個可工作的 Go 環境,AppEngine 應實現獨立安裝, 也就是與 Go 環境互不影響, 尤其是在操作系統中, 不要修改 Go 開發環境,GAE-Go 有自己的獨立環境, 它的目標路徑為 ~/google_appengine/goroot
? 應當下載 GAE 的文檔, 可在官網中, 下載 google-appengine-docs-20111011.zip 文件并解壓
? 在 GAE 中, 大量使用 Python 語言, 同時 Mac OS X 和 Linux 系統已默認安裝了 Python 環境, 如果未
安裝 Python, 可在官網頁面www.python.org, 下載 Python 2.5
? CAE-Go 的庫和 SDK 也是開源軟件, 可在頁面http://code.google.com/p/appengine-go/中找到, 并可使用命令hg clone https://code.google.com/p/appengine-go/下載
? app 包含的所有 Go 包, 將構建成一個獨立的可執行文件,Go 程序可將需處理的請求派發給該文件, 這與Java SDK 和 Python SDK 的工作機制并不相同
在 20.8 節中, 將看到 CAE 云端如何與 web 應用進行連接, 在執行這一步驟之前, 需要在本地 GAE 環境中,實現 app 的開發, 測試和運行, 同時本地 GAE 環境可模擬云端環境.
20.3.2 檢查與測試
安裝檢查
為保證 google_appengine 目錄中包含的 Go 環境, 能夠正常工作, 可利用 dev_appserver.py 腳本, 啟動本地的 AppEngine 服務器, 如果看到以下輸出信息:
則表示一切正常.
運行 app demo
在 SDK 中包含了一些 app demo, 調用這些 demo, 可了解當前的 GAE 開發環境是否正常.
? 進入google_appengine/demos 目錄, 可看到一些文件夾, 比如 helloworld,guestbook 等.
? 進入上述的 demo 目錄, 并執行命令dev_appserver.py helloworld, 這將導致 Go 程序的自動編譯, 自動鏈接和自動運行.
? 上述命令可給出一些警告和輸出信息, 如果在 8080 端口上, 執行 helloworld 應用, 可使用http://localhost:8080, 之后 helloworld 應用將運行在本地 AppEngine 服務器中, 并能為 8080 端口的用戶請求, 提供對應的服務.
? 打開瀏覽器, 并輸入http://localhost:8080 地址, 可顯示一個網頁, 頁面內容為:
這時 web 應用已成功運行在本地 AppEngine 服務器中. 以下是 helloworld 應用的源碼,
例 20.1 helloworld.go
以上的 web 應用很簡單 (參見第 15 章), 并在 init 函數中, 啟動了所有的處理器函數, 同時在處理器函數
(handle) 中, 包含了所需的網頁.
20.4 自定義 app(helloworld)
以下將構建與上一節 helloworld demo 相同的一個 web 應用.
20.4.1 創建一個簡單的 http 處理器
為自定義 app 創建一個目錄, 并命名為 helloapp, 該 app 包含的所有文件都放入該目錄中, 在 helloapp 目錄中, 創建另一個目錄 hello, 其中將包含 Go 源碼 (實現 hello 包), 在 hello 目錄中, 創建一個文件helloworld2.go, 并在文件中包含以下代碼 (以下代碼與上一節的 app demo 基本相同),
例 20.2 helloworld2_version1.go
注意包名 hello, 在編寫單獨的 Go 程序時, 需要在源碼中放入一個 main 包, 但在 GAE-Go 環境中, 運行時管理將為 web 應用, 提供一個 main 包和 http 監聽器, 因此可將代碼放入一個選定的包中, 這里是 hello 包, 其次, 在 AppEngine 上運行的 web 應用 (Go 語言), 可通過 web 服務器, 實現與外部世界的通訊, 這與獨立的web 應用 (Go 語言) 很相似 (參見第 15 章), 所以需要導入 http 包, 并為不同的 url 地址, 定義不同的處理器函數, 同時不會包含 main 函數, 因此處理器的配置將移入 init 函數, 而 web 服務器的啟動將由 GAE 完成, 所以 hello 包可響應任意請求, 并能回傳一個包含 Hello, world! 消息的影響.
20.4.2 創建配置文件 app.yaml
所有的 GAE app 都需要提供一個 yaml 配置文件 app.yaml, 它將包含可提供給 GAE 的 app 元數據 (yaml是一種文本文件的格式, 常用于開源項目, 如果需要深入了解, 可參考網頁www.yaml.org), 該文件可告知 AppEngine, 如何實現運行時管理, 以及當前 web 應用可處理那些 URL 地址, 同時還將為 app demo 保存一個app.yaml 副本, 并會放置在 helloapp 目錄中.
以下將給出當前 app 的文件結構:
只有 app.yaml 是一個必須使用的名稱, 而目錄名,Go 文件名和包名可使用不同的名稱, 但為了便于使用, 上述名稱應使用相同或類似的命令, 同時應用的頂層目錄 (helloapp) 應包含 app 后綴.
app.yaml 文件能被 AppEngine 讀取和解析, 并能在以下情況中, 執行 web 應用.
app.yaml 文件可使用 #, 標記一個注釋, 并能在文件中, 包含以下內容:
? application: 可給出 web 應用的名稱, 這里是 helloworld, 在開發過程中, 可給出任意名稱, 該名稱將在
AppEngine 中注冊 web 應用, 因此需選擇一個唯一的名稱, 同時該名稱也接受更新.
? version: 可指定 app 的版本, 事實上 GAE 可并發運行同一個 app 的不同版本, 但其中一個版本需指定
為默認應用, 它可使用字母, 數字和連號符 (-), 因此可將 T2-31 視為一個測試版本號, 并將 P2-1 視為一
個產品版本號.
? runtime: 可標記 app 的開發語言 (可使用 Java 和 Python), 如果需要對 app 進行版本更新, AppEngine可保存之前的版本, 之后可在管理員控制臺中, 回滾到之前的版本.
? api_version: 指定當前 SDK 中 Go API 的版本, 由于存在與之前版本不兼容的可能性, 如果使用之前的
API 版本, 生成了 app 的早期 (開發) 版本, 雖然 GAE 可運行該 app, 但通常會有一個時間限制, 所以必
須將 app 更新到新的 API 版本, 使用 gofix 工具可滿足更新要求.
? handlers: 將包含一個路由表, 它將告知 GAE, 會有那些請求會發送給服務器, 每個輸入請求都需匹配
url 后續的正則表達式 (在本地開發時,http://localhost:8080/的后續地址將進行匹配, 如果在云端運行,
http://appname.appspot.com/的后續地址將進行匹配).
如果請求的 url 地址與首個 url 模式相匹配, 對應的 script(腳本) 將執行, 在當前文件中, 所有請求都能與
/.* 正則表達式相匹配, 因此 Go 程序需處理所有請求, 在 dev_appserver.py 文件中, 已給出了 _go_app
字符串, 但在云端 App Engine 服務器上, 將被忽略.
在 helloworld demo 的 app.yaml 文件中, 包含了另一個處理器, 如下:
有些文件 (static_files, 靜態文件), 比如圖形文件, 無法進行修改 (本例為 favicon.ico), 這類文件將放置在另一個 AppEngine 服務器的公共緩存中, 以便將它們更快地傳遞給用戶, 如果 web 應用中包含了大量的圖形文件, 則應放置在一個單獨的目錄中, 為了便于使用, 可將目錄命名為 static 或 images.
當開發 app 時,upload 給出了必須上傳到云端的內容, 如果 app 中包含了大量的圖形文件 (images/(.ico.gif|*.jpg)|), 應將本地 images 目錄下的所有文件, 都上傳到 AppEngine 服務器.
在 GAE 運行的大多數應用中, 都會使用模板文件, 這些文件可保存在 app 的根目錄, 或是放置在一個特殊目錄 tmpl 中. 因此一個 GAE 應用的通用目錄結構, 如下:
在控制臺中, 進入 helloapp 目錄, 并輸入以下命令:
上述兩個命令都可啟動 web 服務器, 并監聽 8080 端口的請求, 在瀏覽器中輸入http://localhost:8080/, 可測試 web 應用是否運行成功, 之后可在瀏覽器中, 看到輸出結果Hello, world!. 同時在服務器的控制臺中, 可看到以下輸出信息:
其中<-(A) 表示服務器就緒,<-(B) 表示服務器已編譯和運行了 Go 程序, <-? 表示 app 已接收到請求, 并響應了一個 html 頁面.
當服務器終止運行, 或是尚未啟動時, 客戶端 (瀏覽器) 給出 http://localhost:8080/請求, 將在瀏覽器 (Firefox)中, 打印出一條消息, 如下:
20.4.3 開發的迭代過程
在 app 開發中, 需要對源碼文件進行修改, 也就是對源碼進行編輯和保存, 當完成源碼文件的修改后, 可重新編譯, 并重啟本地 app, 同時無須使用 dev_appserver.py. 因此可在 web 服務器運行時, 對helloworld2.go 文件進行編輯, 也就是修改Hello, world! 字符串, 在瀏覽器中重新輸入http://localhost:8080/, 可看到 helloworld2.go文件的修改結果, 而上述任務也可編寫一個 Rails 或 Django 應用, 以便自動實現.
為了終止 web 服務器, 可在控制臺中, 按下 Ctrl+C 組合鍵, 之后在控制臺中, 可看到以下消息:
其中<-(D) 表示 web 服務器可獲知 app 的修改和重新編譯,<-(E) 表示 web 服務器已經終止運行.
20.4.4 GoClipse IDE 的用法
? 使用 Window / Preferences / Go 菜單, 可指向 GAE-Go 的根目錄.
? 使用 Run / External Tools / External Tools Configuration / Program 菜單, 可在對話框中, 點擊 New按鈕, 可創建一個新的配置文件, 如下:
再使用 Apply / Run 菜單, 可運行 app
在 GoClipse IDE 中, 配置一個外部工具 (可參考頁面 http://code.google.com/p/goclipse/wiki/DeployingToGoogleAppEngineFromEclipse), 可使 app 的開發更加簡單.
20.5 用戶服務
GAE 可基于 Google 的大量硬件設備, 提供一些有價值的服務, 如 20.1 節所述,GAE 可提供用戶服務, 因此可在你的 web 應用中, 集成 Google 的賬號驗證, 基于用戶服務, 需要使用 web 應用的用戶, 可使用 Google 賬號, 并登錄到你的 web 應用, 因此用戶服務可簡化 web 應用的私有化.
編輯 helloworld2.go 文件, 加入所需的賬號驗證服務, 如下
例 20.3 helloworld2_version2.go
在瀏覽器中重新載入之前的頁面, 這時在你的 web 應用中, 將出現一個鏈接, 并可重定向到 Google 的登錄頁面 (本地版本), 這可用于 web 應用的測試, 如果在瀏覽器中任意輸入一個用戶名,web 應用將獲取到一個偽造的 user.User 數值 (基于用戶名產生的數值), 在 AppEngine 中運行的 web 應用, 可使用戶看到Google 的賬號登錄頁面, 之后如果成功登錄, 將重定向到你的 web 應用, 否則將重定向到賬號創建頁面.
用戶 API
為了實現上述操作, 需要導入 GAE 提供的一些 Go 包, 比如 appengine 和 appengine/user 包, 在處理器(handler) 中, 首先將創建一個與當前請求 r 關聯的 Context(上下文) 對象, 如c := appengine.NewContext?, appengine.NewContext 函數可返回一個名為 c 的 appengine.Context 對象, 它可被 Go 語言的 AppEngineSDK 的大多數函數所使用, 以便與 AppEngine 服務進行通訊, 從這個上下文對象中, 可檢查用戶是否完成了登錄操作, 即u := user.Current?.
如果登錄成功,user.Current 可返回一個 user.User 指針 (可表示一個有效用戶), 否則 user.Current 將返回 nil, 如果登錄不成功, 將滿足u == nil 條件, 之后將使用url, err := user.LoginURL(c, r.URL.String()), 使得用戶瀏覽器重定向到 Google 的賬號登錄頁面, 其中的第二個參數r.URL.String(), 即為當前請求的 url 地址, 當成功登錄后,Google 的賬號登錄機制可產生一個重定向 (即定向到所請求的 url 地址), 同時會設定一個 Location頭, 并返回一個 http 狀態碼 302(表示所請求的 url 地址已經找到).
LoginURL() 函數可返回一個錯誤碼, 同時該函數不太可能出現錯誤, 但是在實際編程中, 推薦檢查該錯誤碼, 并顯示檢查結果, 如下:
當用戶登錄后, 可顯示一個與用戶賬號關聯的私有信息, 即fmt.Fprintf(w, ”Hello, %v!”, u), 在這種情況下, fmt.Fprintf函數可使用 user.User 的 String 方法, 以獲取用戶賬號的字符串, 更多細節可參考頁面 http://
code.google.com/appengine/docs/go/users/.
20.6 表單處理
從 15.6 和 15.7 節可知, 在 web 應用中, 經常會使用 template(模板) 包, 這也適用于 GAE app, 在以下代碼中, 可允許用戶輸入一段文本, 首先它可顯示一個游客 (guestbook) 表單 (基于/(根地址) 處理器), 之后該表單將投遞給 sign(登錄) 處理器, 而不是作為文本, 被添加到響應 html 中, 同時 sign 函數可調用r.FormValue, 獲取到表單數據, 并將數據傳遞給 signTemplate.Execute, 同時 signTemplate.Execute 又可將生成的模板, 傳遞給 http.ResponseWriter. 修改 helloworld2.go 文件, 實現上述功能, 如下:
例 20.4 helloworld2_version3.go
20.7 數據存儲集合
web 應用需要從來自于用戶的 html 表單中, 收集所需的信息, 通常情況下, 將會預定義一些固定的信息位置, 以便從表單中獲取或寫入, 而 GAE 則提供了 DataStore(數據存儲) 功能, 可將數據保存在多個 web 服務器, 甚至是多個設備上, 以此實現一個分布式數據庫 (非關系數據庫), 所以用戶的下一次請求可傳遞給另一臺 PC機的 web 服務器, 但 GAE 組織架構將在一個簡單的 API 中, 細心操作所有數據的分布式處理, 響應處理和負載平衡, 同時還提供了一個強大的查詢引擎.
以下將對之前的示例進行擴展, 首先將創建一個 Greeting 結構, 其中包含了作者, 內容和時間等信息, 因此需要保存該結構, 所以需為 entity 程序創建一個匹配的數據結構 (即處理器能夠操作的對象), 通常是一個結構類型, 在運行的程序中, 放置在內存中的結構所包含的數據, 都來自于 entity 的 DataStore.
程序可接收的 url 地址, 如下
? url 根地址 (/): 可獲取所有已保存的請求, 并通過 template 包, 將其顯示出來, 參見 15.7 節.
? url 地址 (/sign): 將一個新的請求, 保存到 DataStore 中.
在以下示例中, 還需要導入 appengine/datastore 包,
例 20.5 helloworld2_version4.go
sign 處理器構建了一個 Greeting 變量 g, 其中使用表單內容進行初始化, 之后使用了 datastore.Put() 進行存儲,DataStore 內部將為每次數據存儲, 生成一個唯一的 key, 為了實現上述功能, 在 Put 函數的調用中, 將使用datastore.NewIncompleteKey(c, ”Greeting”, nil) 作為第 2 個參數 (該函數需傳入一個結構類型名), 第 3 個參數即為 Greeting 變量 g 的指針.
datastor 包還提供了一個 Query 類型, 用于 DataStore 的查詢, 在根地址處理器中, 將構建一個查詢變量 q, 其中將使用請求的 Greeting 對象, 并以日期的降序方式, 對 DataStore 進行查詢, 查詢結果限制在 10 個以內.
查詢結果將保存在一個結構中, 即一個 Greeting 類型的 slice, 之后調用 q.GetAll(c, &greetings), 將 slice 轉存到 greetings 中, 并檢查查詢結果中是否存在錯誤.
當上述操作都通過后, 可將查詢結果的日期數據, 都合并到一個模板中,
它可實現一個 range 結構, 參見 15.7.6 節. 再次測試 helloworld2.go 文件的修改, 在兩次請求之間, 關閉瀏覽器, 這時你會發現, 依然可看到之前的請求.
清除服務器的 DataStore
在開發過程中,web 服務器將使用一個本地 DataStore, 對 web 應用進行測試, 其實就是一個臨時文件, 請求數據會一直保留在臨時文件中,web 服務器在沒有得到指令的情況下, 不會清除這些文件, 如果在開發過程中, 需要清空 DataStore 并重新啟動, 可在啟動服務器時, 加入–clear_datastore 選項,
調試
在 Go 環境中, 可運行 gdb 調試器 (可參考頁面http://golang.org/doc/debugging_with_gdb.html), 可將 gdb附加到一個運行進程中, 在通常情況下, 可使用 dev_appserver.py, 并在 localhost:8080 地址上, 啟動 app, 使用命令 ps ax | grep _go_app, 可查找到 _go_app 的路徑和 PID, 這時可將 gdb 附加到 _go_app 進程, 之后可給出一個 http 請求, 因此 app 的運行將遇到, 在代碼中設置的斷點, 如果對 Go 代碼進行了修改, 必須重新編譯并執行另一個 _go_app 進行調試.
20.8 云端上傳
在上一節的示例中, 使用了 Google 的賬號驗證功能, 它可實現消息發送, 顯示其他已離開用戶的信息, 或是在基本功能上實現更復雜的功能, 因此需要在云端進行開發, 如果你的應用需動用大量的資源, 則應當進行調整,因為 GAE 處理具有自動化的伸縮性.
首先你需要申請一個 Google 賬號, 比如使用 gmail 郵件地址, 作為你的用戶名, 在頁面www.google.com/accounts可快速申請一個 Google 賬號.
在頁面https://appengine.google.com/出現的 App Engine Administration Console(App Engine 管理員控制臺) 中, 可創建和管理 App Engine web 應用.
完成 SMS 驗證后, 可獲得 Create an Application(創建 web 應用) 頁面, 選擇 application identifier(應用標識, 它必須是一個唯一名稱, 在 GAE 包含的所有應用中), 比如 ib-tutgae.appspot.com, 加上 http://前綴, 則可變成 web 應用的 url 地址, 后續無法對應用標識進行修改, 因此可在應用名中, 加入個人喜歡, 以生成一個私有 app, 或是加入公司名稱, 以生成一個商用 app, 之后可選擇 application title(應用標題), 這在 app 中可見, 同時后續可對標題進行修改, 比如 Tutorial GAE App, 去除默認的 Google 驗證功能和高速 Datastore 功能 (Google Authentication,High Replication Datastore), 以便在 GAE 中運行 web 應用時, 不會產生費用問題, 之后點擊 Create Application 按鈕, 將出現一條消息 Application Registered Successfully (應用注冊成功), 之后可將 app 應用上傳到云端, 如下:
? 編輯 app.yaml 文件, 修改 web 應用的數值, 將 helloworld 變更為 ib-tutgae
? 為了將 web 應用上傳到 GAE 并進行配置, 可使用 appcfg.py 腳本命令, 即 appcfg.py update helloapp/
當你的 Google 賬號驗證成功后,web 應用將上傳到運行, 并能在 App Engine 中開發了.
如果需要更新 web 應用的新版本, 首先需要處理代碼中出現的錯誤, 完成 app 的編譯后, 才可將 app 上傳到云端, 否則上傳沒有任何意義, 使用頁面http://application-id.appspot.com, 可在云端上, 對 web 應用進行測試, 其中 application-id 即為唯一的應用標識, 這里是http://ib-tutgae.appspot.com, 這類測試同時支持工作在Windows,Linux,OS X 平臺的瀏覽器.
對 web 應用進行監控
進入https://appengine.google.com/頁面, 可給出一個列表, 其中包含了你的所有應用, 點擊某個應用, 將彈出它的控制面板, 其中可提供 web 應用的監控服務, 如下圖,
監控功能是相當重要的, 因為 web 應用工作在云端, 這意味著你只能進行訪問, 無法掌控代碼運行的狀態或是進行調試, 而從監控功能的圖形結果中可知,web 應用的負載狀況 (每秒的請求數), 消耗的資源數 (CPU 用量, 帶寬, 存儲用量, 數據復制, 后臺用量), 費用產生的明細, 可查看負載信息, 即每個 url 地址的請求數和 cpu 負載, 或是查看錯誤信息, 即 web 應用出現錯誤時, 所給出的信息, 數據面板 (Data Panel) 和 Datastore 查看器 (Viewer) 可查看和查詢你的 Datastore 數據, 使用 Administration 查看方式, 還可得到一些特殊信息, 以及GAE 文檔的鏈接, 選擇 Main/Logs 路徑, 可參看每次請求的日志, 以及錯誤異常的日志記錄 (而異常不會顯示給用戶).
總結
以上是生活随笔為你收集整理的通向Golang的捷径【20. 使用 Go 语言的 GAE】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vbs模拟post请求上传文件
- 下一篇: 分布式限速器