在雲端上啜飲爪哇
在雲端上啜飲爪哇 王建興 qing.chwang at gmail.com
講者簡介 現職 聖藍科技技術長 譯作 Thinking in Java 4th Edition,  正體中文版 Thinking in Java 2nd Edition,  正體中文版 Essential C++,  正體中文版 專欄 iTHome  電腦報程式人專欄
Agenda 雲端計算的好處 以 Java 發展雲端應用軟體的選項 GAE 簡介 Case Study 結論
關於這個講題 雲端計算的觀念及具體的實作逐漸普及 對 Java 開發者而言, 基於什麼原因需要開發雲端上的軟體系統 若欲開發雲端上的軟體系統,有什麼選項 GAE 是一個適合以 Java 開發的雲端平台,該如何於其中開發雲端軟體系統 使用 GAE 時,和典型的 Java Web 應用軟體開發上,會有那些差異需要考量
雲端計算帶來的好處 對使用者而言 只要能上網,服務隨處隨時可得 對服務提供者而言 快速部署及獲得服務 依實際需求量付費 減少 IT 建置及管理的複雜度 提高服務的規模可擴充性( scalability )
Java 在雲端的選項 基於既有的 IaaS 平台 例: Amazon EC2 基於既有的 PaaS 平台 例: GAE
Amazon 的雲端計算平台 EC2: Elastic Compute Cloud 依需要提供計算能力的服務 EBS: Elastic Block Service 依需要提供備份的服務 S3: Simple Storage Service 資料儲存服務 SQS: Simple Queue Service 分散式的訊息佇列服務 SimpleDB 簡易的結構化資料儲存服務
Amazon EC2 (1/2) 虛擬化的計算環境 透過 Web Service API 來管理一組 server instances 依據用量來收費 時數 Virtual Cores Compute Units 32/64 bits Memory Storage 對外頻寬
Amazon EC2 (2/2) 作業系統,主要是 Unix Linux OpenSolaris AMI Amazon Machine Image 內含你所開發的應用程式、程式庫、資料、以及相關的組態設定
使用 EC2 對開發者的好處 簡化設定 可以立即依需要取得所需數量的伺服器 降低初期投資成本 當服務推出成功時,可以快速擴增規模 減低伺服器管理成本 採購 日常系統管理
在 EC2 上部署 Java Web 應用程式 *Chris Richardson, “Running Java applications on the Amazon Elastic Compute Cloud”
Cloud Tools 開放原始碼專案 提供快速便利的 EC2 部署 提供 32/64 bits  的 AMI CentOS 5.10 安裝: Apache/Tomcat/MySQL/JMeter/JetS3t 設定 Tomcat/MySQL/Apache *http://code.google.com/p/cloudtools/
Java libraries for AWS JetS3t 存取 S3 的一套 API https://jets3t.dev.java.net/ Typica 提供存取 SQS, EC2, SimpleDB 的 API http://code.google.com/p/typica/ SimpleJPA 在 SimpleDB 上實作一部份的 JPA 介面 http://code.google.com/p/simplejpa/
基於 IaaS 平台的優缺點 優點 運用彈性高 可量身訂製打造自需的環境及架構 缺點 需處理較多和系統架構相關的議題 規模擴充性 容錯 需自行管理及設定
基於 PaaS 平台開發應用軟體 PaaS 平台提供者,處理大架構上的技術議題 規模可擴充性 系統容錯能力 系統穩定度 系統安全性 應用系統開發者 專注於應用本身
規模擴展時的議題 當你需要擴展系統規模時 加機器? 加記憶體? 加資料庫伺服器? 調整系統架構? 增加快取伺服器 使用 NoSQL …
這正是為什麼有時候我們需要基於 PaaS 平台來開發的重要原因之一
什麼是 GAE ?  (1/2) Google: Google App Engine  讓你得以在和 Google 自身應用程式所處的相同系統上,開發並且運行 Web 應用程式 Wikipedia: Google App Engine  是個在 Google 所管理的資料中心之上開發及運行 Web 應用程式的平台
什麼是 GAE ? (2/2) GAE  讓你在 Google 所打造的基礎設施之上運行 Web 應用程式 在 GAE 上開發應用程式 開發容易 維護容易 擴充規模也很容易
執行環境及程式語言 採用標準 Java 執行環境 標準化的 Java 技術 JVM Java servlets Java  程式語言 可運行於 JVM 的其他直譯式 / 編譯式語言 JavaScript Ruby Go 也提供 Python 執行環境
成本及預算 用多少付多少 沒有設置成本,也沒有循環費用 一開始使用可毋需付費 提供免費額度的資源,足以支持有每月五百萬次頁面檢視量 500 MB  儲存空間 足夠的  CPU  計算力 足夠的頻寬 依據應用程式所動用的資源計費 儲存空間 頻寬 可以控制應用程式資源使用的上限
行情 *http://code.google.com/intl/en/appengine/docs/billing.html $0.64 Hourly per instance Backends ( B8   class) $0.32 Hourly per instance Backends ( B4   class) $0.16 Hourly per instance Backends ( B2   class) $0.08 Hourly per instance Backends ( B1   class) $0.30 N/A (daily) Always On $0.0001 recipients Recipients Emailed $0.45 gigabytes per month High Replication Storage $0.15 gigabytes per month Stored Data $0.10 CPU hours CPU Time $0.10 gigabytes Incoming Bandwidth $0.12 gigabytes Outgoing Bandwidth Unit cost Unit Resource
架構 Request  Response  Web page transactions Result Browser  URL fetch or E-mail More services  Schedule routine  Static Storage  HTTP / HTTPS * 清大資工鍾葉青教授雲端計算課程講義投影片 Web interface Sandbox Runtime environment Datastore Memcache
GAE 採用 Sandbox 的概念 利用 Sandbox 來做隔離及保護 應用程式運行於一方面安全,一方面又受限的環境中 所施加的限制,都是為了提供 易於擴充規模 隔離安全不受干擾侵犯 的執行環境
GAE 上的諸般限制  例一:網路存取 應用程式僅能對外進行兩種網路存取 以 URL 形式存取 發送電子郵件 若欲連結至應用程式,僅能以兩種協定建立連線 HTTP ( 80 port ) HTTPS( 443 port ) 無法建立任意 TCP/UDP 連線,連至其他伺服器 無法自行建立任何 socket port 供其他應用程式連接 這些 限制是基於安全性考量
GAE 上的諸般限制  例二:檔案系統存取 應用程式無法對檔案系統進行存取 應用程式僅能讀取與應用程式一起打包上傳的檔案 在 GAE 上,任何資料僅能儲存在 Datastore memcache 這些限制是基於規模擴充性及系統安全性
GAE 上的諸般限制  例三:執行時間及方式 程式碼的執行只能用在三種場合 處理來自於 Web 端的請求 排程執行的 task Backend 應用程式在處理來自 Web 端的請求時,得在 30 秒內完成回應 應用程式不能衍生額外的執行緒 這些限制是基於安全性及規模擴充性
GAE 上的 Java 執行環境 (1/2) Java Runtime Environment Java Servlet  JavaServer Pages (JSPs). Java Version Java 6 使用  Java 5  或  Java 6  皆可 Sandbox 上的諸般限制,皆於 JVM 中實作
GAE 上的 Java 執行環境 (2/2) API Java  標準  APIs Java Data Objects (JDO)/ Java Persistence API (JPA)  JavaMail API java.net HTTP API Google Accounts APIs 程式語言 Java JavaScript Ruby Scala Go
GAE 的 Datastore (1/2) GAE 的 Datastore 是一個分散式的資料儲存服務 具規模擴充性 有 transaction 的能力 GAE 的 Datastore 和傳統的關聯式資料庫不同 其中的 data object (稱為 entity ),都擁有一組屬性 Datastore 的 entity 沒有所謂 schema 的觀念
GAE 的 Datastore (2/2) 可透過 JDO/JPA 的 API 來存取 Datastore Datastore 能維持資料的一致性( strong consistent ) Datastore 採用樂觀式並行性控制( optimistic concurrency control )
處理 Datastore 會是在 GAE 上開發應用系統的最大挑戰
Kind 、 Entity 、 Key 、 Property User 傳統關聯式資料庫 Datastore *Cloud Tu @TWJUG User Sport Null Null Favor2 Movie Null Null Favor3 Music Cloud 1 Music Tom 3 Null John 2 Favor1 Name PK Music Favor Cloud Name 1 Key John Name 2 Key Music , Sport , Movie Favor Tom Name 3 Key Kind Table Key PK Property Field Entity Row
Native Datastore 操作 DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Entity employee = new Entity("Employee"); employee.setProperty("firstName", "Antonio"); employee.setProperty("lastName", "Salieri"); Date hireDate = new Date(); employee.setProperty("hireDate", hireDate); employee.setProperty("attendedHrTraining", true); datastore.put(employee);  Kind  Entity  Key  Property *Cloud Tu @TWJUG 在 Entity 的 constructor 中指定。未指定時,系統會自動指派一個 UUID 的 key
用 JDO 的方式描述資料  (1/2) @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Album { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id; @Persistent private String albumURL; @Persistent private String owner; …
用 JDO 的方式描述資料  (2/2) public Album(String _albumURL, String _owner, String _siteProvider) { albumURL = _albumURL; owner = _owner; siteProvider = _siteProvider; status = 0; submitDate = new Date(); } public Long getId() { return id; } public String getAlbumURL() { return albumURL; } …
對 Datastore 進行查詢 Query q = new Query("Person"); q.addFilter("lastName",  Query.FilterOperator.EQUAL ,  lastNameParam); q.addFilter("height",  Query.FilterOperator.LESS_THAN ,  maxHeightParam); PreparedQuery pq = datastore.prepare(q); pq.asIterable();
JDO/Query Language public byte[] getPhoto(long id) { PersistenceManager pm =  PMF.get().getPersistenceManager(); String query = &quot;select from &quot; + Photo.class.getName() + &quot;  where id == &quot;+id; List<Photo> photos = (List<Photo>)  pm.newQuery(query).execute(); if( photos.isEmpty() ) { pm.close(); return null; } Photo p = photos.get(0); Blob content = p.getContent(); byte[] b = content.getBytes(); pm.close(); return b; }
EntityGroup 擁有相同 ParentKey 的 Entity 即屬於同一 EntityGroup 對位在同一 EntityGroup 內 Entity 所進行的操作可在同一 transaction 裡 適合 One to Many 的資料表示方式
EntityGroup User *Cloud Tu @TWJUG 自動產生 RootKey ParentKey Cloud Name 1 Key 自動產生 RootKey ParentKey John Name 2 Key 2 ParentKey Mary Name 3 Key 2 ParentKey Mary Name 4 Key 2 ParentKey Joe Name 5 Key A EntityGroup B EntityGroup
建構 EntityGroup Entity parent = new Entity(&quot;User&quot;); Entity child1 = new Entity(&quot;User&quot;, parent.getKey());  Entity child2 = new Entity(&quot;User&quot;, parent.getKey());  Constructor 未指定其 ParentKey 時,系統會自動產生一個 RootKey child1 、 child2 有相同的 parentkey ,二者可在同一 transaction 進行資料操作 可在 parent 刪除時,一併把 children(child1 、 child2) 刪除 ( 註:非系統本身特性,而是在刪除時在程式碼裡註明一併刪除 ) 一個 transaction 中僅能有一 EntityGroup 進行操作 *Cloud Tu @TWJUG
Google Accounts (1/2) GAE 應用程式能直接運用 Google Account 做為使用者認證的機制 對使用者來說,要使用應用程式毋需註冊新帳號 對開發者來說,不需要另行實作認證機制 GAE 應用程式運用 Google Account 時,能取得一些使用者的資訊,包括 Email 位址 顯示名稱
Google Accounts (2/2) 系統管理者身份 透過 Users API 可以知道目前所服務的使用者,是否為註冊的系統管理員
GAE 提供的 Service (1/2) URL Fetch 使用同於 Google infrastructure 的高速網路來存取網路上的資源 Mail 使用 Google infrastructure 來寄送電子郵件
GAE 提供的 Service (2/2) Memcache 讓應用程式以 key-value 方式,高效存取 in-memory 的快取資料 Image Manipulation 提供操作影像的各種基本操作,包括尺寸變更、裁剪、旋轉、以及翻轉等 支援 JPEG 及 PNG 格式
Scheduled Tasks 依照所設定的排程(例如,每小時 、 每天),來執行對應的工作 也就是傳統所說的“ cron jobs”
Backends (1/2) Backends 是在 GAE 中一種特殊的 instance 沒有執行時間限制 有更多的記憶體空間 有更高的 CPU 限制 適合長期執行的工作任務 有兩種類型 常駐( resident ) 動態( dynamic )
Backends (2/2) 無法依 request 量自動 scale 僅能指定 instance 的量 每個 Backend instance 可對應到 unique 的 URL http://[instance].[backend].[app].appspot.com  未指定 instance 則指定至第一個 instance
GAE 中三種類型的程式碼 Request Handler Scheduled Task Backend
同與異  (1/2) 基於 GAE 開發 Web 應用系統和傳統非雲端平台的開發幾乎是相同的 同樣的程式語言 同樣的標準 API 同樣的 Web 技術及框架
同與異  (2/2) 因應雲端平台所需的特性,也有一些差異 掌握這些差異,就能順利的遷移至雲端開發 Sandbox 中的限制 Web 端執行時間的限制 操作資料的方式大異於傳統關聯式資料庫的存取
GAE SDK 下載 http://code.google.com/intl/zh-TW/appengine/downloads.html 內含一個  Web server 在本地端模擬 GAE 的所有 service 在本地端模擬 sandbox 的行為 小細節處略有差異 提供在 GAE 上可取用的所有 API 及 library
GAE 開發流程 (1/3) 編譯方式 Google Plugin for Eclipse Ant build tool 開發 使用 GAE SDK 中的 API 及 library 搭配標準的 Java 開發環境 部署至本地端的 Web server 進行測試
GAE 開發流程 (2/3) 發行 使用 SDK 所附的工具上傳應用程式 使用工具上傳時需指定開發者的 Google 帳戶及密碼 改版 可利用上傳工具上傳新版本 進行測試 切換至新版運行
GAE 開發流程 (3/3) 系統管理 Web 介面進行系統管理的諸般操作 提供 Web 介面進行系統管理的諸般操作 創建新的應用程式 設定應用程式的域名 將應用程式的運行版本切換至新版本 檢視存取及錯誤的日誌記錄 瀏覽應用程式的 datastore
域名 你可以選擇自有的域名 你也可以選擇使用 GAE 服務提供的免費域名 *.appspot.com 例如: diggirlcloud.appspot.com
克服各種限制 不能自建 Thread 回應必須即時( 30 秒) 沒有檔案系統可運用 僅有 HTTP/HTTPS 及 Email 服務可對外存取資源 Session 中的物件必須 serializable
到雲端上喝 Java 咖啡 重新打造全新的應用程式 掌握 GAE 上的特性及限制 移植舊有的系統至 GAE 資料模式的轉變 非 request/response 處理的程式,需改以排程 Task 或 Backend 來處理 面對 30 秒限制
Case Study Diggirl x Cloud 移植舊有的網站至 GAE 上 Directory Service 擴展既有的 Directory Service ,改以 GAE 做為輔助
Diggirl x Cloud
Diggirl x Cloud for iPhone (1/2)
Diggirl x Cloud for iPhone (2/2)
Diggirl 考慮移植至 GAE 的原因 節省基礎建設投資及開支 主機 頻寬 簡化系統管理及維護 得到極佳的系統可擴充性及穩定性 移植方便 標準化的 Java Servlet/JSP 技術 立足 Google Infrastructure
移植過程的變化 資料儲存 MySQL -> GAE Datastore SQL -> NoSQL (具規模可擴充性) 使用 JDO 來存取( Object-Oriented ) 相簿擷取 利用 URL Fetch Service 擷取(快) 利用 Image Service 製作縮圖(快) 定期的排名計算 Cron Job -> Schedule Tasks
移植過程的困難 資料模型的轉變 因為原來的資料模型就很單純,所以轉換沒有太大問題 原來的資料存取層採用 Business Façade 模式,所以衝擊都被它隔離了 沒有檔案系統 改用 Datastore 中的 Blob 來儲存資料 用 Datastore 儲存圖片資料是相對昂貴的 可改用 Amazon S3 服務來做圖片的儲放及存取
Directory Service 的原有架構 Internet API
Directory Service 的現有問題 需要全年不間斷的提供服務 IT 的維護人力 有時還會遭遇 DDoS 攻擊 全球建置伺服器的成本 資料規模擴充性
採 GAE 輔助的新架構 Internet Internet API API
移植過程的變化 資料模型的轉變 MySQL -> GAE Datastore SQL -> NoSQL (具規模可擴充性) 使用 native 的 Datastore API Normalized -> Denormalized (提升效率) 定期的排名計算 Cron Job -> Schedule Tasks
Schemaless 的設計變動 Denormaliztion 減少 table 的數量 增加效率 目錄中的項目有很多不同的分類,而目錄會依據分類提供項目的排名 舊有的方式是個別再建排名表 新的方式是每個項目多若干個 property ,用來表示它在某分類的排名 例如 Rank_XXX 的值代表它在 XXX 分類下的排名 只要用 sort query 針對 Rank_XXX 進行查詢,即可查出 XXX 分類下依據排名的項目清單
得道昇天後的好處 穩固 快,就是快 解決規模擴充性問題 節省基礎施設投資
結論 Java/JVM 在 PaaS 領域中絕對是扮演舉足輕重的角色 基於 Java 的 PaaS 開發應用系統,可以協助解決眾多的議題 從小規模到大規模都適合在雲端上開發
Special Thanks To Itszero http://twitter.com/itszero http://itszero.org/  Cloud Tu http://cloudtu.blogspot.com/ Gen Tseng
Resources GAE 簡介 http://code.google.com/intl/en/appengine/docs/java/overview.html
Thanks!

在雲端上啜飲爪哇

  • 1.
  • 2.
  • 3.
    講者簡介 現職 聖藍科技技術長譯作 Thinking in Java 4th Edition, 正體中文版 Thinking in Java 2nd Edition, 正體中文版 Essential C++, 正體中文版 專欄 iTHome 電腦報程式人專欄
  • 4.
    Agenda 雲端計算的好處 以Java 發展雲端應用軟體的選項 GAE 簡介 Case Study 結論
  • 5.
    關於這個講題 雲端計算的觀念及具體的實作逐漸普及 對Java 開發者而言, 基於什麼原因需要開發雲端上的軟體系統 若欲開發雲端上的軟體系統,有什麼選項 GAE 是一個適合以 Java 開發的雲端平台,該如何於其中開發雲端軟體系統 使用 GAE 時,和典型的 Java Web 應用軟體開發上,會有那些差異需要考量
  • 6.
    雲端計算帶來的好處 對使用者而言 只要能上網,服務隨處隨時可得對服務提供者而言 快速部署及獲得服務 依實際需求量付費 減少 IT 建置及管理的複雜度 提高服務的規模可擴充性( scalability )
  • 7.
    Java 在雲端的選項 基於既有的IaaS 平台 例: Amazon EC2 基於既有的 PaaS 平台 例: GAE
  • 8.
    Amazon 的雲端計算平台 EC2:Elastic Compute Cloud 依需要提供計算能力的服務 EBS: Elastic Block Service 依需要提供備份的服務 S3: Simple Storage Service 資料儲存服務 SQS: Simple Queue Service 分散式的訊息佇列服務 SimpleDB 簡易的結構化資料儲存服務
  • 9.
    Amazon EC2 (1/2)虛擬化的計算環境 透過 Web Service API 來管理一組 server instances 依據用量來收費 時數 Virtual Cores Compute Units 32/64 bits Memory Storage 對外頻寬
  • 10.
    Amazon EC2 (2/2)作業系統,主要是 Unix Linux OpenSolaris AMI Amazon Machine Image 內含你所開發的應用程式、程式庫、資料、以及相關的組態設定
  • 11.
    使用 EC2 對開發者的好處簡化設定 可以立即依需要取得所需數量的伺服器 降低初期投資成本 當服務推出成功時,可以快速擴增規模 減低伺服器管理成本 採購 日常系統管理
  • 12.
    在 EC2 上部署Java Web 應用程式 *Chris Richardson, “Running Java applications on the Amazon Elastic Compute Cloud”
  • 13.
    Cloud Tools 開放原始碼專案提供快速便利的 EC2 部署 提供 32/64 bits 的 AMI CentOS 5.10 安裝: Apache/Tomcat/MySQL/JMeter/JetS3t 設定 Tomcat/MySQL/Apache *http://code.google.com/p/cloudtools/
  • 14.
    Java libraries forAWS JetS3t 存取 S3 的一套 API https://jets3t.dev.java.net/ Typica 提供存取 SQS, EC2, SimpleDB 的 API http://code.google.com/p/typica/ SimpleJPA 在 SimpleDB 上實作一部份的 JPA 介面 http://code.google.com/p/simplejpa/
  • 15.
    基於 IaaS 平台的優缺點優點 運用彈性高 可量身訂製打造自需的環境及架構 缺點 需處理較多和系統架構相關的議題 規模擴充性 容錯 需自行管理及設定
  • 16.
    基於 PaaS 平台開發應用軟體PaaS 平台提供者,處理大架構上的技術議題 規模可擴充性 系統容錯能力 系統穩定度 系統安全性 應用系統開發者 專注於應用本身
  • 17.
    規模擴展時的議題 當你需要擴展系統規模時 加機器?加記憶體? 加資料庫伺服器? 調整系統架構? 增加快取伺服器 使用 NoSQL …
  • 18.
  • 19.
    什麼是 GAE ? (1/2) Google: Google App Engine 讓你得以在和 Google 自身應用程式所處的相同系統上,開發並且運行 Web 應用程式 Wikipedia: Google App Engine 是個在 Google 所管理的資料中心之上開發及運行 Web 應用程式的平台
  • 20.
    什麼是 GAE ?(2/2) GAE 讓你在 Google 所打造的基礎設施之上運行 Web 應用程式 在 GAE 上開發應用程式 開發容易 維護容易 擴充規模也很容易
  • 21.
    執行環境及程式語言 採用標準 Java執行環境 標準化的 Java 技術 JVM Java servlets Java 程式語言 可運行於 JVM 的其他直譯式 / 編譯式語言 JavaScript Ruby Go 也提供 Python 執行環境
  • 22.
    成本及預算 用多少付多少 沒有設置成本,也沒有循環費用一開始使用可毋需付費 提供免費額度的資源,足以支持有每月五百萬次頁面檢視量 500 MB 儲存空間 足夠的 CPU 計算力 足夠的頻寬 依據應用程式所動用的資源計費 儲存空間 頻寬 可以控制應用程式資源使用的上限
  • 23.
    行情 *http://code.google.com/intl/en/appengine/docs/billing.html $0.64Hourly per instance Backends ( B8   class) $0.32 Hourly per instance Backends ( B4   class) $0.16 Hourly per instance Backends ( B2   class) $0.08 Hourly per instance Backends ( B1   class) $0.30 N/A (daily) Always On $0.0001 recipients Recipients Emailed $0.45 gigabytes per month High Replication Storage $0.15 gigabytes per month Stored Data $0.10 CPU hours CPU Time $0.10 gigabytes Incoming Bandwidth $0.12 gigabytes Outgoing Bandwidth Unit cost Unit Resource
  • 24.
    架構 Request Response Web page transactions Result Browser  URL fetch or E-mail More services Schedule routine Static Storage HTTP / HTTPS * 清大資工鍾葉青教授雲端計算課程講義投影片 Web interface Sandbox Runtime environment Datastore Memcache
  • 25.
    GAE 採用 Sandbox的概念 利用 Sandbox 來做隔離及保護 應用程式運行於一方面安全,一方面又受限的環境中 所施加的限制,都是為了提供 易於擴充規模 隔離安全不受干擾侵犯 的執行環境
  • 26.
    GAE 上的諸般限制 例一:網路存取 應用程式僅能對外進行兩種網路存取 以 URL 形式存取 發送電子郵件 若欲連結至應用程式,僅能以兩種協定建立連線 HTTP ( 80 port ) HTTPS( 443 port ) 無法建立任意 TCP/UDP 連線,連至其他伺服器 無法自行建立任何 socket port 供其他應用程式連接 這些 限制是基於安全性考量
  • 27.
    GAE 上的諸般限制 例二:檔案系統存取 應用程式無法對檔案系統進行存取 應用程式僅能讀取與應用程式一起打包上傳的檔案 在 GAE 上,任何資料僅能儲存在 Datastore memcache 這些限制是基於規模擴充性及系統安全性
  • 28.
    GAE 上的諸般限制 例三:執行時間及方式 程式碼的執行只能用在三種場合 處理來自於 Web 端的請求 排程執行的 task Backend 應用程式在處理來自 Web 端的請求時,得在 30 秒內完成回應 應用程式不能衍生額外的執行緒 這些限制是基於安全性及規模擴充性
  • 29.
    GAE 上的 Java執行環境 (1/2) Java Runtime Environment Java Servlet JavaServer Pages (JSPs). Java Version Java 6 使用 Java 5 或 Java 6 皆可 Sandbox 上的諸般限制,皆於 JVM 中實作
  • 30.
    GAE 上的 Java執行環境 (2/2) API Java 標準 APIs Java Data Objects (JDO)/ Java Persistence API (JPA) JavaMail API java.net HTTP API Google Accounts APIs 程式語言 Java JavaScript Ruby Scala Go
  • 31.
    GAE 的 Datastore(1/2) GAE 的 Datastore 是一個分散式的資料儲存服務 具規模擴充性 有 transaction 的能力 GAE 的 Datastore 和傳統的關聯式資料庫不同 其中的 data object (稱為 entity ),都擁有一組屬性 Datastore 的 entity 沒有所謂 schema 的觀念
  • 32.
    GAE 的 Datastore(2/2) 可透過 JDO/JPA 的 API 來存取 Datastore Datastore 能維持資料的一致性( strong consistent ) Datastore 採用樂觀式並行性控制( optimistic concurrency control )
  • 33.
    處理 Datastore 會是在GAE 上開發應用系統的最大挑戰
  • 34.
    Kind 、 Entity、 Key 、 Property User 傳統關聯式資料庫 Datastore *Cloud Tu @TWJUG User Sport Null Null Favor2 Movie Null Null Favor3 Music Cloud 1 Music Tom 3 Null John 2 Favor1 Name PK Music Favor Cloud Name 1 Key John Name 2 Key Music , Sport , Movie Favor Tom Name 3 Key Kind Table Key PK Property Field Entity Row
  • 35.
    Native Datastore 操作DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Entity employee = new Entity(&quot;Employee&quot;); employee.setProperty(&quot;firstName&quot;, &quot;Antonio&quot;); employee.setProperty(&quot;lastName&quot;, &quot;Salieri&quot;); Date hireDate = new Date(); employee.setProperty(&quot;hireDate&quot;, hireDate); employee.setProperty(&quot;attendedHrTraining&quot;, true); datastore.put(employee); Kind Entity Key Property *Cloud Tu @TWJUG 在 Entity 的 constructor 中指定。未指定時,系統會自動指派一個 UUID 的 key
  • 36.
    用 JDO 的方式描述資料 (1/2) @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Album { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id; @Persistent private String albumURL; @Persistent private String owner; …
  • 37.
    用 JDO 的方式描述資料 (2/2) public Album(String _albumURL, String _owner, String _siteProvider) { albumURL = _albumURL; owner = _owner; siteProvider = _siteProvider; status = 0; submitDate = new Date(); } public Long getId() { return id; } public String getAlbumURL() { return albumURL; } …
  • 38.
    對 Datastore 進行查詢Query q = new Query(&quot;Person&quot;); q.addFilter(&quot;lastName&quot;, Query.FilterOperator.EQUAL , lastNameParam); q.addFilter(&quot;height&quot;, Query.FilterOperator.LESS_THAN , maxHeightParam); PreparedQuery pq = datastore.prepare(q); pq.asIterable();
  • 39.
    JDO/Query Language publicbyte[] getPhoto(long id) { PersistenceManager pm = PMF.get().getPersistenceManager(); String query = &quot;select from &quot; + Photo.class.getName() + &quot; where id == &quot;+id; List<Photo> photos = (List<Photo>) pm.newQuery(query).execute(); if( photos.isEmpty() ) { pm.close(); return null; } Photo p = photos.get(0); Blob content = p.getContent(); byte[] b = content.getBytes(); pm.close(); return b; }
  • 40.
    EntityGroup 擁有相同 ParentKey的 Entity 即屬於同一 EntityGroup 對位在同一 EntityGroup 內 Entity 所進行的操作可在同一 transaction 裡 適合 One to Many 的資料表示方式
  • 41.
    EntityGroup User *CloudTu @TWJUG 自動產生 RootKey ParentKey Cloud Name 1 Key 自動產生 RootKey ParentKey John Name 2 Key 2 ParentKey Mary Name 3 Key 2 ParentKey Mary Name 4 Key 2 ParentKey Joe Name 5 Key A EntityGroup B EntityGroup
  • 42.
    建構 EntityGroup Entityparent = new Entity(&quot;User&quot;); Entity child1 = new Entity(&quot;User&quot;, parent.getKey()); Entity child2 = new Entity(&quot;User&quot;, parent.getKey()); Constructor 未指定其 ParentKey 時,系統會自動產生一個 RootKey child1 、 child2 有相同的 parentkey ,二者可在同一 transaction 進行資料操作 可在 parent 刪除時,一併把 children(child1 、 child2) 刪除 ( 註:非系統本身特性,而是在刪除時在程式碼裡註明一併刪除 ) 一個 transaction 中僅能有一 EntityGroup 進行操作 *Cloud Tu @TWJUG
  • 43.
    Google Accounts (1/2)GAE 應用程式能直接運用 Google Account 做為使用者認證的機制 對使用者來說,要使用應用程式毋需註冊新帳號 對開發者來說,不需要另行實作認證機制 GAE 應用程式運用 Google Account 時,能取得一些使用者的資訊,包括 Email 位址 顯示名稱
  • 44.
    Google Accounts (2/2)系統管理者身份 透過 Users API 可以知道目前所服務的使用者,是否為註冊的系統管理員
  • 45.
    GAE 提供的 Service(1/2) URL Fetch 使用同於 Google infrastructure 的高速網路來存取網路上的資源 Mail 使用 Google infrastructure 來寄送電子郵件
  • 46.
    GAE 提供的 Service(2/2) Memcache 讓應用程式以 key-value 方式,高效存取 in-memory 的快取資料 Image Manipulation 提供操作影像的各種基本操作,包括尺寸變更、裁剪、旋轉、以及翻轉等 支援 JPEG 及 PNG 格式
  • 47.
    Scheduled Tasks 依照所設定的排程(例如,每小時、 每天),來執行對應的工作 也就是傳統所說的“ cron jobs”
  • 48.
    Backends (1/2) Backends是在 GAE 中一種特殊的 instance 沒有執行時間限制 有更多的記憶體空間 有更高的 CPU 限制 適合長期執行的工作任務 有兩種類型 常駐( resident ) 動態( dynamic )
  • 49.
    Backends (2/2) 無法依request 量自動 scale 僅能指定 instance 的量 每個 Backend instance 可對應到 unique 的 URL http://[instance].[backend].[app].appspot.com 未指定 instance 則指定至第一個 instance
  • 50.
    GAE 中三種類型的程式碼 RequestHandler Scheduled Task Backend
  • 51.
    同與異 (1/2)基於 GAE 開發 Web 應用系統和傳統非雲端平台的開發幾乎是相同的 同樣的程式語言 同樣的標準 API 同樣的 Web 技術及框架
  • 52.
    同與異 (2/2)因應雲端平台所需的特性,也有一些差異 掌握這些差異,就能順利的遷移至雲端開發 Sandbox 中的限制 Web 端執行時間的限制 操作資料的方式大異於傳統關聯式資料庫的存取
  • 53.
    GAE SDK 下載http://code.google.com/intl/zh-TW/appengine/downloads.html 內含一個 Web server 在本地端模擬 GAE 的所有 service 在本地端模擬 sandbox 的行為 小細節處略有差異 提供在 GAE 上可取用的所有 API 及 library
  • 54.
    GAE 開發流程 (1/3)編譯方式 Google Plugin for Eclipse Ant build tool 開發 使用 GAE SDK 中的 API 及 library 搭配標準的 Java 開發環境 部署至本地端的 Web server 進行測試
  • 55.
    GAE 開發流程 (2/3)發行 使用 SDK 所附的工具上傳應用程式 使用工具上傳時需指定開發者的 Google 帳戶及密碼 改版 可利用上傳工具上傳新版本 進行測試 切換至新版運行
  • 56.
    GAE 開發流程 (3/3)系統管理 Web 介面進行系統管理的諸般操作 提供 Web 介面進行系統管理的諸般操作 創建新的應用程式 設定應用程式的域名 將應用程式的運行版本切換至新版本 檢視存取及錯誤的日誌記錄 瀏覽應用程式的 datastore
  • 57.
    域名 你可以選擇自有的域名 你也可以選擇使用GAE 服務提供的免費域名 *.appspot.com 例如: diggirlcloud.appspot.com
  • 58.
    克服各種限制 不能自建 Thread回應必須即時( 30 秒) 沒有檔案系統可運用 僅有 HTTP/HTTPS 及 Email 服務可對外存取資源 Session 中的物件必須 serializable
  • 59.
    到雲端上喝 Java 咖啡重新打造全新的應用程式 掌握 GAE 上的特性及限制 移植舊有的系統至 GAE 資料模式的轉變 非 request/response 處理的程式,需改以排程 Task 或 Backend 來處理 面對 30 秒限制
  • 60.
    Case Study Diggirlx Cloud 移植舊有的網站至 GAE 上 Directory Service 擴展既有的 Directory Service ,改以 GAE 做為輔助
  • 61.
  • 62.
    Diggirl x Cloudfor iPhone (1/2)
  • 63.
    Diggirl x Cloudfor iPhone (2/2)
  • 64.
    Diggirl 考慮移植至 GAE的原因 節省基礎建設投資及開支 主機 頻寬 簡化系統管理及維護 得到極佳的系統可擴充性及穩定性 移植方便 標準化的 Java Servlet/JSP 技術 立足 Google Infrastructure
  • 65.
    移植過程的變化 資料儲存 MySQL-> GAE Datastore SQL -> NoSQL (具規模可擴充性) 使用 JDO 來存取( Object-Oriented ) 相簿擷取 利用 URL Fetch Service 擷取(快) 利用 Image Service 製作縮圖(快) 定期的排名計算 Cron Job -> Schedule Tasks
  • 66.
    移植過程的困難 資料模型的轉變 因為原來的資料模型就很單純,所以轉換沒有太大問題原來的資料存取層採用 Business Façade 模式,所以衝擊都被它隔離了 沒有檔案系統 改用 Datastore 中的 Blob 來儲存資料 用 Datastore 儲存圖片資料是相對昂貴的 可改用 Amazon S3 服務來做圖片的儲放及存取
  • 67.
  • 68.
    Directory Service 的現有問題需要全年不間斷的提供服務 IT 的維護人力 有時還會遭遇 DDoS 攻擊 全球建置伺服器的成本 資料規模擴充性
  • 69.
    採 GAE 輔助的新架構Internet Internet API API
  • 70.
    移植過程的變化 資料模型的轉變 MySQL-> GAE Datastore SQL -> NoSQL (具規模可擴充性) 使用 native 的 Datastore API Normalized -> Denormalized (提升效率) 定期的排名計算 Cron Job -> Schedule Tasks
  • 71.
    Schemaless 的設計變動 Denormaliztion減少 table 的數量 增加效率 目錄中的項目有很多不同的分類,而目錄會依據分類提供項目的排名 舊有的方式是個別再建排名表 新的方式是每個項目多若干個 property ,用來表示它在某分類的排名 例如 Rank_XXX 的值代表它在 XXX 分類下的排名 只要用 sort query 針對 Rank_XXX 進行查詢,即可查出 XXX 分類下依據排名的項目清單
  • 72.
    得道昇天後的好處 穩固 快,就是快解決規模擴充性問題 節省基礎施設投資
  • 73.
    結論 Java/JVM 在PaaS 領域中絕對是扮演舉足輕重的角色 基於 Java 的 PaaS 開發應用系統,可以協助解決眾多的議題 從小規模到大規模都適合在雲端上開發
  • 74.
    Special Thanks ToItszero http://twitter.com/itszero http://itszero.org/ Cloud Tu http://cloudtu.blogspot.com/ Gen Tseng
  • 75.
    Resources GAE 簡介http://code.google.com/intl/en/appengine/docs/java/overview.html
  • 76.