登入  |  English
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
技術專欄 國民雲端-當 Python 遇上 GAE

國民雲端-當 Python 遇上 GAE

簡介

講到 PaaS (platform as a service),我們很難忽略 Google 的 GAE (Google App Engine),這個由近 10 年來的網路巨人在 2008 年推出的雲端平台,雖然在技術的定位與根本上和 Amazon 的 AWS 有著本質上的不同,在坊間卻常常被拿來討論比較。雖然對 GAE 的評價毀譽參半(請參考下列的「優缺點」部分),但 GAE 在雲端平台中的重要性可見一斑。

在 GAE 中,可以使用的語言有兩個:Java 與 Python,雖然社群中有很多專精其他語言的高手會用各種方式掛上其他語言(比如說用 jRuby 掛 RoR 上去),但這些畢竟在官方版本中沒有支援。跟 Java 相比,Python 的確是個較冷門的語言,在 GAE 上面的速度也相對比 GAE 上面的 JVM 慢了一些,但是除了筆者個人對 python 的熱愛以外,GAE 其實對 Python 下了不小的功夫。先別說 Guido van Rossum-Python 的發明人此刻就坐在 Google 的辦公室裡思考 GAE 與 Python 的未來,Python 這個快速開發的語言真的會讓它的駕馭者省掉非常非常多寫程式的時間,再說,連 Java 這麼複雜的語言都能學會了,Python 的上手對您來說絕對輕而易舉。

筆者認為,目前 GAE 平台最適合以下幾種活動:

  1. 新行動裝置 APP 的後端資料中心
  2. 新 Web Start-up 團隊想要試試水溫
  3. 中小企業的網站建置

建議應用範圍

新行動裝置 APP 的後端資料中心

不管是 iOS,Android 還是 Windows Mobile,都可以用 GAE 作為行動裝置 App 的後端資料中心。

以 LBS 服務來說,不管是要找餐廳、夜店,還是景點,我們都需要一個後端資料中心記錄地點資訊、使用者評論,甚至任何 App 社交所產生的資訊,並在適當的時候傳回行動裝置。如此一來,行動裝置才不會因為塞滿資料而變得肥大,不同使用者之間的資料也才能夠互動,達成社交服務的目的。

用 GAE 作為行動裝置 APP 初期的資料中心真是再適合不過了。行動裝置 APP 服務最核心的地方,就是行動裝置 APP 的使用者經驗,一開始的時候,所有資源都會投入到行動裝置 APP 的使用經驗本身,沒有多餘的資源照料資料中心的主機建置、軟體維護,甚至安全性的問題。

這時候,GAE 就提供了一個很完美的方案,主機建置、軟體維護、安全性都由 Google 一手包辦,我們只需要規劃我們服務的資料庫,並在 GAE 裡面實作出來,APP 就可以上路了!

新 web start-up 團隊想要試試水溫

創業是一件很辛苦的事情,與在大公司當RD非常不同的其中一項,就是我們常常面臨資源不足,必須在「完美的方案」與「堪用」之間作取捨,這時候,GAE 就變成了一個「堪用下的完美解決方案」。

GAE 有個免費額度,在使用量沒有超出免費額度時,它都是免費的。新的 Web Start-up 缺乏資金和資源,可以先用 GAE 做出網站 prototype,試試看市場的反應,慢慢用 lean start-up 的方法與精神摸索調整。在這個過程中,只要您的網站沒有大量的數值運算、資料、流量,GAE 可以讓您在尋找 market-product-fit 的過程中以近乎零的成本運行。

一旦找到 market-product-fit,衝破免費的界線怎麼辦?這時候我們有兩個處理方式:

  1. Google 情義相挺至今,在我們找到 market-product-fit後,我們一定非常願意付錢
  2. 既然找到 market-product-fit,漸漸得到資源,我們有能力搬家了!

筆者所在的團隊──好險網團隊,打的就是這個主意。

中小企業的網站建置

一般而言,如果不是網路業,中小企業網站的流量都不高,資源消耗也不大,因此在 GAE 上面的網頁寄存 (Hosting) 近乎免費(如果不是免費的話)。既然如此,又何必花錢花時間尋找其他的 Hosting 呢?不管其他家的寄存服務穩定性再高,也難以超越 Google。再者,跟中小企業主說:「我們用的是 Google 的雲端啦!」,印象分數馬上大增。

如果再全面一點,帶入 Google Apps,從 Email 系統、文書處理系統、公司行事曆系統、公司知識分享系統到網站等等,都用 Google 打造完備,軟硬體成本增加不多,卻交出整套產品線,從此客戶的名片上不再印著 yahoo.com,而是 客戶公司.com,這種全方位的解決方案用 GAE 再適合不過了。

