Python 是 Rackspace 的核心技術
簡介
要成為託管服務行業的領導者,您必須快速且靈活。透過使用 Python 來實現我們的企業資料系統,Rackspace 可以快速有效地更改其內部系統,以跟上行業和我們自身業務流程的變化。我們透過一個名為“CORE”的中央客戶資訊系統來實現這一點,該系統同時用於客戶關係管理 (CRM) 和企業資源規劃 (ERP)。Python 和 CORE 是使 Rackspace 能夠提供我們狂熱支援 (Fanatical Support™) 和更快客戶服務的關鍵因素。
背景
Rackspace 的中央客戶資料庫最初是一個簡單的 ERP 系統,用於配置和跟蹤託管伺服器。它最初只是一個小的 PHP 頁面集合,這些頁面對於 Rackspace 客戶群開始時數百臺伺服器來說做得很好。
隨著 Rackspace 的發展,這個小的 PHP 系統成為了 Rackspace 的業務中心。每次出現自動化流程的機會時,它都會被納入該系統。
幾年後,結果是一個由數千個 PHP 頁面和模組組成的龐大且無法維護的混亂局面,這些頁面和模組主要由一個人編寫和維護。PHP(當時的版本 3)的限制被拉得很薄,該系統對於一個人來說維護量太大,而且很難引入新人來幫助它。

