產品研發作到又快又好的一個核心原則

業務對技術的要求web


以前有人提問「如何提升本身的工資」,其實我的認爲這取決於你貢獻的價值到底有多大。我09年進入百度的時候,高併發的場景非常流行,當時那些技術較強的人都可以解決關於高併發的問題,會採用各類技術手段進行極致的調優。數據庫


咱們再回過頭來看下,現今的互聯網通過不斷髮展以後,不少基礎組件已經變得很是豐富和完善,好比web Server 從Apache到Nginx,緩存也開始出現了,數據庫索引的正確使用方式也被你們所熟知等等。慢慢的關於性能瓶頸的問題你們不多再遇到了,這實際上是因爲咱們的系統變得愈來愈複雜,業務對技術的要求變成了既快又好,「快」指的固然就是工期短,而「好」則是可維護性強,能支持後續的發展。若是能作到這兩點,那麼你的價值就會獲得很大的提高。瀏覽器


要作到又快又好,還有一個核心的原則——全部重複的都應該被自動化。它帶來了兩個好處,一是標準,不用再寫過多的代碼,二就是「快」。接下來的內容將會反覆提到這一理念,首先讓咱們從研發的角度來過一遍整個項目的流程。緩存


項目流程數據結構

標準API定義


隨着微服務化的流行,團隊之間的協做變得愈加重要。原先的接口定義通常採用的是IDL的方式,不過IDL的問題在於標準是本身定義的,且沒法在瀏覽器上直觀的閱讀和感覺。因此整個流程的第一件事情就是標準API的定義,爲此須要用到Swagger,但沒必要預先就定義好,由於長期來看業務的發展會促使代碼變動,而接口卻並不會跟隨改變,這時接口文檔和代碼的表現就會不一致。所以爲了減小人爲因素的干擾,咱們須要作到的是100%同步。併發


當配置好Swagger以後就能夠經過一些方式自動的生成接口定義,同時訪問服務地址也能獲取到接口的標準,還能夠進一步的經過頁面展現接口的具體內容。不過這種方式須要重複寫不少的註釋,並且這些註釋並無做用於代碼,同時代碼和註釋也沒法保障同步。app


圖片


正常來講各類框架中都會有路由功能,可以直接定義路由的處理方法和請求方式。有了這一層支持就意味着在Swagger中的註釋已經無用,咱們只須要分析這裏的語法拿到對應的值就夠了,這樣也能夠實現接口的同步。框架



上圖這種方式保證了開發人員在寫代碼的時候必定會去寫註釋,而這樣的註釋纔算是真正有意義且可以成爲對API的描述。ide


枚舉的可維護性


能夠發現上面的API描述,實際上是定義了一個枚舉,用不一樣的數字表示不一樣的狀態。這樣雖然能夠節省字節,可是其餘人員在使用的時候卻須要查看描述來肯定各數字表明的含義。微服務



爲了解決這樣的問題,咱們又新定義了一個enum標籤。由於這裏全部的代碼均可以經過語法樹查看到,因此咱們這裏作了一些註釋。同時Go能夠經過interface定義如何解析注入的字段,CERT_TYPE__ID_CARD和CERT_TYPE__PASSPORT在注入的時候就會被轉成對應的數字。 圖中左邊就是實際的使用狀況,能夠看到傳遞的直接是字段名,這樣的方式能讓人很好的理解參數的含義。



上圖的界面大概的展現了最終的效果。


數據庫操做的重複性


當接口定義好以後,到了正式的開發階段首先要作的確定是定義數據結構。這個階段也會出現各類問題,好比要寫不少重複的增刪查改方法;在定義完數據結構以後還得生成建立對應table的SQL語句,當model發生改變的時候須要從新調整修改SQL,若是有多種環境,一段時間以後對應的數據庫可能還會不一致。



咱們以前是經過寫代碼來定義外部的元素,而若是定義一個model讓它完成全部的工做,那麼就只須要定義正確的數據庫的表結構就能完成建立工做。如上圖定義了數據庫的各類結構細節,經過解析它就能自動的執行對數據庫的相關操做,好比檢測數據庫和表是否存在,沒有的話就自動建立;檢測表的字段和定義是否一致。這樣在啓動的時候就能保證model和表結構的一致,須要注意的是這種方式咱們只在非線上環境中使用。經過檢測env環境變量來獲知當前運行環境,從而決定是否啓用該功能。


另外針對第一個問題也有了解決方案。若是發現第一個ID爲主鍵就可以自動生成全部的增刪查改方法,惟一索引一樣也是這種原理,對於普通索引只要符合最左前綴原則其實組合也沒有太多。


Client代碼的重複性和準確性


正常來講數據庫代碼寫完以後,就輪到了邏輯代碼的編寫。這個過程當中會請求不少的外部服務,開發人員須要寫大量的請求代碼,同時這些代碼還須要通過測試人員的測試。


圖片


手動的編寫無疑是繁瑣的,有了標準API以後其實徹底能夠經過上圖的方法自動生成請求代碼。


在微服務中咱們常常須要作服務治理,通常的作法是根據Request ID獲取到請求鏈,可是這種方式準確率並不是100%,由於有可能請求只監控到一天中的某個階段的流量。


圖片


採用自動化生成以後就意味着可以徹底肯定所調用的服務,每一個服務的依賴層級也能明確的知曉。最後咱們就能繪製出上面這樣的結構圖,其中圓點越大表示依賴越多。


Mock


在測試的時候一旦碰到與環境相關的內容就會變得很是麻煩,那麼可不可在不部署任何東西的狀況下就能測試到全部的業務邏輯呢?其實在以上的全部部分所有標準化以後,測試的時候不是必需要去請求外部。好比在知道了client擁有的方法以後,只須要定義好interface,而後編寫測試代碼的時候實現另外一個interface注入其中就能測試全部的業務邏輯,而且還能夠自由的構造下游想返回的數據。


配置管理


圖片


上線時候的配置管理有不少種方案,有中心化管理、經過代碼倉庫管理,其中還會涉及到數據庫密碼這樣的私密信息,以及各類其餘的問題。


咱們對此的思路稍微有些不一樣——配置被直接當成了代碼,不存在配置文件。配置文件的問題在於程序的邏輯被外部的因素控制,並且控制細節也不容易被知曉。


配置代碼內部首先有一些默認值方便處理,而後會定義一些configTag用來代表該參數能夠從外部注入,具體的注入方式經過環境變量完成。程序啓動的時候會讀取其中的環境變量,而後去匹配配置代碼中的參數更改對應的值。


CI Flow


圖片


配置管理問題解決以後就輪到了CI Flow。爲了應對業務高速發展的場景,咱們實現了一種新的Flow,全部的代碼都是在master上,每次開發新功能的時候都會新建一個feature,開發完成以後會打上規定格式的tag,而後咱們會對應的將程序打包併發布到測試環境,測試沒問題以後會再次打上demo的tag,識別到這個tag以後就會再將程序放到demo環境中驗證,最後合併到master上。這樣在並行開發的時候互相之間就不會產生影響。


將來待作的


原先產品提出需求以後,是先開發完以後再進行測試,這種方式效率並不高。其實開發定義好標準接口以及邏輯處理方法以後,開發部分的內部實現和測試部分的編寫是能夠並行的。全部咱們但願構建這樣一種模式,即開發定義好基礎框架後,測試可以緊隨其後編寫代碼。雖然這樣會模糊測試和開發的邊界,可是咱們的另一個理念就是全部人都是開發。

相關文章
相關標籤/搜索