項目開發準備規範

1 基本編碼規範


  這個基本上每個公司都有一份這樣的文檔(如果沒有你基本上可以考慮job-hopping),這個文檔一般跟項目無關,比如命名規範,註釋規範,SQL規範等等。另外,要統一jdk,包括本地開發環境、服務器環境;定好項目名,包名,數據庫名,表名,以及是否每個表需要通用字段(如version樂觀鎖版本號)等等。


  這裏重點強調2個地方,工程規範和包名目錄規範。


  工程規範:要明確定義每個工程模塊的邊界,尤其是在分佈式系統中,這一點顯得尤爲重要,開發人員要對框架的層次結構非常理解,比如什麼時候該定義DTO,什麼時候該定義Domain。這個如果沒有搞清楚,在項目的整個生命週期裏面,項目的體積越來越龐大,這個問題一旦暴露出來簡直就是災難。


  包名目錄規範:包目錄規範要儘可能從頂層開始,開發人員的包目錄權限要儘可能低,簡單的說就是儘可能讓開發人員少去建包,這一點很像日本的外包項目,目的就是統一規範。另外一點,要避免兩個工程模塊出現相同的包路徑,這樣在引用的時候極有可能出現衝突。


2 定義好組件的邊界和職責


  系統分解之後,要定義好組件(子系統或者模塊)的邊界和職責,這個是項目初期開發人員最關心的問題,如果這個沒有定義清楚,後面系統就要面臨重構的危險。


  比如基礎數據,並不是所有基礎資料、配置信息都放到基礎數據中,只有跨系統、跨服務、模塊的基礎資料、配置信息才屬於基礎數據管理範疇;另外基礎數據服務的接口需要具備一定的通用性,儘可能減少針對某個系統、服務、模塊開放特殊接口;並且不允許基礎數據服務依賴上層服務。


3 項目版本定義


  項目初期,除了一些基礎的模塊,比如工具類等公共模塊可能被打包成Release版本,其他的一般都是SNAPSHOT版本,當項目陸陸續續上線之後,比如分佈式系統中RPC調用要給客戶端系統提供jar包引用,版本控制的作用就會凸顯出來。這裏推薦一批文章《語義化版本2.0.0》,是關於語義化的版本規範,這個規範是由 Gravatars 創辦者兼 GitHub 共同創辦者 Tom Preston-Werner 所建立。


4 svn代碼管理與發佈規範


  根據項目的開發模型,定好代碼的主幹(trunk),分支(branches),基線(tags)的關係,以及相關環境的發佈流程規範。


5 自動構建


  在分佈式系統開發中,沒有自動構建簡直不敢想象,往往一個項目有很多個子項目部署在幾十臺甚至幾百臺服務器上。如果沒有自動構建,開發人員有可能要花費大量的時間在服務打包發佈上,一旦需要馬上發佈一個測試bug,都需要很長一段時間,這會另整個團隊精疲力竭。


6 代碼日誌規範


  項目的日誌在生產環境上禁止將日誌輸出到Console中。項目代碼中都需要通過Logger對象來輸出日誌和異常,禁止使用system.out.println等方法進行輸出,禁止使用e.printStackTrace來輸出異常。日誌需要通過日期、大小兩個維度來分割文件,避免日誌文件過大無法打開。生產環境的日誌級別禁止開啓DEBUG,如果排查確實需要則可以針對特定類打開而不能將整個環境設置爲DEBUG,可能會造成系統因爲文件鎖卡死。


7 統一異常處理


  分佈式業務處理系統,系統中存在大量的跨服務調用,並且需要對不同類型的異常做不同級別的處理,處理的方式需要隨着系統的不斷擴展而適應不同類型的異常處理,並且做到跨服務的異常統一定義和快速定位跨服務的異常發生的源頭和原因。一般通過定義全系統統一的異常編碼,並定義其產生的原因,並需要達到識別系統的目的。


8 提供批量更新方法


  批量更新必須使用提供的統一批量更新方法,對性能有很大的提升,如果有非常特殊的場景需求無法使用則必須要經過評審,否則這有可能成爲一個性能瓶頸。


9 儘早提供基礎服務


  如短信服務,郵件服務,這些基礎服務要優先安排開發,因爲幾乎每個模塊都有可能涉及到。


10 規範多線程寫法


  如果系統中有用到多線程,不要隨意開闢線程,儘可能使用統一的線程池,並封裝公共的調用方法以及返回結果。


11 規範事務的處理


  11.1 避免產生一個較長時間鎖定多行數據的事務,儘可能將事務拆解或改爲異步。


  11.2 分佈式事務


    在項目儘可能不通過數據庫層面的分佈式事務來實現數據的一致性而是通過異步、補償、冪等等方式來實現數據的最終一致性。


l  冪等性:


       任何對外提供的服務入口方法都必須實現冪等性,重複使用同樣的參數調用同一方法時總能獲得同樣的結果,而不會造成重複的處理。


       查詢服務:查詢本身就是冪等的,所以不需要做額外的處理。


       新增服務:通過唯一性約束來控制數據的唯一性避免重複寫入數據


       更新服務:通過樂觀鎖來控制數據的冪等性


       刪除服務:刪除本身也是冪等的,所以不需要做額外的處理


l  異步消息處理:


       跨系統進行事務處理時儘可能的使用異步消息處理來進行,先將數據保存爲一箇中間狀態,並將消息寫入MQ,由下游系統訂閱處理。下游系統處理完之後再將結果反饋給上游更新狀態。MQ中寫入的數據正常情況下不要使用完整數據,會造成MQ的IO壓力很高而且數據可能是已經過期的,並且會將隊列變成專用而不是通用,可能無法被其他服務訂閱。


l  補償


MQ處理時可能存在消息丟失、故障等問題丟失數據導致流程中斷,所以需要補償措施來保障流程不會長時間中斷。由一個分佈式事務的最上游系統提供一個定時補償措施檢測長時間未完成事務的流程,並重新觸發這個流程(重新寫入MQ)。


12 確定基礎數據緩存方案


  緩存往往被忽視,等到項目後期碰到性能瓶頸的時候才發現需要重構,那個時候的代價是很大的,所以需要儘早的定好緩存方案,是用ehcache? guava? redis?這個要確定下來並讓開發人員實施下去。


13 規範緩存環境使用


  memcached/redis緩存環境規劃,要定義好數據結構使用規範,比如不能讓所有人都用key/value這種方式來存儲,最終導致緩存環境髒亂。


14 分佈式文件存儲


  儘早確定是在物理上做共享磁盤?還是使用分佈式的文件系統?


15 單元測試


  編寫單元測試要成爲一種習慣,另外,單元測試應該是沒有副作用的。定義良好的單元測試在運行多次的情況下,如果沒有其他條件發生變化,那麼每一次都應該產生完全相同的結果。比如說,在數據庫中通常會插入一些假數據,然後在測試中驗證這些數據,這種方式的測試不可靠,因爲數據庫可能發生變化。可以在單元測試過程中使用內存數據庫或者每次單元測試的數據都是自動生產最後自動刪除的。


  許多同事怕寫單元測試的一個主要原因就是依賴太多(遠程服務調用、redis、webservice等),如果一個服務因爲種種原因掛掉了,那麼這個測試就會失敗。要解決這個痛點,可以引入mock對象可以滿足這些條件的需求,而Mockito正是這樣的一個框架,用Mockito來模擬相關行爲,不用費力去準備各種依賴環境,這時只需專注於業務邏輯即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章