申請步驟

被稱為「國民雲端」當然有其原因,只要具備 Google 的帳號,就能夠使用這個國民雲端,而幾乎所有的工程師都有個 Google (Gmail) 帳號,意即我們已經可以開始使用 GAE 的服務了。既然這麼棒,那就來實際操作,弄個小的 web app 試試。

  1. 首先,我們必須先申請一個 Google 的帳號,請點這裡申請(如果已經有 Google 的帳號,請跳過這一步)
  2. 有了自己的 Google 帳號以後,請到這裡啟用 GAE,語言選擇請選擇 Python 喔。啟用的過程中會使用手機認證。
  3. 認證完成後,我們到這裡來開啟我們的第一個應用程式。
  4. 填完表單送出以後,我們可以由以下連結 https://appengine.google.com/dashboard/nonedeployed?app_id=s~ 進入此應用程式的管理介面。

申請的步驟至此已經全部完成,快摩拳擦掌,進入應用程式建置的部份。

範例教學

要寫 GAE 的應用程式,不裝 Google 應用服務引擎 SDK 是難以為繼的,請到這裡下載 Python 版本的 Google 應用服務引擎 SDK,安裝到自己的機器上。

Hello World!

如果學過一些程式語言,我們一定懂得什麼叫做「那些年我們學過的 Hello World!」,沒錯,這個就是 Python 在 GAE 上面的 Hello World,請接招。

請在我們喜歡的地方建立一個資料夾,就命名為 helloworld,然後在裡面新增兩個空白的檔案,分別叫作 helloworld.py 與 app.yaml,檔案架構看起來就像這樣:

[helloworld]-------- helloworld.py
                |--- app.yaml

在 helloworld.py 內放入印出 Hello world, GAE! 的程式碼:

print 'Content-Type: text/plain'
print ''
print 'Hello world, GAE!'

app.yaml 是 GAE 平台會讀的設定檔,請寫入以下內容:

application: 我們應用程式的id
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: helloworld.py

在 handlers 的設定中,我們指定把所有的 request 都交給 helloworld.py 這個 Python script 處理。

我們在 local 上跑跑看吧,用 terminal或是「命令提示字元」到 helloworld 資料夾打入以下命令,local 的 GAE web server 就開始運行了:

google_appengine/dev_appserver.py helloworld/

接著用瀏覽器指到 https://localhost:8080/ 位址,我們就看到 Hello world, GAE!了,成功! (按下 Ctrl-C 可以把 local 的 GAE web server 停下來)

簡單的留言板系統

把 helloworld.py 的內容全部換成以下的程式碼,我們的 helloworld 就立刻變身成一個簡單的留言板系統了:

import cgi
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db

class Greeting(db.Model):
    author = db.StringProperty(multiline=False)
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
    def get(self):
        self.response.out.write('')
        greetings = db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")
        for greeting in greetings:
            self.response.out.write('%s wrote:' % greeting.author)
            self.response.out.write('
%s
' % cgi.escape(greeting.content)) # Write the submission form and the footer of the page self.response.out.write(""" <form method="post"> <div><input name="author" type="text" /></div> <div><textarea cols="60" rows="3" name="content"></textarea></div> <div><input type="submit" value="Sign Guestbook" /></div> </form> """) def post(self): greeting = Greeting() greeting.author = self.request.get('author') greeting.content = self.request.get('content') greeting.put() self.redirect('/') application = webapp.WSGIApplication( [('/', MainPage)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()

看起來很複雜,其實一點也不,這個程式可以分成以下四個部分來解釋:

控制單元 (Controller)

以下這段程式碼主導了 request 在 helloworld.py 中如何傳遞:

application = webapp.WSGIApplication(
                                 [('/', MainPage)],
                                 debug=True)

('/', MainPage) 這裡指定了只要 request 的目的是根目錄,就用 MainPage 這個 class 裡面的程式碼來處理。

當然,我們也可以擴充,只要把 [('/', MainPage)] 改成 [('/', MainPage),('/sos_cool', SoSCool)],馬上就可以把目的是 /sos_cool 的 request 交由目前尚未實作的 SoSCool class 來處理。

資料單元 (Model)

資料單元包括下列程式碼:

class Greeting(db.Model):
    author = db.StringProperty(multiline=False)
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)

