天天看點

(四)阿裡巴巴JAVA程式設計規範之工程規約

(一) 應用分層

1. 【推薦】圖中預設上層依賴于下層,箭頭關系表示可直接依賴,如:開放接口層可以依賴于Web層,也可以直接依賴于 Service層,依此類推:

開放接口層:可直接封裝 Service接口暴露成 RPC接口;通過 Web封裝成 http接口;網關控制層等。終端顯示層:各個端的模闆渲染并執行顯示層。目前主要是 velocity渲染,JS渲染,JSP渲染,移動端展示層等。

· Web層:主要是對通路控制進行轉發,各類基本參數校驗,或者不複用的業務簡單處理等。

· Service層:相對具體的業務邏輯服務層。

· Manager層:通用業務處理層,它有如下特征:

1) 對第三方平台封裝的層,預處理傳回結果及轉化異常資訊;

2) 對 Service層通用能力的下沉,如緩存方案、中間件通用處理;

3) 與 DAO層互動,對 DAO的業務通用能力的封裝。

· DAO層:資料通路層,與底層 Mysql、Oracle、Hbase、OB進行資料互動。

·外部接口或第三方平台:包括其它部門 RPC開放接口,基礎平台,其它公司的 HTTP接口。

2. 【參考】(分層異常處理規約)在 DAO層,産生的異常類型有很多,無法用細粒度異常進行catch,使用 catch(Exception e)方式,并 throw new DaoException(e),不需要   列印日志,因為日志在 Manager/Service層一定需要捕獲并打到日志檔案中去,如果同台伺服器再打日志,浪費性能和存儲。在 Service層出現異常時,必須記錄日志資訊到磁盤,盡可能帶上參數資訊,相當于保護案發現場。如果 Manager層與 Service同機部署,日志方式與 DAO層處理一緻,如果是單獨部署,則采用與 Service一緻的處理方式。Web層絕不應該繼續往上抛異常,因為已經處于頂層,無繼續處理異常的方式,如果意識到這個異常将導緻頁面無法正常渲染,那麼就應該直接跳轉到友好錯誤頁面,盡量加上友好的錯誤提示資訊。開放接口層要将異常處理成錯誤碼和錯誤資訊方式傳回。

3. 【參考】分層領域模型規約:

· DO(Data Object):與資料庫表結構一一對應,通過 DAO層向上傳輸資料源對象。

· DTO(Data Transfer Object):資料傳輸對象,Service和 Manager向外傳輸的對象。

· BO(Business Object):業務對象。可以由 Service層輸出的封裝業務邏輯的對象。

· QUERY:資料查詢對象,各層接收上層的查詢請求。注:超過 2個參數的查詢封裝,禁止使用 Map類來傳輸。

· VO(View Object):顯示層對象,通常是 Web向模闆渲染引擎層傳輸的對象。

(二) 二方庫規約

1. 【強制】定義 GAV遵從以下規則:

1) GroupID格式:com.{公司/BU }.業務線.[子業務線],最多 4級。

說明:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress等 BU一級;子業務線可選。

正例:com.taobao.tddl 或 com.alibaba.sourcing.multilang

2) ArtifactID格式:産品線名-子產品名。語義不重複不遺漏,先到倉庫中心去查證一下。

正例:tc-client / uic-api / tair-tool

3) Version:詳細規定參考下方。

2. 【強制】二方庫版本号命名方式:主版本号.次版本号.修訂号

1) 主版本号:當做了不相容的 API修改,或者增加了能改變産品方向的新功能。

2) 次版本号:當做了向下相容的功能性新增(新增類、接口等)。

3) 修訂号:修複 bug,沒有修改方法簽名的功能加強,保持 API 相容性。

3. 【強制】線上應用不要依賴 SNAPSHOT版本(安全包除外);正式釋出的類庫必須使用 RELEASE版本号更新+1的方式,且版本号不允許覆寫更新,必須去中央倉庫進行查證。

說明:不依賴 SNAPSHOT版本是保證應用釋出的幂等性。另外,也可以加快編譯時的打包建構。

4. 【強制】二方庫的新增或更新,保持除功能點之外的其它 jar包仲裁結果不變。如果有改變,必須明确評估和驗證,建議進行 dependency:resolve前後資訊比對,如果仲裁結果完全不一緻,那麼通過 dependency:tree指令,找出差異點,進行<excludes>排除 jar包。