Rackspace 託管服務在最先進的資料中心中提供定製伺服器 放大
我們第一次嘗試更新系統是在 PHP 版本 4 釋出時。此版本承諾提供更好的面向物件功能,而現在正是 Rackspace 為該專案投入更多人員的時候。
該系統從頭開始進行了完全重新設計,包括新的資料庫架構和應用程式設計策略。此時,我們將該專案重新命名為“CORE”,它是 Core Objects Reused Everywhere 的首字母縮寫,以反映 CORE 的總體設計目標:在公司的所有系統中實現模組化和可重用性。考慮到這個目標,我們的團隊開始使用 PHP 的面向物件功能進行工作。
雖然我們能夠重新調整應用程式並增加功能,但該專案最終還是失敗了,這主要是由於在使用 PHP 提供的物件框架時遇到的問題。
記憶體洩漏、不一致的介面、不一致的內部資料模型、隨機釋放的物件、儘管明確使用引用但仍有多個物件副本、內部 PHP 錯誤以及無法追蹤的程式碼故障幾乎使在 PHP 中完成此任務變得不可能。
即使在我們獲得了相對穩定的程式碼庫之後,我們仍然遠未達到 Core Objects Reused Everywhere 的目標,因為我們不得不偏離純粹的面向物件方法,只是為了解決 PHP 中固有的問題。很明顯,PHP 不適合我們的大規模、任務關鍵型專案。必須找到新的解決方案。
CORE 中的 Python
我們一直認為 Python 是實現我們企業系統的絕佳候選者,但最初它被放棄了,轉而基於我們已經擁有的 PHP 中的現有(龐大)程式碼庫進行構建。當時,我們認為可以透過引入更好的結構化系統設計在 CORE 中成功使用 PHP。
不幸的是,這不足以克服我們在 PHP 中遇到的其他問題,因此我們重新評估了我們的情況。Python 2.2 的第一個 alpha 版本最近釋出,我們決定開始使用該版本中可用的新功能開發新的 CORE 框架。
內省的力量
編寫新框架的首要任務之一是構建其資料庫介面。
Python 的內省模型隨著 Python 2.2 的釋出而得到了顯著增強。我們決定使用它來構建基於符合 DBI 2.0 標準的資料庫聯結器的通用資料庫介面類。在這種方法中,元類將所有資料庫查詢抽象為單個乾淨的 API,而不是手動編寫查詢或特定於表的包裝器。
我們建立此元類的後代,為每個表建立一個 API。每個表的類都包含一些描述資料庫中列的類常量。這樣,我們可以快速簡單地將新表新增到整體 API,而無需擔心任何特定表的實現細節。
該 API 還使用元資料來自動驗證和轉換傳遞給資料庫的值。這是透過“規範化器”函式完成的,該函式將透過 API 傳遞的 Python 資料型別轉換為有效的 SQL 值。該函式還驗證資料庫或 Python 不一定檢查的型別和格式,例如電話號碼和郵政編碼。
在任何地方重用物件
資料庫 API 完成後,我們在其之上建立了第二層類。這個更高級別的 API 實現了特定應用程式的業務邏輯,例如聯絡人管理或故障單處理。它還防止使用者執行與 Rackspace 的業務實踐不一致的操作,或分配會導致資料庫中其他型別的高階資料損壞的資料。
透過建立第二層,我們實現了最初的 Core Objects Reused Everywhere 目標。整個公司的程式設計師開始使用此 API 來實現應用程式功能的介面。這不需要與我們的 API 開發團隊進行太多互動,並且可以在不必擔心誤用 API 的情況下完成。
雖然我們主要為中央企業應用程式 CORE 設計了該 API,但它在 Rackspace 的許多其他系統中得到了重用。例如,一個小組在該 API 之上構建了一個 SOAP 伺服器,以便從他們的 PHP 應用程式訪問它。其他應用程式直接使用該 API,看到我們的工作如此輕鬆地與其他系統重用和整合,這令人非常欣慰。
將 Python 與 Apache 整合
在 API 就位後,我們開發 CORE 的下一個任務是找到一個有用的模板模組,將我們的 Python 程式碼與在 Apache Web 伺服器上執行的 HTML 頁面整合在一起。
在查看了許多可用的基於 Python 的模板模組後,我們選擇建立自己的簡單解析器。我們的方法是將伺服器端模板頁面轉換為 Python servlet,其輸出由 HTTP 伺服器傳送到使用者的瀏覽器。
雖然這是一個相當簡單的練習,但我們確實遇到了一些源於 CORE 資料庫元類設計的問題。我們發現,像元類所做的那樣在執行時更改類和模組違反了 Python 可選的受限執行環境施加的指南。由於我們認為受限執行是支援持久 Web 模組的必要元件,因此我們選擇使用 CGI 而不是 mod_python 或類似的持久解決方案來部署 CORE。
由於快速硬體和多臺伺服器很容易獲得,並且由於我們的模板解析器預編譯並快取其生成的 Python servlet 程式碼,因此 CGI 解決方案足以滿足我們的需求。它還允許我們解決諸如資料庫連線池和在 Python 之外限制執行環境之類的問題。
單元測試
得益於 Python 附帶的單元測試模組,我們的專案在投入生產時出現的錯誤比我們使用 PHP 時想象的要少得多。在使用 PHP 進行維護期間,總是存在一個問題,即一個地方的更改是否會破壞應用程式另一部分中的其他內容。
現在,我們在設計每個 API 時都會為每個 API 編寫單元測試。這意味著我們可以透過執行整個 API 的單元測試來驗證一個模組中的更改以及它對所有其他模組的影響。
自從引入 Python 和單元測試以來,我們在已部署的應用程式中看到的錯誤的性質已轉變為主要包括使用者介面中的錯誤,例如佈局問題或錯誤的事件處理。
現在,很少有錯誤來自 API 本身,即使有,通常也是由於應用程式部署期間糟糕的版本管理或 DBA 協調造成的。Python 無法解決開發過程中的 _所有_ 問題,但它確實為我們減少了關鍵系統缺陷的數量。
文件
缺乏文件是我們之前開發工作中的一個主要問題。我們嘗試了幾種工具和策略來記錄我們的 PHP 工作,但最終都失敗了。程式碼變化太快,而當時可用於 PHP 的程式碼級文件工具又過於繁瑣,難以證明為使文件正確解析所需付出的努力是值得的。此外,儘管經過仔細的規劃和編碼策略,PHP 和 HTML 的混合使用使得程式碼的解讀和理解更加困難。
幸運的是,Python 在設計時就考慮到了文件,它為模組、類和方法使用了“文件字串”。由於文件實際上是語言本身的一部分,並且 pydoc 是 Python 發行版中的一個標準模組,因此很容易將 API 文件提取為 HTML 和其他格式。
隨著時間的推移,我們發現 Python 的語法結構使得程式碼非常易讀,這本身就對文件化和維護程式碼的整體任務有所幫助。
結論
Python 極大地改進了 CORE 專案的開發流程,並加快了開發速度和釋出速度,這使我們能夠跟上 Rackspace 不斷變化的業務流程。
Python 使我們能夠建立一個複雜的動態資料模型,該模型靈活且易於使用,用於抽象資料庫操作。有了它,我們實現了“核心物件在任何地方重用”的目標。
Python 整合的單元測試和文件工具極大地增強了我們部署和維護更穩定、無錯誤產品的能力。
最終,我們成功開發了一款企業應用程式,該應用程式在交付 Rackspace Managed Hosting 的 “狂熱支援、無與倫比的速度和託管行業無限的靈活性” 的承諾中發揮著重要作用。
關於作者
Nick Borko 是內部應用程式開發總監,也是 Rackspace 企業資料庫應用程式 CORE 的專案經理。 Rackspace Managed Hosting 是為中小型企業提供託管服務的領導者。 所有客戶平臺都包括最先進的資料中心、定製伺服器、可突發連線、99.999% 的正常執行時間 SLA、專職客戶經理、即時緊急響應以及全天候 24 小時訪問現場專家技術人員,以支援所有硬體和核心軟體。 Rackspace 成立於 1998 年,總部位於德克薩斯州聖安東尼奧,為 80 多個國家/地區的客戶管理伺服器。