JAVA開發規范
前言
本規范的目的是提升代碼質量,提升團隊協作效率,規范中出現的強制,推薦,參考含義如下:
【強制】:必須嚴格遵守,如有特殊情況,需架構委員會評審報備。
【推薦】:沒特殊情況必須遵守,在開發組長允許下可以不遵守。
【參考】:可以參考,不做嚴格要求。
后臺開發規范
1.1 命名規范
-
【強制】駝峰式命名,其他不允許,常量除外。
-
【強制】拼音和英文混合不允許。
正例: alibaba / taobao / youku / hangzhou 等國際通用的名稱,可視同英文。 反例: DaZhePromotion [ 打折 ] / getPingfenByName() [ 評分 ] -
【強制】常量命名大寫,單詞以下劃線隔開,語義盡量表達完整,比如MAX就語義不明確。
正例: MAX _STOCK _COUNT 反例: MAX _COUNT -
【強制】抽象類使用Abstract開頭或者Base結尾,異常類以Exception結尾, 測試類命名以它要測試的類的名稱開始,以 Test 結尾。
-
【強制】除非業界通用縮寫,否則不允許單詞縮寫。
反例: AbstractClass “縮寫”命名成 AbsClass;condition “縮寫”命名成 condi ,此類隨意縮寫嚴重降低了代碼的可閱讀性。 -
【推薦】工具類以Utils結尾,幫助類以Helper結尾,幫助類跟工具類的區別在于幫助類是方便業務邏輯使用的,工具類是更通用的。
正例: 應用工具類包名為 com . yujiahui . common . util 、類名為 MessageUtils( 此規則參考spring 的框架結構 ) -
【推薦】枚舉類使用Enum結尾。
-
【推薦】如果模塊、接口、類、方法使用了設計模式,在命名時體現出具體模式。
說明:將設計模式體現在名字中,有利于閱讀者快速理解架構設計理念。 正例: public class OrderFactory; public class LoginProxy; public class ResourceObserver; -
【參考】分層命名規范
1. DTO命名規范,如果DTO是命令,則Cmd結尾,如果是查詢,Query結尾,如果是view object,VO結尾,其他無法歸類的DTO結尾。 2. Service層以Service結尾,Dao層以Dao結尾。方法獲取單個對象以get開頭,獲取多個對象以list開頭,獲取數量已count開頭。 插入以create開頭,更新以update開頭,刪除以delete開頭 3. 領域層工廠以Factory結尾,領域服務建議以DomainService結尾,實體和值對象不需要后綴,是什么名稱就什么名稱,比如訂單實體就叫Order 4. 領域模型層命名盡量與數據表一致,比如表order_detail,命名為OrderDetail,如果表有統一前綴,前綴是否體現到模型對象名上在一個項目內統一。 -
【推薦】實體里面有些布爾方法如果用is開頭容易被框架判斷為屬性,建議都用iz開頭,比如izEasy。
1.2 常量規范
-
【強制】魔鬼數字不允許。
-
【強制】long 或者 Long 初始賦值時,使用大寫的 L ,不能是小寫的 l ,小寫容易跟數字 1 混淆,造成誤解。
說明: Long a = 2 l; 寫的是數字的 21,還是 Long 型的 2?。 -
【推薦】不要在一個類里面維護所有常量,比如領域模型的常量可以放到領域模型里面,也可以另外建立一個常量類,常量類以Constants結尾
正例:緩存相關常量放在類 CacheConstants 下 ; 系統配置相關常量放在類 ConfigConstants 下 -
【推薦】常量類共享應該按層次放置,層次分為:跨應用共享,應用內共享,模塊內共享,類內共享??鐟霉蚕淼某A款惙胖迷谝粋€jar的constant包下,應用內共享的常量類放置下通用模塊下的constant包下,模塊內共享的常量類放置在本模塊的constant包下。
反例:易懂變量也要統一定義成應用內共享常量,兩位攻城師在兩個類中分別定義了表示“是”的變量: 類 A 中: public static final String YES = " yes " ; 類 B 中: public static final String YES = " y " ; A . YES . equals(B . YES) ,預期是 true ,但實際返回為 false ,導致線上問題。
1.3 格式規范
- 【強制】第一個大括號不換行,單行字符120個,其他采用IDE默認格式。
- 【推薦】不同業務邏輯或者不同語義的代碼之間需要有空行。
- 【強制】IDE設置文件編碼為UTF-8。
- 【強制】一行不允許定義多個變量。
1.4 Java規范
-
【強制】所有覆寫的方法都必須加上@Override。
-
【推薦】equals方法容易報空指針異常,常量放前面或者使用Objects.equals(jdk7引入)。
正例:" test " .equals(object); 反例: object.equals( " test " ); -
【強制】包裝類的相等比較用equals,不能用==。
-
【推薦】基本類型和包裝類型的使用標準:
1. pojo類型的屬性用包裝類型 2. RPC方法的參數和返回值用包裝類型 3. 局部變量使用基本類型 -
【強制】領域模型類必須實現toString方法
-
【推薦】類內方法定義的順序是:公有方法》保護方法》私有方法》getter,setter。
-
【推薦】類的方法的訪問控制從嚴。類的方法只在內部使用必須是private,只對繼承類開放,必須是protected,變量跟方法類似。
-
【強制】不要在類里面使用靜態變量存儲數據,如果需要,使用線程安全的數據結構。
-
【強制】不能在foreach循環中刪除集合元素,刪除元素使用迭代器。
// 正面案例 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (刪除元素的條件) { iterator.remove(); } } // 反面案例 List<String> a = new ArrayList<String>(); list.add("1"); list.add("2"); for (String item : list) { if ("1".equals(item)) { list.remove(item); } } -
【強制】SimpleDateFormat線程不安全不要定義為static變量。
// 正例:注意線程安全,使用 DateUtils 。亦推薦如下處理: private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @ Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; -
【推薦】高并發時,考慮鎖的性能,盡量用無鎖數據結構,能鎖區塊就不要鎖整個方法,能鎖對象及不要鎖整個類。
-
【強制】有并發修改同一個對象的場景,需要加鎖,并發修改的概率大于20%,使用悲觀鎖,否則使用樂觀鎖, 樂觀鎖根據業務場景考慮重試次數。
-
【推薦】有返回值的函數盡量不要修改入參。
-
【推薦】盡量少用else,使用衛語句。比如:if(condition) {return obj;} 其他邏輯; 如果實在if-else多,采用狀態模式。
// 正例:超過 3 層的 if-else 的邏輯判斷代碼可以使用衛語句、策略模式、狀態模式等來實現, public void today() { if (izBusy()) { System.out.println(“change time.”); return; } if (izFree()) { System.out.println(“go to travel.”); return; } return; }
1.5 業務代碼規范
-
【強制】方法的參數不允許超過5個。
-
【推薦】參數和返回值不要用Map這種泛化參數。
-
【強制】方法的大括號層級不允許超過4層。
-
【推薦】一個方法只做一件事情,方法不超過30行。
-
【強制】方法不能有副作用,比如查詢類方法,不允許改變入參的屬性值。
-
【推薦】類不能超過500行。
-
【推薦】不允許大量重復代碼。
-
【強制】批量操作必須分組,比如批量插入一千條數據,分為500一組。
正例:List groups = Lists.partition(list,500);
-
【強制】業務查詢返回數據過多必須分頁,比如不能超過5000條返回數據。
-
【推薦】工具類先看項目中是否有提供,不允許隨意添加,如果碰到項目中和jar內有同名工具類,優先使用項目中的類,比如StringUtils在多個jar中有,先使用本項目的StringUtils,滿足不了要求,再用其他jar的類或者移植方法到本項目的StringUtils。
-
【推薦】重要業務流程必須有業務日志,采用BizLog注解,記錄新舊值。
-
【推薦】Service層提供的都是業務邏輯方法,不要放大量查詢方法,有多種查詢的業務模型抽取出Query類,比如OrderQueryService,也可以采用CQRS模式,命令和查詢分離。
-
【強制】業務上存在并發操作的場景,考慮方法的冪等性,或者使用樂觀鎖。
-
【推薦】時刻進行代碼重構,避免代碼腐化,去掉下次再改的心態(潛臺詞:永不再改)
-
【強制】業務上涉及訂單、用戶信息、金額等安全敏感數據文件導出并上傳阿里云OSS時,必須使用文件服務的
/api/file/uploadPrivate接口上傳到阿里云OSS。 -
【強制】業務邏輯盡量避免跨數據庫事務操作,嚴禁事務中穿插執行不同數據庫的sql語句,必要時要考慮失敗場景補償方案和告警機制。
反例: 執行A數據庫更新邏輯X 執行B數據庫更新邏輯Y 執行A數據庫更新邏輯X 執行B數據庫更新邏輯Y
1.6 異常規范
- 【推薦】不允許對大段代碼進行try-catch。
- 【強制】對于有核心功能的死循環線程必須try-catch整個循環體,防止任何異常導致循環線程退出,如果有性能問題,可以酌情優化
- 【推薦】不允許捕獲異常后不做任何處理,如果不想處理,拋出去。
- 【推薦】方法可能返回null,調用方要做非空判斷防止NPE問題。
- 【推薦】避免直接拋RuntimeException,使用業務異常,比如BusinessException,ApplicatinException,DomainException。
1.7 日志規范
- 【推薦】應用的擴展日志文件命名格式 logName.時間.logType.log。logType:日志類型,比如json表示結構化日志,app表示普通日志,logName:日志名稱。
- 【推薦】錯誤日志和業務日志分開。
- 【推薦】異常日志必須包含堆棧信息和現場參數。
- 【強制】嚴禁輸出大量無效日志,比如在大循環中輸出日志。
1.8 注釋規范
-
【參考】類、類屬性、類方法的注釋使用 Javadoc 規范,使用/**內容*/格式,避免使用// xxx 方式。
-
【推薦】所有的抽象方法 ( 包括接口中的方法 ) 必須要用 Javadoc 注釋、除了返回值、參數、異常說明外,還必須指出該方法做什么事情,實現什么功能。
說明:對子類的實現要求,或者調用注意事項,請一并說明。
-
【推薦】所有的枚舉類型字段要有注釋,說明每個數據項的用途。
-
【推薦】代碼修改的同時,注釋也要進行相應的修改,尤其是參數、返回值、異常、核心邏輯等的修改。
-
【參考】謹慎注釋掉代碼。在上方詳細說明,而不是簡單的注釋掉。如果無用,則刪除。
說明:代碼被注釋掉有兩種可能性:
1. 后續會恢復此段代碼邏輯。
2. 永久不用。前者如果沒有備注信息,難以知曉注釋動機。后者建議直接刪掉 ( 代碼倉庫保存了歷史代碼 ) 。
-
【參考】對于注釋的要求:第一、能夠準確反應設計思想和代碼邏輯 ; 第二、能夠描述業務含義,使別的程序員能夠迅速了解到代碼背后的信息。完全沒有注釋的大段代碼對于閱讀者形同天書,注釋是給自己看的,即使隔很長時間,也能清晰理解當時的思路 ; 注釋也是給繼任者看的,使其能夠快速接替自己的工作。
-
【參考】好的命名、代碼結構是自解釋的,注釋力求精簡準確、表達到位。避免出現注釋的一個極端:過多過濫的注釋,代碼的邏輯一旦修改,修改注釋是相當大的負擔。
// 反例 put elephant into fridge
put(elephant, fridge);
方法名 put ,加上兩個有意義的變量名 elephant 和 fridge ,已經說明了這是在干什么,語義清晰的代碼不需要額外的注釋。
-
【推薦】及時清理不再使用的代碼段或配置信息。
說明:對于垃圾代碼或過時配置,堅決清理干凈,避免程序過度臃腫,代碼冗余。 正例:對于暫時被注釋掉,后續可能恢復使用的代碼片斷,在注釋代碼上方,統一規定使用三個斜杠(///)來說明注釋掉代碼的理由。
接口規范
- 【強制】Rest接口返回值必須是BaseResult對象及其子類對象,封裝了錯誤碼,錯誤描述,isSuccess,data信息。data放業務數據。業務錯誤碼自己定義,推薦優先使用英文,避免使用通用錯誤碼,通用錯誤碼參考ExceptionEnum。
比如{code:”0”,msg:”操作成功”,data:{XX}}。
-
【推薦】Rest接口必須標明請求的content_type。比如content_type=applicaton/json
-
【強制】接口提供方必須考慮冪等性,防止重復調用導致嚴重的業務災難。
-
【強制】查詢接口如果數據量過多,需要分頁返回。
-
【推薦】接口必須標明字段的類型,長度,是否必填,文字說明必須準確,反例:person:人員。
-
正例:person:人員編碼。
-
【推薦】Rest接口返回值需要綜合考慮實際功能、安全和性能需求,精細化按需返回業務數據。
-
比如,移動端接口需要考慮性能問題,要避免返回無效字段;對于中臺服務移動端接口返回的多余字段場景,需要業務應用封裝處理后再返回給移動端。
PC端接口返回值要求 移動端接口返回值要求 中臺服務 滿足實際功能、安全即可 滿足實際功能、安全即可。性能要求需要業務應用封裝處理。 業務應用 滿足實際功能、安全即可 除了滿足實際功能、安全需求之外,要考慮性能,避免返回無效字段
-
-
【推薦】Feign Api提供方禁止在給下游使用方的jar中引入AutoConfiguration等影響啟動的配置類
數據庫規范
1. 建表相關規范
- 庫名、表名、字段名,使用小寫和下劃線 _ 分割
- 庫名、表名、字段名,不超過12個字符。默認支持64個字符。
- 庫名、表名、字段名,見名知意,建議使用名詞而不是動詞。
- 使用 InnoDB 存儲引擎。支持;事務、鎖、高并發 性能好。
- 推薦使用 utf8mb4 可以存emoji
- 單表字段數,建議不超過40個
2. 字段相關規范
- 整型定義中不顯示設置長度,如使用 INT,而不是INT(4)
- 存儲精度浮點數,使用 DECIMAL 替代 FLOAT、DOUBLE
- 所有字段,都要有 Comment 描述
- 所有字段應定義為 NOT NULL
- 超過2038年,用DATETIME存儲
- 短數據類型 0~80 選用 TINYINT 存儲
- UUID 有全局唯一統一字段屬性,適合做同步ES使用。
- IPV4,用無符號 INT 存儲
- IPV6,用VARBINARY存儲
- JSON MySql 8.x 新增特性
- update_time 設置 on update 更新屬性
3. 索引相關規范
-
要求有自增ID作為主鍵,不要使用隨機性較強的 order_id 作為主鍵,會導致innodb內部page分裂和大量隨機I/O,性能下降。
-
單表索引建議控制在5個以內,單索引字段數不超過5個。注意:已有idx(a, b)索引,又有idx(a)索引,可以把idx(a)刪了,浪費空間,降低更新、寫入性能。* 單個索引中,每個索引記錄的長度不能超過64KB
-
利用覆蓋索引來進行查詢操作,避免回表。另外建組合索引的時候,區分度最高的在最左邊。
-
select(count(distinct(字段)))/count(id) = 1的區分度,更適合建索引。在一些低區分度的字段,例如type、status上建立獨立索引幾乎沒意義,降低更新、寫入性能。 -
防止因字段不同造成的隱式轉換,導致索引失效。
-
更新頻繁的字段,不要建索引。
4. 使用相關規范
-
單表數據量不超過500萬行,ibc 文件大小不超過 2G
-
水平分表用取模,日志、報表類,可以用日期
-
單實例表數目小于 500
-
alter表之前,先判斷表數據量,對于超過100W行記錄的表進行alter table,必須在業務低峰期執行。因為alter table會產生表鎖,期間阻塞對于該表的所有寫入
-
SELECT語句必須指定具體字段名稱,禁止寫成
“*”select *會將不需要讀的數據也從MySQL里讀出來,造成網卡壓力,數據表字段一旦更新,但model層沒有來得及更新的話,系統會報錯 -
insert語句指定具體字段名稱,不要寫成 `insert into t1 values(…)``
-
``insert into…values(XX),(XX),(XX)..` 這里XX的值不要超過5000個,值過多會引起主從同步延遲變大。
-
union all和union,不要超過5個子句,如果沒有去重的需求,使用union all性能更好。 -
in 值列表限制在500以內,例如
select… where userid in(….500個以內…),可以減少底層掃描,減輕數據庫壓力。 -
除靜態表或小表(100行以內),DML語句必須有where條件,且盡量使用索引查找
-
生產環境禁止使用 hint,如 sql_no_cache,force index,ignore key,straight join等。 要相信MySQL優化器。hint是用來強制SQL按照某個執行計劃來執行,但隨著數據量變化我們無法保證自己當初的預判是正確的。
-
where條件里,等號左右字段類型必須一致,否則會造成隱式的類型轉化,可能導致無法使用索引
-
生產數據庫中強烈不推薦在大表執行全表掃描,查詢數據量不要超過表行數的25%,否則可能導致無法使用索引
-
where子句中禁止只使用全模糊的LIKE條件進行查找,如like ‘%abc%’,必須有其他等值或范圍查詢條件,否則可能導致無法使用索引
-
索引列不要使用函數或表達式,如
where length(name)=10或where user_id+2=1002,否則可能導致無法使用索引 -
減少使用or語句 or有可能被 mysq l優化為支持索引,但也要損耗 mysql 的 cpu 性能??蓪r語句優化為union,然后在各個where條件上建立索引。如
where a=1 or b=2優化為where a=1… union …where b=2, key(a),key(b)某些場景下,也可優化為in -
分頁查詢,當limit起點較高時,可先用過濾條件進行過濾。如
select a,b,c from t1 limit 10000,20; 優化為select a,b,c from t1 where id>10000 limit 20; -
同表的字段增刪、索引增刪等,合并成一條DDL語句執行,提高執行效率,減少與數據庫的交互。
-
replace into和insert on duplicate key update在并發環境下執行都可能產生死鎖(后者在5.6版本可能不報錯,但數據有可能產生問題),需要catch異常,做事務回滾,具體的鎖沖突可以關注next key lock和insert intention lock -
TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日志資源少,但 TRUNCATE 無事務且不觸發 trigger ,有可能造成事故,故不建議在開發代碼中使用此語句。說明: TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同。
安全規范
接口安全
- 【強制】涉及大批量敏感數據的接口增加限流和內網訪問保護
- 【強制】涉及小批量敏感數據的接口增加內網訪問保護
- 【強制】所有不宜公開數據都必須添加接口權限
代碼安全
- 【強制】新加的jar要經過技術中臺組安全檢測評估才能使用
- 【強制】敏感字段禁止明文存儲,需要使用統一工具類進行加密處理
- 【強制】mybatis中能用#{}時不要用${},#{}能防止SQL注入。禁止SQL拼接不安全參數。
密碼安全
- 【強制】所有使用中的業務系統(包括測試環境)密碼必須由大寫字母+小寫字母+數字+特殊字符四種組合,字符數不少于8位。
技術文檔的寫作規范
- 設計文檔需要的核心要素有業務架構 ,應用架構,領域模型(數據架構),技術架構,。
- 業務架構描繪系統的業務流程和功能
- 應用架構描繪系統之間的關系
- 數據架構是指領域模型的關系
- 技術架構描繪系統實現,我們都是比較統一的技術架構,可以省略
Java開發編程軍規
一、禁止循環中查詢數據庫,盡量在循環外一次查詢
- 說明
系統性能瓶頸很大一部分都是指向了數據庫,而循環中查詢數據庫非常耗資源。
- 案例
展示少量樹結構數據時,循環內查詢數據后進行數據組裝。導致服務器在測試環境就頻繁宕機。
使用java.util.Comparator#compare方法調用數據庫查詢接口,導致線上性能極低。
二、禁止把redis這種緩存當數據庫用
- 說明
緩存無法完全符合事務特性ACID原則,數據存在不可使用的風險比較大。
- 案例
會員數據直接存儲到redis緩存中,數據量也比較大,經常會丟數據。
三、禁止循環中創建新線程,盡量使用線程池
四、死循環必須有退出機制
- 說明
死循環中最好有休眠語句存在,另外還要退出機制。
- 案例
訂單同步應用請求第三方平臺數據時,平臺方沒有翻頁的結束標志,同時代碼中沒有退出機制直接導致該平臺訂單同步異常。
五、共享變量必須考慮線程安全
- 說明
盡量避免使用共享變量,無法避免時必須考慮線程安全。
- 案例
微信抽獎功能中,每次中獎都是同一個,原因是對共享變量進行了修改操作,后面的邏輯獲取的是臟數據。
六、浮點計算必須使用BigDecimal
- 說明
如果需要精確計算,非要用String來夠造BigDecimal不可。
七、批量操作必須考慮合理分組
- 說明
數據量大時須批量操作,而批量操作必須分組,避免一次操作耗時過久導致連鎖反應。
- 案例
訂單歷史遷移數據時,分組為5000,導致數據庫刪除操作沒有走索引。建議分組數量在100~500之間。
八、禁止單點部署
- 說明
增加一臺服務器部署可以降低50%的服務不可用風險。
九、禁止大表的全表掃描不加限流
- 說明
全表掃描已經很耗數據庫資源了,頻繁處理請求不加限流就更雪上加霜。
- 案例
售后問題跟蹤單的導出,時間索引沒有控制范圍,導致全表掃描。導出數據接口沒有加限流加劇服務資源消耗。
十、讀寫分離架構,必須考慮讀到過期數據
- 說明
讀寫分離在業務數據更新寫入后再重現讀取時會存在延遲問題,導致讀到臟數據。
- 案例
A. 雙十一開啟讀寫分離,主從同步有延遲,導致業務事件重復發送,原因是讀取到歷史 臟數據。
B. 會員積分服務創建數據后其他服務應用馬上查詢,結果是查詢到空數據。
十一、事務內有外部調用,必須考慮外部不穩定和性能問題
- 說明
事務本身是很耗資源,極易產生超時的問題,要避免再引入外部不穩定因素。
- 案例
個人中心服務,事務內遠程查詢美麗分享官的積分,導致性能極低。外部接口調用需要設置超時和最長等待時間。
十二、接口提供方和Xxljob定時任務必須考慮冪等性,防止重復調用導致嚴重的業務災難
- 說明
根據墨菲定律,接口重復調用是會必現的線上問題。
- 案例
訂單付款接口,冪等邏輯不嚴謹導致重復付款問題。apollo報表中心由于xxljob一秒內重復調度任務,導致統計數據重復,嚴重影響管理層的決策判斷。
十三、禁止資源操作(IO等)后未釋放
十四、嵌套事務的默認傳播屬性是Propagation.REQUIRED,如果需要開啟新事務,必須手動設置事務傳播屬性為Propagation.REQUIRES_NEW。盡量不要使用嵌套事務。
- 說明
使用事務注解或者編程式事務時,需要考慮默認的事務傳播屬性,根據需要決定是并入同一個事務還是開啟新事務。
- 案例
OMS異步操作任務,調用第三方接口時,修改狀態為確認中狀態,需要先提交事務更新,后面的邏輯操作成功則需要修改為已確認,失敗則修改為待審核。當第三方接口沒有返回明確的成功或失敗時,狀態應該保持確認中不變。如果調用接口前不開啟新事務,會導致后面回滾的數據有誤。
十五、覆寫對象的equals()方法時必須同時覆寫hashCode()方法
- 說明
equals和hashCode方法是對象在hash容器內高效工作的基礎,正確的覆寫這兩個方法才能保證在hash容器內查找對象的正確性,同時一個好的hashCode方法能大幅提升hash容器效率。
十六、禁止含事務的循環內加線程同步鎖
- 說明
循環上層包含事務,使用synchronized鎖,會導致MySQL事務鎖和JVM同步鎖互相等待死鎖問題。
- 案例
@Transactional(rollbackFor = Exception.class)
public void storeData(List<Order> orderList) {
/**
order_id = {1,2,3}
線程A更新order_id為1后進入下一輪循環,事務鎖還未釋放,同步鎖需要重新獲取。
同時線程B已獲取同步鎖,需要更新order_id=1的事務操作。結果就是線程A等待線程B持有的
JVM同步鎖,線程B等待線程A持有的事務鎖。
*/
for(Order order : orderList) {
synchronized (LOCK) {
updateOrderId(order);
}
}
}
十七、使用線程池時,必須設置合理的大小,禁止不加限制動態批量創建線程
- 說明
不加限制的批量創建線程會搶占大量系統的資源,引發OOM等連鎖異常,最終導致宕機
- 案例
將new MapReduce<>(xxx)創建線程池的代碼放在API接口實現方法中沒有加其他限制,導致引發OOM宕機,中間觸發了Redis連接超時、Kafka重復消費等異常
十八、所有公共代碼(比如api包、通用工具類)或公共服務(中臺服務、業務應用自身服務)的改動,必須考慮向下兼容
- 說明·
對多個系統項目都有依賴的公共代碼進行修改時,需要考慮兼容歷史邏輯,除非確認所有使用方都能夠接受功能修改產生的影響
- 案例
項目A的開發人員將公共jar包中邏輯進行了修改(該修改需要開啟一個新配置才和原邏輯一致),同時deploy jar包進行測試,新配置只在測試環境進行了操作。依賴了公共jar包的項目B這時進行線上發版,但是沒有進行配置(而且也不知道有這個配置),導致線上事故。
十九、禁止在新建表或者增加修改表字段時設置字符集和排序規則
- 說明·
字符集和排序規則后期修改需要耗費巨大的資源,影響業務穩定性,為了保持schema-表-表字段三者的字符集和排序規則一致,禁止在新建表或者增加修改表字段時設置字符集和排序規則。
- 案例
A項目的某一個表的字段設置了字符集和排序規則,導致與表-schema的排序規則不一致,在聯合查詢時這個表作為關聯字段,報關聯字段排序規則不一致的錯誤,無法進行關聯查詢,只能修改,如果是一張大表修改會非常耗時,占用大量的io會影響業務。
二十、新建表或者增加修改表字段時使用TEXT/BLOD字段需要評估必要性
- 說明·
TEXT/BLOD的大字段會產生磁盤臨時表,而且不能使用全文索引,各種操作的代價都非常高昂,在業務中最好不要使用,如果實在是要使用,也要獨立出一張表專門用于存儲,不得跟業務表中使用。
- 案例
A項目前期的一張表中使用了一個TEXT存儲json大字段,導致這張表占用了600多G的空間,其中那一個大字段就占用90%的表空間,后續的查詢,遷移,碎片整理都非常的耗資源。

浙公網安備 33010602011771號