Greeting 繼承了 db.Model,代表所有 Greeting 中定義的欄位都會對應到 Google Big Table 資料庫中的欄位。細節如下:

  • author = db.StringProperty(multiline=False) 定義 author 欄位,其資料型態是單行的字串,記錄留言人的身分。
  • content = db.StringProperty(multiline=True) 定義 content 欄位,其資料型態是可以分行的字串,記錄留言的內容。
  • date = db.DateTimeProperty(auto_now_add=True) 定義 date 欄位,其資料型態是日期,記錄留言的時間。

如此一來,輕輕鬆鬆地就定義了留言板的資料表與細節。

HTTP Post 方法

request 進入 MainPage 後,如果是用 http post 方法送出,就會交由 MainPage 內的 post function 處理。

    def post(self):
        greeting = Greeting()
        greeting.author = self.request.get('author')
        greeting.content = self.request.get('content')
        greeting.put()
        self.redirect('/')

在這個 function 中,我們新建一個 Greeting 物件來儲存新的留言,接下來,從 request 中讀出留言與作者,塞入 Greeting 物件中,再使用 greeting.put() 把整個物件寫到 Google Big Table 資料庫中。

最後,我們用 get 方法重新導向到根目錄下。

HTTP Get 方法

Get 方法在這裡主要用於呈現過去的 10 則留言,並提供 html 表單給使用者留言,我們不討論 html 的部分,但是我們要研究一下在 python GAE 的程式設計中,要如何把資料從資料庫中找出來:

    greetings = db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")
    for greeting in greetings:
        self.response.out.write('%s wrote:' % greeting.author)
        self.response.out.write('
%s
' % cgi.escape(greeting.content))

學過 SQL 的人對 GAE 的 GQL 格式一定不陌生,在這裡,我們用 GAE 的 GQL 語法 SELECT * FROM Greeting ORDER BY date DESC LIMIT 10 把最新 10 筆留言從 big table 找出來。

然後,我們用 for 迴圈把每一筆資料都寫到 http 的 response 中,這樣就大功告成了。

如何部署

大功告成,但是如何上傳到 GAE 上面,讓全世界都可以使用呢?

GAE 把部署這件事情弄得超級簡單,只要 terminal 或是「命令提示字元」到 helloworld 上層目錄中,下達以下命令,一步步地跟著作,部署程式即可輕鬆完成:

appcfg.py update helloworld/

現在您可以用瀏覽器看:

https://我們應用程式的id.appspot.com

我們的應用程式正在 GAE 上面運作著。

優缺點

終於要開始討論 GAE 的優劣了,因為所有的語言與平台設計都有其目的與邏輯,當然也有它們擅長的地方,與非常不拿手的領域,以下是筆者認為 GAE 的正與負。

優點

GAE 的優點有以下三點:

  1. 介面容易:只要上 Google 就可以申請與管理了,得來全不費功夫。
  2. 服務穩定:Google 的穩定性不容質疑!
  3. 服務擴張容易:只要拿錢來,多少要求都幫您辦到,scale up 超容易──只是要很多錢。

缺點

缺點?我最愛說缺點了,各位看倌們請看了:

  1. 系統封閉:因為安全性問題,語言與 Python SDK 的很多地方都被閹割,需要繞道解決,更別說有太多現成的 opensource 專案裝不上去了。而且因為系統封閉,照 GAE 寫成的程式就只能在 GAE 上面使用,非常沒有彈性。
  2. 資料庫難用:不僅難用,備份與搬動資料還異常困難。沒關係,反正 CloudSQL 應該快出來了。
  3. 真的太貴了:新的收費機制上線了以後,真的太貴了,好多人都因為費用的因素搬家了。

結語

GAE 出來的時候大家都寄予厚望,可是幾乎所有我遇到的 GAE 使用者都只把它當作玩具,沒有非常認真得用它建置大型應用程式,其主要原因就是因為上述缺點的第一與第二點。

但是不可諱言的,GAE 這些特性非常適合某些小型系統,如果您有以下三種系統要設計實作,不妨考慮 GAE,說不定您也會愛上這樣用它:

  1. 新行動裝置 APP 的後端資料中心
  2. 新 Web Start-up 團隊想要試試水溫
  3. 中小企業的網站建置



自由軟體鑄造場電子報 : 第 187 期 PaaS:程式語言開發在雲端「Programming in Paas」(上)
標籤: GAE,   Google App Engine,   Google,   PaaS,   platform as a service,   雲端,   python,  
分類: 技術專欄



評論 

 
0 #1 BLUE 2014-05-31 10:52
您好 請問一下 GAE 是否夠使用android app 做存取呢?