看完這篇項目設計規約,你應該就能構建良好的項目結構了!

這是我參與更文挑戰的第30天,活動詳情查看:更文挑戰linux

應用分層

  • 默認上層依賴下層,箭頭關係表示直接依賴(好比開放接口能夠依賴於Web層,也能夠直接依賴於Service層)
    • 開放接口層: 能夠直接封裝Service方法暴露成RPC接口; 經過Web封裝成接口; 進行網關安全控制,流量控制等
    • 終端顯示層: 各個端的模板渲染並執行顯示的層. 當前主要是velocity渲染,JS渲染,JSP渲染,移動端展現等
    • Web層: 主要對訪問控制進行轉發,各種基本參數校驗,或者不復用業務的簡單處理等
    • Service層: 相對具體的業務邏輯服務層
    • Manager層: 通用業務處理層,具備如下特徵:
      • 對第三方平臺封裝的層,預處理返回結果及轉化異常信息
      • 對Service層通用能力下沉,好比緩存方案,中間件通用處理
      • 與DAO層交互,對多個DAO的組合複用
    • DAO層: 數據訪問層,與底層MySQL,Oracle,HBase等進行數據交互
    • 外部接口或第三方平臺: 包括其它部門的RPC開放接口,基礎平臺,其它企業的HTTP接口

在這裏插入圖片描述

  • 分層異常處理規約:
    • DAO層:
      • 產生的異常類型有不少,沒法用細粒度的異常進行catch
      • 使用catch(Exception e) 方式,並throw new DAOException(e)
      • 不須要打印日誌,由於日誌在Manager或者Service層必定須要捕獲並打印到日誌文件中去,若是同臺服務器再打印日誌,會浪費性能和存儲
    • Service層:
      • 出現異常時,必須記錄出錯日誌到磁盤,儘量帶上參數信息,至關於保護案發現場
    • Manager層:
      • 若是Manager層與Service同機部署,日誌方式與DAO層處理一致
      • 若是是單獨部署,採用與Service一致的處理方式
    • Web層:
      • Web層絕對不容許繼續往上拋異常,由於已經處於頂層
      • 若是意識到這個異常將致使頁面沒法正常渲染,應該直接跳轉到友好錯誤頁面,加上用戶容易理解的錯誤提示信息
    • 開放接口層:
      • 要將異常處理成錯誤碼和錯誤信息方式返回
  • 分層領域模型規約:
    • DO: Data Object, 此對象與數據庫表結構一一對應,經過DAO層向上傳輸數據源對象
    • DTO: Data Transfer Object, 數據傳輸對象 ,Service或者Manager向外傳輸的對象
    • BO: Business, 業務對象,由Service層輸出的封裝業務邏輯對象
    • AO: Application Object, 應用對象,在Web層與Service層之間抽象的複用對象模型,極爲貼近展現層,複用度不高
    • VO: View Object, 顯示層對象,一般是Web向模板渲染引擎層傳輸的對象
    • Query: 數據查詢對象,各層接收上層的查詢請求. 注意超過2個參數的查詢封裝,禁止使用Map類來傳輸

