從零到一,美芽的技術實戰

gww3 9年前發布 | 28K 次閱讀 技術

美芽作為一個美妝視頻社區,在 2 月份上線之后,極受女性用戶的歡迎。此次美芽 CTO 姚東旭在 UPYUN Open Talk 廈門場分享了美芽從零到一的整個產品生命周期,帶給創業公司很多值得借鑒的地方。

以下為正文

美芽在萌芽過程中,同很多初創產品一樣,有常見的三個特點:較小的用戶規模、快速的需求變化以及尚未完善的團隊。

1. 較小的用戶規模。雖然偶有例外,譬如“足跡”的爆發式增長,傳言 DAU 有 300 萬,而一般的產品不會有這種運氣;

2. 快速的需求變化。初創產品蘊含很多的不確定性。無法同時兼顧產品細節,也無法在較短時間內將功能極盡完善,因而通常情況下會盡快推向市場,以驗證想法的正確性;

3. 尚未完善的團隊。互聯網創業公司對于技術人員的強烈需求,與市場的供不應求,有著難以消解的矛盾。加上創業公司無法高價請人,通常情況下的應對之策只能是一人多用。

面對這樣的境況,相比較代碼的執行效率或線上接口的響應效率,更為注重開發效率是美芽的應對之策。而影響開發效率主要包括三方面:一是溝通成本,以客戶端和后端同學的溝通為主;二是重復輪子,已經有成熟的開源實現了,卻用自己的代碼重復實現了;三是過度設計。

溝通成本:協議 / 流程

1. 協議

在協議方面,很多項目在設計前后端交互協議時非常隨意,比如 /Post/Show/xx ,實現起來也沒有統一標準。

從請求無法明確看出該以哪種方式獲取數據,客戶端同學必須詢問服務端,或者在文檔里清晰的描述出來。特別是對于新加入的開發者,需要一個熟悉的過程。比如刪除一個帖子,使用 DELETE 或 GET 方法,也并沒有統一的標準,針對這個問題,美芽是選用 REST風格。

