本文轉載自github,原文地址java
阿里巴巴java開發手冊終極版mysql
下文是對裏面經常使用的一些案例及規範的抽取。linux
無規矩不成方圓,無規範不能協做
對軟件來講,適當的規範和標準毫不是消滅代碼內容的創造性、優雅性,而是限制過分個性化,以一種廣泛承認的方式一塊兒作事,下降故障率,提高協做效率。git
開發手冊詳細列舉如何開發更加高效,更加容錯,更加有協做性,力求知其然,更知其否則,結合正反例,提升代碼質量。好比,異常日誌處理時的各類不規範行爲;集合轉換的各類坑;建立線程池出現的等待隊列OOM等。github
簡單,適用的代碼規約背後所傳遞的是技術上的追求卓越、協同合做的精神,是每一個技術團隊不可缺失的重要利器。 代碼是軟件工程裏面的產品設計、系統架構設計等工做的最後承載體,代碼的質量決定了一切工做的成敗。正則表達式
一、全部編程相關命名均不能如下劃線或美圓符號開始,也不能如下劃線或美圓符號結束。spring
反例: _name / __name / $Object / name_ / name$ / Object$sql
二、全部編程相關的命名嚴禁使用拼音與英文混合的方式,更不容許直接使用中文的方式。
三、類名使用 UpperCamelCase 風格,必須聽從駝峯形式,但如下情形例外:(領域模型的相關命名)DO / DTO / VO / DAO 等。數據庫
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion編程
四、方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須聽從 駝峯形式。
正例: localValue / getHttpMessage() / inputUserId
五、常量命名所有大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。
正例: MAX_STOCK_COUNT
反例: MAX_COUNT
六、抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類命名以它要測試的類的名稱開始,以 Test 結尾
七、中括號是數組類型的一部分,數組定義以下:String[] args;
反例:請勿使用 String args[]的方式來定義
八、POJO 類中的任何布爾類型的變量,都不要加 is,不然部分框架解析會引發序列化錯誤。
反例:定義爲基本數據類型 boolean isSuccess;的屬性,它的方法也是 isSuccess(),RPC 框架在反向解析的時候,「覺得」對應的屬性名稱是 success,致使屬性獲取不到,進而拋出異常。
九、包名統一使用小寫,點分隔符之間有且僅有一個天然語義的英語單詞。包名統一使用 單數形式,可是類名若是有複數含義,類名可使用複數形式。
正例: 應用工具類包名爲com.alibaba.mpp.util、類名爲MessageUtils(此規則參考spring 的框架結構)
十、若是使用到了設計模式,建議在類名中體現出具體模式。
說明:將設計模式體如今名字中, 有利於閱讀者快速理解架構設計思想。
正例:
public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
十一、對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務必定是接口,內部 的實現類用 Impl 的後綴與接口區別。
正例:CacheServiceImpl 實現 CacheService 接口。
十二、枚舉類名建議帶上 Enum 後綴,枚舉成員名稱須要全大寫,單詞間用下劃線隔開。
說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。
正例:枚舉名字:DealStatusEnum;成員名稱:SUCCESS / UNKOWN_REASON。
1三、各層命名規約
Service/DAO 層方法命名規約:
1) 獲取單個對象的方法用 get 作前綴。
2) 獲取多個對象的方法用 list 作前綴。
3) 獲取統計值的方法用 count 作前綴。
4) 插入的方法用 insert 作前綴。
5) 刪除的方法用 delete 作前綴。
6) 修改的方法用 update 作前綴。
領域模型命名規約:
1) 數據對象:xxxDO,xxx 即爲數據表名。
2) 數據傳輸對象:xxxDTO,xxx 爲業務領域相關的名稱。
3) 展現對象:xxxVO,xxx 通常爲網頁名稱。
4) POJO 是 DO/DTO/BO/VO 的統稱,禁止命名成 xxxPOJO。
1四、long 或者 Long 初始賦值時,必須使用大寫的 L,不能是小寫的 l,小寫容易跟數字 1 混淆,形成誤解。
說明:Long a = 2l; 寫的是數字的 21,仍是 Long 型的 2?
1五、不要使用一個常量類維護全部常量,應該按常量功能進行歸類,分開維護。
如:緩存相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。
1六、對外暴露的接口簽名,原則上不容許修改方法簽名,避免對接口調用方產生影響。
接口過期必須加@Deprecated 註解,並清晰地說明採用的新接口或者新服務是什麼
1七、當一個類有多個構造器方法,或者多個同名方法(重載),這些方法應該按順序放置在一塊兒,便於閱讀。
1八、推薦儘可能少用 else。if-else 的方式能夠改寫成:
if(condition){ ... return obj; } // 接着寫 else 的業務邏輯代碼;
說明:若是使用要 if-else if-else 方式表達邏輯,最好不要超過 3 層
1九、全部的類都必須添加做者信息。方法前要加註釋。
代碼修改的同時,註釋也要進行相應的修改,尤爲是參數、返回值、異常、核心邏輯 等的修改。
說明:代碼與註釋更新不一樣步,就像路網與導航軟件更新不一樣步同樣,若是導航軟件嚴重滯後, 就失去了導航的意義。
20、接口返回值不容許使用枚舉類型或者包含枚舉類型的 POJO 對象(建議用字符串代替)。容易引起反序列化失敗。
2一、依賴於一個二方庫羣時,必須定義一個統一版本變量,避免版本號不一致。
說明:依賴 springframework-core、-context、-beans,它們都是同一個版本,能夠定義一個變量來保存版本:${spring.version},定義依賴的時候,引用該版本。
一、Object的equals方法容易拋空指針異常,應使用常量或肯定有值的對象來調用equals。
正例: "test".equals(object);
反例: object.equals("test");
說明:推薦使用 java.util.Objects#equals (JDK7 引入的工具類)
二、全部的相同類型的包裝類對象之間值的比較,所有使用 equals 方法比較。
三、序列化類新增屬性時,請不要修改 serialVersionUID 字段,避免反序列失敗;若是徹底不兼容升級,避免反序列化混亂,那麼請修改 serialVersionUID 值。
四、使用索引訪問用 String 的 split 方法獲得的數組時,需作最後一個分隔符後有無內 容的檢查,不然會有拋 IndexOutOfBoundsException 的風險。
String str = "a,b,c,,"; String[] ary = str.split(","); //預期大於 3,結果是 3 System.out.println(ary.length);
五、字符串的聯接方式,使用 StringBuilder 的 append 方法進行擴展。
反例: String str = "start"; for(int i=0; i<100; i++){ str = str + "hello"; } 說明:反編譯出的字節碼文件顯示每次循環都會 new 出一個 StringBuilder 對象,而後進行 append 操做,最後經過 toString 方法返回 String 對象,形成內存資源浪費。
六、final 可提升程序響應效率,聲明成 final 的狀況:
1) 不須要從新賦值的變量,包括類屬性、局部變量。
2) 對象參數前加 final,表示不容許修改引用的指向。
3) 類方法肯定不容許被重寫。
4) 類不能被繼承
七、Map/Set 的 key 爲自定義對象時,必須重寫 hashCode 和 equals。
正例:String 重寫了 hashCode 和 equals 方法,因此咱們能夠很是愉快地使用 String 對象做 爲 key 來使用。
八、使用集合轉數組的方法,必須使用集合的 toArray(T[] array),傳入的是類型徹底同樣的數組,大小就是 list.size()
反例: 直接使用 toArray 無參方法存在問題,此方法返回值只能是 Object[]類,若強轉其它類型數組將出現 ClassCastException 錯誤。<br> 正例: List<String> list = new ArrayList<String>(2); list.add("guan"); list.add("bao"); String[] array = new String[list.size()]; array = list.toArray(array); 注:ArrayList 源碼:<br> public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
九、使用工具類Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法, 它的 add/remove/clear 方法會拋出 UnsupportedOperationException 異常。
說明:asList 的返回對象是一個 Arrays 內部類,並無實現集合的修改方法。Arrays.asList 體現的是適配器模式,只是轉換接口,後臺的數據還是數組。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一種狀況:list.add("c"); 運行時異常。
第二種狀況:str[0]= "gujin"; 那麼 list.get(0)也會隨之修改。
十、不要在 foreach 循環裏進行元素的 remove/add 操做。remove 元素請使用 Iterator 方式,若是併發操做,須要對 Iterator 對象加鎖。
反例: List<String> a = new ArrayList<String>(); a.add("1"); a.add("2"); for (String temp : a) { if("1".equals(temp)){ a.remove(temp); } } 正例: Iterator<String> it = a.iterator(); while(it.hasNext()){ String temp = it.next(); if(刪除元素的條件){ it.remove(); } }
十一、集合初始化時,儘可能指定集合初始值大小。
說明:ArrayList 儘可能使用 ArrayList(int initialCapacity) 初始化
十二、使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷。
說明:keySet 實際上是遍歷了 2 次,一次是轉爲 Iterator 對象,另外一次是從 hashMap 中取出 key 所對應的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中,效率更高。若是是 JDK8,使用 Map.foreach 方法。
正例:
values()返回的是 V 值集合,是一個 list 集合對象;
keySet()返回的是 K 值集合,是 一個 Set 集合對象;
entrySet()返回的是 K-V 值組合集合。
1三、Map 類集合 K/V 能不能存儲 null 值的狀況
集合類 | Key | Value | Super | 說明 |
---|---|---|---|---|
Hashtable | 不容許爲 null | 不容許爲 null | Dictionary | 線程安全 |
ConcurrentHashMap | 不容許爲 null | 不容許爲 null | AbstractMap | 線程局部安全 |
TreeMap | 不容許爲 null | 容許爲 null | AbstractMap | 線程不安全 |
HashMap | 容許爲 null | 容許爲 null | AbstractMap | 線程不安全 |
1四、利用 Set 元素惟一的特性,能夠快速對另外一個集合進行去重操做,避免使用 List 的 contains 方法進行遍歷去重操做。
1五、獲取單例對象要線程安全(雙重空判斷)。在單例對象裏面作操做也要保證線程安全。
1六、線程資源必須經過線程池提供,不容許在應用中自行顯式建立線程。
說明:使用線程池的好處是減小在建立和銷燬線程上所花的時間以及系統資源的開銷,解決資源不足的問題。若是不使用線程池,有可能形成系統建立大量同類線程而致使消耗完內存或者 「過分切換」的問題。
1七、多線程並行處理定時任務時,Timer 運行多個 TimeTask 時,只要其中之一沒有捕獲拋出的異常,其它任務便會自動終止運行,使用 ScheduledExecutorService 則沒有這個問題。
@param command the task to execute delay the time from now to delay execution unit the time unit of the delay parameter @method ScheduledFuture<?> java.util.concurrent.ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)
1八、線程池不容許使用 Executors 去建立,而是經過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同窗更加明確線程池的運行規則,規避資源耗盡的風險。
說明:Executors 各個方法的弊端:
newFixedThreadPool 、newSingleThreadExecutor 和 newScheduledThreadPool:
主要問題是堆積的請求處理隊列可能會耗費很是大的內存,甚至 OOM。
1九、建立線程或線程池時請指定有意義的線程名稱,方便出錯時回溯。
正例: public class TimerTaskThread extends Thread { public TimerTaskThread(){ super.setName("TimerTaskThread"); ... } }
20、避免 Random 實例被多線程使用,雖然共享該實例是線程安全的,但會因競爭同一 seed 致使的性能降低。
說明:Random 實例包括 java.util.Random 的實例或者 Math.random()實例。
正例:在 JDK7 以後,能夠直接使用 API ThreadLocalRandom,在 JDK7 以前,能夠作到每一個線程一個實例。
2一、volatile 解決多線程內存不可見問題。對於一寫多讀,是能夠解決變量同步問題, 可是若是多寫,一樣沒法解決線程安全問題。
若是想取回 count++數據,使用以下類實現:
AtomicInteger count = new AtomicInteger();
count.addAndGet(1);
count++操做若是是JDK8,推薦使用 LongAdder 對象,比 AtomicLong 性能更好(減小樂觀鎖的重試次數)。
2二、在一個 switch 塊內,每一個 case 要麼經過 break/return 來終止,要麼註釋說明程序 將繼續執行到哪個 case 爲止;在一個 switch 塊內,都必須包含一個 default 語句而且放在 最後,即便它什麼代碼也沒有。
2三、在使用正則表達式時,利用好其預編譯功能,能夠有效加快正則匹配速度。
說明:不要在方法體內定義:Pattern pattern = Pattern.compile(規則);
2四、獲取當前毫秒數:System.currentTimeMillis(); 而不是 new Date().getTime();若是想獲取更加精確的納秒級時間值,用 System.nanoTime。
2五、日誌輸出最好使用佔位符的方式
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
2六、避免重複打印日誌,浪費磁盤空間,務必在 log4j.xml 中設置 additivity=false。
正例:<logger name="com.taobao.ecrm.member.config" additivity="false">
2七、輸出的 POJO 類必須重寫 toString 方法,不然只輸出此對象的 hashCode 值(地址值),沒啥 參考意義。
一、任何字段若是爲非負數,必須是 unsigned。
二、表名、字段名必須使用小寫字母或數字
正例:getter_admin,task_config,level3_name
三、禁用保留字,如 desc、range、match、delayed 等,參考官方保留字。
四、惟一索引名爲 uk_字段名;普通索引名則爲 idx_字段名
說明:uk_ 即 unique key;idx_ 即 index 的簡稱。
五、若是存儲的字符串長度幾乎相等,使用 CHAR 定長字符串類型。
varchar 是可變長字符串,不預先分配存儲空間,長度不要超過 5000,若是存儲長度大於此值,定義字段類型爲 TEXT,獨立出來一張表,用主鍵來對應,避免影響其它字段索引效率。
六、表必備三字段:id, gmt_create, gmt_modified
說明:其中 id 必爲主鍵,類型爲 unsigned bigint、單表時自增、步長爲 1;分表時改成從 TDDL Sequence 取值,確保分表之間的全局惟一。
gmt_create, gmt_modified 的類型均爲 date_time 類型。
id
int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
created_time
timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '建立時間',
updated_time
timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新時間',
PRIMARY KEY (id
),
七、若是修改字段含義或對字段表示的狀態追加時,須要及時更新字段註釋。
八、單錶行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表。
說明:若是預計三年後的數據量根本達不到這個級別,請不要在建立表時就分庫分表。
反例:某業務三年總數據量才 2 萬行,卻分紅 1024 張表。
問:你爲何這麼設計?答:分 1024 張表,不是標配嗎?
九、合適的字符存儲長度,不但節約數據庫表空間、節約索引存儲,更重要的是提高檢索速度。
正例:
人的年齡用 unsigned tinyint(表示範圍 0-255,人的壽命不會超過 255 歲);
海龜就 必須是 smallint,
太陽的年齡,就必須是 int;
全部恆星的年齡都加起來,那麼就必須使用 bigint。
十、業務上具備惟一特性的字段,即便是組合字段,也必須建成惟一索引
說明:不要覺得惟一索引影響了 insert 速度,這個速度損耗能夠忽略,但提升查找速度是明
顯的;另外,即便在應用層作了很是完善的校驗和控制,只要沒有惟一索引,根據墨菲定律, 必然有髒數據產生。
十一、嚴禁多個表間join操做
十二、頁面搜索嚴禁左模糊或者全模糊,若是須要請走搜索引擎來解決。
說明:索引文件具備 B-Tree 的最左前綴匹配特性,若是左邊的值未肯定,那麼沒法使用此索
引。
1三、若是有 order by 的場景,請注意利用索引的有序性。order by 最後的字段是組合索引的一部分,而且放在索引組合順序的最後,避免出現 file_sort 的狀況,影響查詢性能。
正例:
where a=? and b=? order by c; 索引:a_b_c
反例:
索引中有範圍查找,那麼索引有序性沒法利用,如:WHERE a>10 ORDER BY b; 索引 a_b 沒法排序。
1四、建組合索引的時候,區分度最高的在最左邊
正例:
若是 where a=? and b=? ,a 列的幾乎接近於惟一值,那麼只須要單建 idx_a 索引便可。
說明:存在非等號和等號混合判斷條件時,在建索引時,請把等號條件的列前置。如:where a>?
and b=? 那麼即便 a 的區分度更高,也必須把 b 放在索引的最前列。
1五、建立索引時避免有以下極端誤解:
1)誤認爲一個查詢就須要建一個索引。
2)誤認爲索引會消耗空間、嚴重拖慢更新和新增速度。
3)誤認爲惟一索引一概須要在應用層經過「先查後插」方式解決。
1六、不得使用外鍵與級聯,一切外鍵概念必須在應用層解決。
說明:(概念解釋)學生表中的 student_id 是主鍵,那麼成績表中的 student_id 則爲外鍵。 若是更新學生表中的 student_id,同時觸發成績表中的 student_id 更新,則爲級聯更新。外鍵與級聯更新適用於單機低併發,不適合分佈式、高併發集羣;級聯更新是強阻塞,存在數據庫更新風暴的風險;外鍵影響數據庫的插入速度。
1七、IDB 數據訂正時,刪除和修改記錄時,要先 select,避免出現誤刪除,確認無誤才能提交執行。
1八、in 操做能避免則避免,若實在避免不了,須要仔細評估 in 後邊的集合元素數量,控制在 1000 個以內
1九、全部的字符存儲與表示,均以 utf-8 編碼,那麼字符計數方法注意:
說明:
SELECT LENGTH("阿里巴巴"); 返回爲 12
SELECT CHARACTER_LENGTH("阿里巴巴"); 返回爲 4
若是要使用表情,那麼使用 utfmb4 來進行存儲,注意它與 utf-8 編碼。
20、在表查詢中,一概不要使用 * 做爲查詢的字段列表,須要哪些字段必須明確寫明。
說明:
1)增長查詢分析器解析成本。
2)增減字段容易與 resultMap 配置不一致。
2一、不要用 resultClass 當返回參數,即便全部類屬性名與數據庫字段一一對應,也須要定義;反過來,每個表也必然有一個與之對應。
說明:配置映射關係,使字段與 DO 類解耦,方便維護
2二、xml 配置中參數注意使用:#{},#param# 不要使用${} 此種方式容易出現 SQL 注入
2三、更新數據表記錄時,必須同時更新記錄對應的 gmt_modified 字段值爲當前時間。
2四、不要寫一個大而全的數據更新接口,傳入爲 POJO 類,無論是否是本身的目標更新字段,都進行 update table set c1=value1,c2=value2,c3=value3; 這是不對的。
執行 SQL 時,儘可能不要更新無改動的字段,一是易出錯;二是效率低;三是 binlog 增長存儲。
一、默認上層依賴於下層,箭頭關係表示可直接依賴,如:開放接口層能夠依賴於 Web 層,也能夠直接依賴於 Service 層,依此類推:
開放接口層:可直接封裝 Service 接口暴露成 RPC 接口;經過 Web 封裝成 http 接口;網關控制層等。
終端顯示層:各個端的模板渲染並執行顯示層。當前主要是 velocity 渲染,JS 渲染,JSP 渲 染,移動端展現層等。
Web 層:主要是對訪問控制進行轉發,各種基本參數校驗,或者不復用的業務簡單處理等。
Service層:相對具體的業務邏輯服務層。
Manager層:通用業務處理層,它有以下特徵:
- a. 對第三方平臺封裝的層,預處理返回結果及轉化異常信息;
- b. 對 Service 層通用能力的下沉,如緩存方案、中間件通用處理;
- c. 與 DAO 層交互,對 DAO 的業務通用能力的封裝。
DAO 層:數據訪問層,與底層 Mysql、Oracle、Hbase 進行數據交互。
外部接口或第三方平臺:包括其它部門 RPC 開放接口,基礎平臺,其它公司的 HTTP 接口。
二、分層領域模型規約:
- DO(Data Object):與數據庫表結構一一對應,經過 DAO 層向上傳輸數據源對象。
- DTO(Data Transfer Object):數據傳輸對象,Service 和 Manager 向外傳輸的對象。
- BO(Business Object):業務對象。能夠由 Service 層輸出的封裝業務邏輯的對象。
- QUERY:數據查詢對象,各層接收上層的查詢請求。注:超過 2 個參數的查詢封裝,禁止使 用 Map 類來傳輸。
- VO(View Object):顯示層對象,一般是 Web 向模板渲染引擎層傳輸的對象。
一、高併發服務器建議調小 TCP 協議的 time_wait 超時時間。
說明:操做系統默認 240 秒後,纔會關閉處於 time_wait 狀態的鏈接,在高併發訪問下,服務
器端會由於處於 time_wait 的鏈接數太多,可能沒法創建新的鏈接,因此須要在服務器上調小此等待值。
正例:
在linux 服務器上請經過變動/etc/sysctl.conf 文件去修改該缺省值(秒):
net.ipv4.tcp_fin_timeout = 30
二、調大服務器所支持的最大文件句柄數(File Descriptor,簡寫爲 fd)。
說明:主流操做系統的設計是將 TCP/UDP 鏈接採用與文件同樣的方式去管理,即一個鏈接對應於一個 fd。主流的 linux 服務器默認所支持最大fd 數量爲 1024,當併發鏈接數很大時很容易由於 fd 不足而出現「open too many files」錯誤,致使新的鏈接沒法創建。
建議將linux服務器所支持的最大句柄數調高數倍(與服務器的內存數量相關)。
6、性能規範
- 常見OOM預防
- 禁止應用中顯示建立線程,避免不可控出現unable to create new native thread;
- 控制select/update/delete/insert的數據級和可變集合的size,避免隨着業務增長內存數據量不可控;
- 頁面查詢不推薦全表查詢,查詢經過查詢條件限制查詢條數;
- 頁面下載條數和下載次數作限制,避免請求過多致使OOM;
- SQL優化目標必須知足range、ref或者consts,不能夠是all類型,避免慢SQL致使鏈接數耗盡影響業務功能;
- 代碼書寫中考慮MySQL中共享鎖和排它鎖場景,預防產生死鎖;
- 代碼中不建議使用@Transactional,由於通常業務場景中用不到,它影響數據庫性能而且多個操做可能在併發下致使數據庫死鎖;
- 數據庫單表達到必定數據量級須要作分庫分表或者冷熱數據隔離,避免業務增長帶來的性能問題;
- 避免系統中出現單點故障,包括中間件和應用程序等全部的節點;
- 能異步處理的別同步處理,異步能夠釋放線程資源,避免阻塞,提升響應效率;
- 隨着業務量的增長,考慮功能拆分和數據庫表拆分,除此支付系統建議按照通道拆分,不一樣的通道指定獨立的work線程,分而治之,避免相互之間影響;提升併發的一個思路就是拆分,拆分後經過異步提升併發效率。
- 頁面請求參數嚴格限制或者校驗處理,防止SQL注入;
- 頁面URL請求作細粒度的權限攔截,防止訪問權限過大;
- 部署在公網的應用作好防止XSS攻擊的防範措施;
- 和第三方系統交互須要互加白名單確保安全;
- 系統全站提供HTTPS服務;
- 和第三方系統交互報文須要加密傳輸;
- 用戶敏感數據作數據脫敏(如:用戶手機號nick);
- 預防頁面被頻繁請求,佔用系統資源;
- 預防API被頻繁請求,佔用系統資源;