二方庫依賴規約

  • 定義GAV遵循如下規則:
    • GroupID格式: com.[公司/BU].業務線[.子業務線]
      • 最多4
      • 子業務線可選
      • com.taobao.jstorm, com.alibaba.dubbo.register
    • ArtifactID格式: 產品線-模塊名
      • 語義不重複不遺漏
      • 先到中央倉庫查證一下
      • dubbo-client, fastjson-api
    • Version: 主版本號.次版本號.修訂號
      • 主版本號: 產品方向更改,或者大規模的API不兼容,或者架構不兼容升級
      • 次版本號: 保持相對兼容性,增長主要功能特性,影響範圍極小的API不兼容修改
      • 修訂號: 保持徹底兼容性,修復BUG,新增次要功能特性
        • 注意起始版本號爲: 1.0.0,而不是 0.0.1.
        • 正式發佈的類庫必須先去中央倉庫進行查證,使版本號有延續性,正式版本號不容許覆蓋升級
  • 線上應用不要依賴SNAPSHOT版本,除了安全包之外
    • 不依賴SNAPSHOT版本是保證應用發佈的冪等性
    • 同時也能夠加快編譯時的打包構建
  • 二方庫的新增或升級,保持除功能點以外的其它jar包不變
    • 若是有改變,必須明確評估和驗證,建議進行dependency:resolve先後信息比對
    • 若是仲裁結果徹底不一致,那麼經過dependency:tree命令,找出差別點,進行 < excludes > 排除jar包
  • 二方庫能夠定義枚舉類型,參數可使用枚舉類型,可是接口返回值不容許使用枚舉類型或者包含枚舉類型的POJO對象
  • 依賴於一個二方庫羣時,必須定義一個統一的版本變量,避免版本號不一致
    • 依賴springframework-core, -context, -beans. 都是同一個版本號,能夠定義一個變量來保存版本
    • ${spring.version}, 定義依賴的時候,引用該版本
  • 禁止在子項目的pom依賴中出現相同的GroupId, 相同的ArtifactId, 可是不一樣的Version
    • 在本地調試時會使用各子項目指定的版本號,可是合併成一個war, 只能有一個版本號出如今lib目錄中
    • 可能出現線下調試是正確的,發佈到線上去出現故障問題
  • 因此pom文件中的依賴聲明放在 < dependencies > 語句塊中,全部版本號仲裁放在 < dependencyManagement > 語句塊中
    • < dependencyManagement > 裏只是聲明版本,並不實現引入
    • 須要子項目顯式的聲明依賴 ,versionscope都讀取自父pom
    • < dependencies > 全部聲明在主pom< dependencies > 裏的依賴都會自動導入,並默認被全部的子項目繼承
  • 二方庫不要有配置項,最低限度不要再增長配置項
  • 爲了不應用二方庫的依賴衝突問題,二方庫發佈者應當遵循如下原則:
    • 精簡可控原則:
      • 移除一切沒必要要的API和依賴,只包含Service API, 必要的領域模型對象, Utils類, 常量, 枚舉等
      • 若是依賴其它二方庫,儘可能是provided引入,讓二方庫使用者去依賴具體的版本號
      • log的具體實現,只依賴日誌框架
    • 穩定可追溯原則:
      • 每一個版本的變化應該被記錄,二方庫維護信息,源碼位置,都須要可以方便查到
      • 除非用戶主動升級版本,不然公共二方庫的行爲不該該發生變化

服務器規約

  • 高併發的服務器要調小TCP協議的time_wait時間
    • 操做系統默認240秒後,纔會關閉處於time_wait狀態的鏈接
    • 在高併發訪問下,服務器端會由於處於time_wait的鏈接數太多,可能沒法創建新的鏈接
    • 因此須要在服務器上調小此等待值
      • 在linux服務器上經過變動 /etc/sysctl.conf文件去修改該缺省值(s)
net.ipv4.tcp_fin_timeout = 30
複製代碼
  • 調大服務器所支持的最大文件句柄數(fd, File Descriptor)
    • 主流操做系統的設計是將TCP/UDP鏈接採用與文件同樣的方式去管理,即一個鏈接對應於一個fd
    • 主流的linux服務器默認支持的最大fd數量爲1024, 當併發鏈接數很大時很容易由於fd不足出現 "open too many files" 錯誤,致使新的鏈接沒法創建
    • 須要將linux服務器支持的最大句柄數調高數倍,與服務器內存數量相關
  • JVM環境參數設置 -XX: +HeapDumpOnOutOfMemoryError 參數,使JVM遇到OOM場景時輸出dump信息
    • OOM的發生是有機率的,甚至相隔數月纔出現一例,出錯時的堆內信息對解決問題很是有幫助
  • 在線上生產環境 ,JVMXmsXmx設置同樣大小的內存容量,避免在GC後調整堆大小帶來的壓力
  • 服務器重定向
    • 服務器內部重定向使用forward
    • 服務器外部重定向地址使用URL拼裝工具類來生成,不然會帶來URL維護不一致問題和潛在的安全風險
相關文章
相關標籤/搜索