Python 如何使基於 Java 的 StubHub 受益

發表於2013-07-23

自2006年以來,Python 已經相當流行,你可以看到越來越多的初創公司在他們開始自己的業務時選擇 Python作為主要語言,例如:

Netflix – 線上電視節目和電影公司
Dropbox – 最流行的檔案同步和共享工具
YouTube – 分享線上視訊
Disqus – 線上討論和評論服務
OpenStack – 用於構建公共雲和私有云的全開放原始碼,全 Python 基礎構建

當這些初創公司把這個優雅利落的語言作為基礎設施來支援其業務的快速增長而得到越來越多的利益時,我在考慮我們 StuhbHub (一個基於 Java 生態系統的公司)怎樣也可以從中獲益,節省工作時間,並顯著提高生產力,我會解釋 Python 是什麼?為什麼選擇 Python ,並向你展示用 Python 為我們的日常工作提供解決方案。

Python是什麼 ? 為什麼選擇Python ?

Python是一種解釋型的,物件導向的動態語言,像Java一樣同樣是跨平臺的。與傳統的主流語言如 Java / C + + 相比,程式設計師們喜歡它是由於以下原因:

1. Python 是一種多用途的語言

我們知道,每一種語言都有其自身的優勢或劣勢,例如有些人會用 C++ 寫執行在Windows作業系統平臺上的遊戲,但沒有人會用 C++ 去建網站。好訊息是你幾乎可以利用 Python 處理任何工作,例如:web 應用,桌面 GUI 應用,Linux 指令碼或其他任何方便的工具,並且作為”膠水語言”你甚至可以在 Python 程式碼中呼叫像 Java/C++ 等其他語言,這意味著你已有的程式碼庫可以重用。

2. Python 更有生產力

一般來說, 當我們談及 Java 和 Python時,最顯著的區別是作為動態語言 Python 不需要編譯這一步。這其實就意味著”生產力”。

還記得我們如何驗證 Java 程式碼的修改嗎? 尤其是在 StubHub,我們有一個相當大的程式碼庫。

  1. 修改你的 Java 程式碼 (1分鐘)
  2. 使用 ant/maven 把你的 Java 程式碼編譯為位元組碼 (5分鐘)
  3. 重啟 Jboss/Tomcat 來部署你的應用程式(5分鐘)
  4. 開啟瀏覽器檢視變化

這裡的痛點是:假設你有一個 bug 修復需要1分鐘,但你必須等待至少10分鐘,才能在瀏覽器中看到變化,更糟糕的是,如果所做的修復並不能正常工作,因此,又要花費下一個10分鐘只是為了做構建和部署。

當你使用 Python 處理的話,就相當容易了。

  1. 修改你的 Python 程式碼(1分鐘)
  2. F5 重新整理瀏覽器檢視變化

恭喜! 你在每次迭代修改上都節省了十分鐘的時間。

考慮一下每位開發者每天有多少次修改程式碼,像 StubHub 這樣的龐大組織又有多少開發者,你可以計算下你總共可以節省多少工時,這可能大得超乎你的想象。

3. 優雅,整齊,緊湊的 Python

還有另一個主要的優點。Python的語法相當酷,我曾有一次用 Python 和 Java 去實現同樣的功能,與 Java 相比 Python 僅僅用了一半的程式碼行數做了同樣的事情。 基於此,這就是為什麼人們喜歡用虛擬碼來驗證想法或通過編寫 Python 程式碼,實現一個快速原型。這能很快地讓你知道你的想法或原型是否可行,然後你可以為你的生產環境用 Java 重寫程式碼。這總好過你在一開始用 Java 編碼,卻最終發現你的原型是不可行的。

StubHub 的 Python 故事

StubHub 走的技術路線如下:

第一代: coldfusion
第二代:Java, 基於流的框架
第三代:Java, Tapestry + Spring + Hibernate 各種現代技術框架

你可以看到整個技術生態系統的發展是基於Java的。作為一名工程師,有時你不可能說服你的團隊或架構師放棄已有的程式碼庫或把底層架構從 Java 轉為其他的,但是,仍舊有一些改善的空間,你可以把事情做得又好又快,讓我給你分享一下來自我在 StubHub 個人工作經歷的幾個故事。

故事1:使用 Python 處理 Java 原始碼

2011年 StubHub 的技術團隊舉行了為期一週名為 fixit 的活動,活動要求所有的開發者在一週之內為已有的程式碼寫儘可能多的測試用例以提高整體的測試覆蓋率,但在此之前,我們需要先把一些測試用例標記為”broken”, 因為如果有任何測試用例失敗,都會導致分析工具無法正常產生覆蓋率報告。

關鍵是給測試用例標記上”broken”很容易, 只要給 @Test annotations 加上 broken 的屬性,如下所示:

把這樣的程式碼:

改成:

但在 StubHub 的程式碼庫中有成百上千的測試用例程式碼,那意味著你首先得把他們都找出來,從程式碼庫中檢出一份案例,修改原始碼,提交回修改,然後為下一個案例重複此步驟直到處理完所有成百上千個案例。

這事相當枯燥,我認為Python 更擅長這種重複的檔案處理而不是我,以下是自動處理的Python程式碼片段:

僅僅14行程式碼,通過遍歷給定的路徑,並使用 p4 edit ... 從 Peforce 檢出檔案,從Java原始檔讀取檔案內容,使用正規表示式把測試用例標記為 broken,然後把更改寫回原始檔。我想這個指令碼節約了我一天的工作。

故事2:測試第三方的API