REST 可以翻譯為表現層狀態轉化,這里應該還有個主語,那就是 Resource(資源),特指網絡上的具體信息,比如帖子和評論。美芽在設計客戶端請求接口的 時候都是針對一個資源做操作。REST定義了一個對資源操作的標準,使用 HTTP 的四個動詞表示對資源的操 作,GET,POST,DELETE,PUT。以用戶帖子為例:

  1. GET /posts 獲取帖子列表,
  2. GET /posts/id 獲取編號為 id 帖子的內容,
  3. POST /posts 發布帖子,
  4. DELETE /posts/id 刪除編號為 id 的帖子,
  5. PUT /posts/id 修改編號為 id 的帖子。
  6. </ol>

    無論新加任何功能模塊,包括評論或點贊等都執行這一標準。在開發客戶端的過程中,就避免了添加新功能時對接口做其他的約定。


    以模型 Post 舉例,接口可以變成在獲取帖子時,將 id 傳過去,返回來就是需要的對象。帖子在后端或數據庫中的字段,在客戶端對應的就是 Post 模型的屬性。 

    不再需要有文檔去介紹它,只需要自動生成一份數據庫字典就把所有東西解決了,少了很多中間成本。在客戶端要創建帖子就變得極其簡單,客戶端用定義好的方法請求到后端,服務端收到請求后就往數據庫里新建一個資源。美芽在客戶端接口設計的時候都是針對資源操作。

    總結來說,接口設計面向資源、而非功能。在客戶端有各種功能和操作,在接口上面肯定不能所有的東西都按客戶端的要求設計,這樣會增加很大成本。我們在接口設計上只關注數據,至于怎么操作是客戶端的事情,將數據和表現分離。

    2. 流程

    開發流程,剛出道的時候由于流程不完善,會出現各種問題,比如剛上線的代碼或剛修正了一個 Bug隨意發布,發布上去后又發現有問題。

    針對這點,美芽制定了本地環境 - 開發環境 - 預發環境 - 生產環境四個環節。每個人在本地環境完成后將代碼提交,會自動發布到集成開發環境;預發環境的存在,是想在上線之前,在同樣的生產環境下,做最終的確認,之后再更新到用戶環境中。


    代 碼管理的流程,從倉庫來說,首先有 master 和 dev 兩個長期分支,master 是主干分支,dev 是開發的集成環境 。當要修改 bug 或者開發新特性時會新建一個新分支,問題修復后需要將這個分支 merge 到 dev 分支,需要上線時就合并到 master,這是一個特定的生命周 期。

    代碼在推向預發環境前要經過其他成員的審核,審核之后才會合并。合并后使用 git hooks 工具,自動將代碼更新到預發環境,在App客戶端 內部會做一些開關控制它用哪個環境。

    在 整個過程中,對所有同學都是透明的,我們使用了 Slack 作為消息樞紐,Slack 訂閱了 Github 通知事件。團隊里面的每一位成員,只要關 注項目都會看到所有的動態,包括特性上線、Bug修復等。還有一個工具 fabric, 這是一個 異常上報 組件,客戶端集成 fabric sdk后 就可以將異常上報到 fabric,fabric再通知到 Slack, 團隊成員就能在 slack 中看到客戶端運行動態了。

    重復輪子:框架 / 類庫 / 開源軟件

    框架

    其 一,為了保證開發效率,希望框架使用起來能夠足夠簡單,新的團隊成員也能夠很好地適應。關于頗受爭議的 ORM 需要觀察它的適用情況,在用戶規模尚小、 數據量較小時,ORM 能夠快速實現業務需求,而當量級漸長就該果斷舍棄;其二,框架必須保證功能強大,以盡可能減少開發量。基于以上的綜合考慮,美芽選擇選擇使用了以下PHP框架和工具:

    2. DB migration,這個是修改數據表結構的一個工具。剛剛提及的需求會較不穩定,經常會遇到字段的增減,而此類操作如果只是手動修改,并需要同步到其它環境,將極其不利于管理。DB migration 這個機制是用要代碼表示數據庫字段的增刪。


    譬如在增設字段時,新增一個類表示對數據表的操作,其中,up 方法就是執行修改,down 是回滾修改。等到上線時,就只需更新 PHP代碼,這就統一了表結構的統一操作,所有的東西都用代碼呈現,呈現又是文本,可以進行版本管理。人員對數據庫的所有操作都有紀錄。

    3. Command。比如,開發一個命令行工具,讓用戶輸入一個名字,根據名字調用信息,需要包含輸入參數,和選項參數以及輸出。Command 會將這些東西做包裝,不需要開發除了產品業務邏輯之外的東西。

    4. Queue, 進行很多操作時不能同步等待,比如推送一條消息,發布一條評論讓對方收到消息通知,肯定不能在請求里同步處理,而是要放到隊列里異步執行,再推送到蘋果的 服務器最后推送到用戶。這個例子是項目中用的,我們添加隊列的時候只需在服務器上執行一條命令打開這個隊列。


    5. Tinker,這也是命令行的工具,可以做到在執行這條命令的時候,把整個項目環境加載進去。而且是一個交互式的操作,比如要取一個對象就可以直接查詢,把信息打出來。相比較調試代碼時用url或者添加各種參數,這種處理方式會非常方便。

    6. 還有一個是對 Log 的處理,使用時只需要配置一下,在當前環境下需要打的 Log 級別,在代碼中直接使用即可,或者在生產中將這類信息都保留。

    上面使用的每一項都不是太復雜,或者難度特別大,自己做也都可以。但在資源有限的情況下,初創團隊更重要的是投入更大的時間和精力在業務上。這個框架是集成了開發中一些通用的內容,減少了很多額外的開發工作。

    雖然看上去 Laravel 框架非常美好,但美好都是有代價的,Laravel 框架非常的慢。因為它提供了各種封裝、加載了很多東西,導致一個空的接口響應時間也需要幾十毫秒。所以更適合量不大的初創產品。但與此同時,美芽也正在積極解決效率問題。

    再 來看 iOS 類庫,REST 只是定義了標準,而沒有提供完整的工具來實現,通常服務端返回的是 JSON 格式數據,客戶端將收到的 JSON 格式 轉換成 NSDictionary,再由 NSDictionary 轉換成 NSObject, 這可能對應到客戶端的一個 Model 或者一個具體 對象;客戶端發請求到服務端時,就需要將 NSObject 轉化成 NSDictionary, 再轉換成 JSON 格式,然后發送到服務端。這個過 程非常煩鎖,而且需要對每個類都實現一套 encode decode 的邏輯,而實質上我們關心的只是 Value 而已。我們引進 了 Mantle 庫,這個庫會幫你實現這一系列封包解包的過程。

    再加上 TMCache AFNetworking 這兩個庫(前者用來實現快速的對象緩存,而后者基本上每個 iOS 程序員都熟悉的一個網絡框架),就能實現整個產品的 Model 層。

    最 后介紹一套開源軟件 ELK(Elasticsearch Logstash Kibana),這一套軟件主要用來處理日志,進而分析問題,其中 Elasticsearch 負責存儲+搜索、Logstash 負責搜集、Kibana 負責展示,通過 ELK我們可以隨時觀察事件的發生,并作出及 時妥當的處理。

    比如客戶端訪問服務器時返回系統繁忙這些錯誤,或者是帖子加載過慢這些問題都可以通過這一套軟件展示出來。雖然看似復雜,但實際操作卻極其簡單,現在我們主要分析程序內部日志,Nginx access log 和 Nginx error log。

    這些日志會先通過 logstash 采集,存儲到 ES 上,再通過 Kibana 展示出來。

    同 時,這一套工具還有對運營數據分析的支持。接入這套工具,美芽實現了各種業務的簡單統計,包括注冊統計、地區分析、時間分析、用戶活躍時間等等。接 入 ELK 也是非常簡單的,只需將原始數據導入,調用一些查詢語句就可以展現,只需要調用一下接口、填入統計數據即可,業務上不需要做什么操作和修改, 更無需修改數據庫和代碼主邏輯。

    美 芽整體宏觀架構如下圖所示:美芽用戶通過 APP 或者PC 版跟 Nginx 交互再訪問 API,這里所產生的日志都會寫文件,在文件寫入之后就會 有 Logstash Agent 會翻譯成固定的格式存到 Elsearch, 同時 API 內部也會將日志會先輸出到消息隊列中,由消息隊列再異步 輸出到 Logstash Agent,Dashboard 會調用 kibana 的接口,以運營能接受的形式展現出來,如下圖:

    會管理線上服務器的客戶端開發,才是一名好運維

    特 別介紹下美芽的運維,盡一人多用之能事,運維也兼做開發。在代碼的上線流程中并不需要運維的參與,但軟件安裝、配置更新就需要運維處理。美芽的運維,主要 是通過 Saltstack,用 YAML 來描述服務器的狀態。YAML 作為一種比較簡潔的數據格式,是純文本的,也就是說服務器的所有狀態都可以進 行版本管理,服務器的狀態可根據每個版本里面的配置文件體現出來服務器當前是什么樣的狀態。

    看下面一個簡單的示例,下圖是一個 logstash 的 saltstack 配置:

    首先是有一個 master 節點,這是一個中心節點,然后有很多的 minion 節點需要被更新。


    執行以下一條命令就可以將所有的 minion 更新了,命令有兩個參數,一個是 prod,是一個分組的概念,比如五臺服務器,把五臺服務器都放到分組里面;后面一個參數 production, 代表生產環境。操作時,前半部分是針對五臺服務器做的工作。


    作者簡介:姚東旭,美芽 CTO,原騰訊工程師,曾在 QQ 會員以及微云產品中心做研發工作,由于個人興趣以及工作原因,做過各種平臺的開發,目前主要關注 DevOps、團隊開發效率以及代碼質量保證等領域。

    來自:http://www.csdn.net/article/2015-05-12/2824668

 本文由用戶 gww3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!