5. 【強制】二方庫裡可以定義枚舉類型,參數可以使用枚舉類型,但是接口傳回值不允許使用枚舉類型或者包含枚舉類型的 POJO對象。

6. 【強制】依賴于一個二方庫群時,必須定義一個統一版本變量,避免版本号不一緻。

說明:依賴 springframework-core,-context,-beans,它們都是同一個版本,可以定義一個變量來儲存版本:${spring.version},定義依賴的時候,引用該版本。

7. 【強制】禁止在子項目的 pom依賴中出現相同的 GroupId,相同的 ArtifactId,但是不同的Version。

說明:在本地調試時會使用各子項目指定的版本号,但是合并成一個 war,隻能有一個版本号出現在最後的 lib目錄中。曾經出現過線下調試是正确的,釋出到線上出故障的先例。

8. 【推薦】工具類二方庫已經提供的,盡量不要在本應用中程式設計實作。

l json操作: fastjson

l md5操作:commons-codec

l 工具集合:Guava包

l 數組操作:ArrayUtils(org.apache.commons.lang3.ArrayUtils)

l 集合操作:CollectionUtils(org.apache.commons.collections4.CollectionUtils)

l 除上面以外還有 NumberUtils、DateFormatUtils、DateUtils等優先使用org.apache.commons.lang3這個包下的,不要使用 org.apache.commons.lang包下面的。原因是 commons.lang這個包是從 JDK1.2開始支援的是以很多 1.5/1.6的特性是不支援的,例如:泛型。

9. 【推薦】所有 pom檔案中的依賴聲明放在<dependencies>語句塊中,所有版本仲裁放在

<dependencyManagement>語句塊中。

說明:<dependencyManagement>裡隻是聲明版本,并不實作引入,是以子項目需要顯式的聲明依賴,version和 scope都讀取自父 pom。而<dependencies>所有聲明在主 pom的<dependencies>裡的依賴都會自動引入,并預設被所有的子項目繼承。

10.【推薦】二方庫盡量不要有配置項,最低限度不要再增加配置項。

11.【參考】為避免應用二方庫的依賴沖突問題,二方庫釋出者應當遵循以下原則:

1)精簡可控原則。移除一切不必要的 API和依賴,隻包含 Service API、必要的領域模型對象、Utils類、常量、枚舉等。如果依賴其它二方庫,盡量是 provided引入,讓二方庫使用者去依賴具體版本号;無 log具體實作,隻依賴日志架構。

2)穩定可追溯原則。每個版本的變化應該被記錄,二方庫由誰維護,源碼在哪裡,都需要能友善查到。除非使用者主動更新版本,否則公共二方庫的行為不應該發生變化。

(三) 伺服器規約

1. 【推薦】高并發伺服器建議調小 TCP協定的 time_wait逾時時間。

說明:作業系統預設 240秒後,才會關閉處于 time_wait狀态的連接配接,在高并發通路下,伺服器端會因為處于 time_wait的連接配接數太多,可能無法建立新的連接配接,是以需要在伺服器上調小此等待值。

正例:在 linux伺服器上請通過變更/etc/sysctl.conf檔案去修改該預設值(秒):

net.ipv4.tcp_fin_timeout = 30

2. 【推薦】調大伺服器所支援的最大檔案句柄數(File Descriptor,簡寫為 fd)。

說明:主流作業系統的設計是将 TCP/UDP連接配接采用與檔案一樣的方式去管理,即一個連接配接對應于一個 fd。主流的 linux伺服器預設所支援最大 fd數量為 1024,當并發連接配接數很大時很容易因為fd不足而出現“open too many files”錯誤,導緻新的連接配接無法建立。 建議将linux伺服器所支援的最大句柄數調高數倍(與伺服器的記憶體數量相關)。

3. 【推薦】給JVM設定-XX:+HeapDumpOnOutOfMemoryError參數,讓JVM碰到OOM場景時輸出dump資訊。

說明:OOM的發生是有機率的,甚至有規律地相隔數月才出現一例,出現時的現場資訊對查錯非常有價值。

4. 【參考】伺服器内部重定向必須使用forward;外部重定向位址必須使用URLBroker生成,否則因線上采用HTTPS協定而導緻浏覽器提示“不安全”。此外,還會帶來URL維不一緻的問題。