2012 年我加入了一個名為禮物卡的專案,有一個名為 Black Hawk 的第三方技術合作方,他們提供兌換錢的 Web Service API。在這個專案剛開始的時候,他們希望確保 StubHub 的測試伺服器和 Black Hawk 伺服器之間的 API 呼叫是通暢的。由於這僅僅只是做個驗證,並不需要很嚴謹的寫下正規的,能夠很好處理異常的 Java 程式碼,也不需要在我們已經安裝了 JRE 和 HttpClient 庫的環境下部署我們的程式碼並測試 API(順便說一下, Python 作為基礎應用被預裝在大多數的 Linux 分發版中),當我認為這並不是很正式的程式碼,以後也不會被別人重用或者維護,就有了可以做同樣事情的 Python 程式碼:

通過 Python 來呼叫服務很令人愉快。儘管第一次失敗了,由於程式碼的短小和易讀性我只需要拷貝Python程式碼段到郵件裡,傳送給第三方的人詢問:“這段程式碼有什麼毛病 嗎?” 他們更正了某個 http 請求包的問題,給我回了郵件,然後我在測試伺服器上修改程式碼,再次測試,它正常工作了。這期間並沒有用到 JRE/IDE/編譯/構建/部署,僅僅通過 ssh 連線到你的 Linux 伺服器,使用 vi/emacs 修改你的程式碼, 然後 執行!

故事3:給客戶重新傳送獎勵郵件

2012 年,我還參與了另外一個名為 Rewards 的專案,旨在給參加這項活動的使用者傳送打折資訊。他們加入這項活動以後,應該會收到一封關於活動詳情的郵件。不幸的是由於伺服器的問題,有 1285 位使用者沒有成功收到郵件,因此儘管他們已經加入了 Rewards 這個活動,卻可能無法瞭解到如何獲得折扣。因此,我被要求重新傳送郵件來補救這個問題。

這項任務很緊急,如果我們能及時重新傳送郵件,對使用者來說也很有價值。但是假如我們選擇傳統的 Java 程式碼,我們需要通過 JDBC 或 Hibernate 來呼叫 SQL, 從資料庫獲得沒收到郵件的使用者,寫下重新傳送郵件的程式碼, 弄清楚在生產環境上,哪裡構建/部署這段程式碼比較合適,然後回滾這次部署,因為這段程式碼只會使用一次。這很醜陋而且我能想象到,這至少需要花費我們2天時 間來開發部署。

選擇Python的話事情就簡單多了,它還是一段執行在Linux伺服器上的指令碼。為了避免讀取資料庫,我們可以首先從資料庫中取出使用者 id 並像這樣作為一個列表寫到指令碼中:

1285個使用者 ID 看起來是比較大的數目,但把他們全部放在 Python 的一個列表中作為指令碼的一部分還是可以接受,然後讓我們給使用者重新傳送郵件:

最終,僅僅一個晚上,我想所有的使用者應該都收到了他們遺漏的 Rewards 郵件。

故事4:推薦原型

在 2010 年我有一位擅長數學的同事為 StubHub 提出了一個推薦演算法,大致思路是:當使用者瀏覽 StubHub 上的分類/活動資訊時,系統會猜測使用者對什麼最感興趣並有可能購買,我想可能我們又需要使用 Python 構建一個快速應用來驗證他的推薦演算法是否有效。

因此我花費了15分鐘跟他討論演算法並嘗試理解底下的神奇的規則,15分鐘後,我搞清楚了,然後開始用 Python 編碼。

第一, 我只是想為了驗證演算法,讓原型能工作起來,我不會去用 Java 做一些伺服器端的變更,資料模型的變更,對於我來說那更像是一個正式的專案,而不是一個原型。因此,我覺得我可以建一個內建瀏覽器的GUI桌面應用程式, 人們可以操作內建瀏覽器並檢視顯示在GUI應用上(而非瀏覽器上)的推薦資訊,這樣可以使我們避免伺服器端更改。幸運的是,用 Python 來構建一個 GUI 應用程式並不難。

其次,我需要從資料庫獲取歷史訂單資訊並將這些處理後的資料應用於演算法上。你可能知道 Python 在處理資料上同樣比較擅長。

最終,在堅持不懈地使用 Python 編碼 2 天后,我得到了一份如下的粗略原型:

GUI 應用的左側是一個內建的瀏覽器顯示了洛杉磯湖人的比賽,GUI 應用右側顯示了基於內建瀏覽器中當前的比賽,人們可能感興趣的推薦賽事。推薦賽事裡第一位的比賽是2010年的76隊和湖人隊之間的比賽,我猜你能告訴我 這個推薦結果對於 NBA 粉絲來說是不是還算合理。:)

讓我們就假設結果是不理想的,但至少在兩天內,我們就有機會知道該演算法可行與否。這比我們用 Java 在兩週內得到一個好演算法更重要。你越快證明你錯了,你越快可以篩選出更好的演算法。這才是關鍵的地方。假如您的 Java 原型失敗會怎樣?你將失去整兩個星期的時間而非兩天,這個代價太昂貴了。

Python 故事的結尾

這些就是我在 StubHub 所有的 Python 故事,他們可能很微不足道,但是我相信故事還會繼續。我們並非在討論 Java,Python 或 C++ 哪個更好,我一點也不關心這個,我只知道我越多武裝自己,我就會變得越強大,去處理各種各樣的問題,而且不僅要努力地工作,也要聰明地工作。

這會讓生活更輕鬆一點。

相關文章