阿里巴巴 Java 開發(fā)手冊(二)

(二)日志規(guī)約

1.【強制】應用中不可直接使用日志系統(tǒng)(Log4j、Logback)中的API,而應依賴使用日志框架

SLF4J中的API,使用門面模式的日志框架,有利于維護和各個類的日志處理方式統(tǒng)一。

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(Abc.class);

2.【強制】日志文件推薦至少保存15天,因為有些異常具備以“周”為頻次發(fā)生的特點。

3.【強制】應用中的擴展日志(如打點、臨時監(jiān)控、訪問日志等)命名方式:

appName_logType_logName.log。logType:日志類型,推薦分類有

stats/desc/monitor/visit等;logName:日志描述。這種命名的好處:通過文件名就可知

道日志文件屬于什么應用,什么類型,什么目的,也有利于歸類查找。

正例:mppserver應用中單獨監(jiān)控時區(qū)轉換異常,如:

mppserver_monitor_timeZoneConvert.log

說明:推薦對日志進行分類,錯誤日志和業(yè)務日志盡量分開存放,便于開發(fā)人員查看,也便于

通過日志對系統(tǒng)進行及時監(jiān)控。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——21/34

4.【強制】對trace/debug/info級別的日志輸出,必須使用條件輸出形式或者使用占位符的方

式。

說明:logger.debug("Processing trade with id: " +id+ "symbol: " +symbol);

如果日志級別是warn,上述日志不會打印,但是會執(zhí)行字符串拼接操作,如果symbol是對象,

會執(zhí)行toString()方法,浪費了系統(tǒng)資源,執(zhí)行了上述操作,最終日志卻沒有打印。

正例:(條件)

if (logger.isDebugEnabled()) {

logger.debug("Processing trade with id: " + id + " symbol: " + symbol);

}

正例:(占位符)

logger.debug("Processing trade with id: {} symbol : {} ", id, symbol);

5.【強制】避免重復打印日志,浪費磁盤空間,務必在log4j.xml中設置additivity=false。

正例:

6.【強制】異常信息應該包括兩類信息:案發(fā)現(xiàn)場信息和異常堆棧信息。如果不處理,那么往上

拋。

正例:logger.error(各類參數(shù)或者對象toString + "_" + e.getMessage(), e);

7.【推薦】可以使用warn日志級別來記錄用戶輸入?yún)?shù)錯誤的情況,避免用戶投訴時,無所適

從。注意日志輸出的級別,error級別只記錄系統(tǒng)邏輯出錯、異常等重要的錯誤信息。如非必

要,請不要在此場景打出error級別。

8.【推薦】謹慎地記錄日志。生產環(huán)境禁止輸出debug日志;有選擇地輸出info日志;如果使

用warn來記錄剛上線時的業(yè)務行為信息,一定要注意日志輸出量的問題,避免把服務器磁盤

撐爆,并記得及時刪除這些觀察日志。

說明:大量地輸出無效日志,不利于系統(tǒng)性能提升,也不利于快速定位錯誤點。 記錄日志時請

思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——22/34

三、MySQL規(guī)約

(一)建表規(guī)約

1.【強制】表達是與否概念的字段,必須使用is_xxx的方式命名,數(shù)據(jù)類型是unsigned tinyint

(1表示是,0表示否),此規(guī)則同樣適用于odps建表。

說明:任何字段如果為非負數(shù),必須是unsigned。

2.【強制】表名、字段名必須使用小寫字母或數(shù)字;禁止出現(xiàn)數(shù)字開頭,禁止兩個下劃線中間只

出現(xiàn)數(shù)字。數(shù)據(jù)庫字段名的修改代價很大,因為無法進行預發(fā)布,所以字段名稱需要慎重考慮。

正例:getter_admin,task_config,level3_name

反例:GetterAdmin,taskConfig,level_3_name

3.【強制】表名不使用復數(shù)名詞。

說明:表名應該僅僅表示表里面的實體內容,不應該表示實體數(shù)量,對應于DO類名也是單數(shù)

形式,符合表達習慣。

4.【強制】禁用保留字,如desc、range、match、delayed等, 請參考MySQL官方保留字。

5.【強制】唯一索引名為uk_字段名;普通索引名則為idx_字段名。

說明:uk_即unique key;idx_即index的簡稱。

6.【強制】小數(shù)類型為decimal,禁止使用float和double。

說明:float和double在存儲的時候,存在精度損失的問題,很可能在值的比較時,得到不

正確的結果。如果存儲的數(shù)據(jù)范圍超過decimal的范圍,建議將數(shù)據(jù)拆成整數(shù)和小數(shù)分開存儲。

7.【強制】如果存儲的字符串長度幾乎相等,使用char定長字符串類型。

8.【強制】varchar是可變長字符串,不預先分配存儲空間,長度不要超過5000,如果存儲長

度大于此值,定義字段類型為text,獨立出來一張表,用主鍵來對應,避免影響其它字段索

引效率。

9.【強制】表必備三字段:id,gmt_create,gmt_modified。

說明:其中id必為主鍵,類型為unsigned bigint、單表時自增、步長為1。gmt_create,

gmt_modified的類型均為date_time類型。

10.【推薦】表的命名最好是加上“業(yè)務名稱_表的作用”。

正例:tiger_task/tiger_reader/mpp_config

11.【推薦】庫名與應用名稱盡量一致。

12.【推薦】如果修改字段含義或對字段表示的狀態(tài)追加時,需要及時更新字段注釋。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——23/34

13.【推薦】字段允許適當冗余,以提高性能,但是必須考慮數(shù)據(jù)同步的情況。冗余字段應遵循:

1)不是頻繁修改的字段。

2)不是varchar超長字段,更不能是text字段。

正例:商品類目名稱使用頻率高, 字段長度短,名稱基本一成不變, 可在相關聯(lián)的表中冗余存

儲類目名稱,避免關聯(lián)查詢。

14.【推薦】單表行數(shù)超過500萬行或者單表容量超過2GB,才推薦進行分庫分表。

說明:如果預計三年后的數(shù)據(jù)量根本達不到這個級別,請不要在創(chuàng)建表時就分庫分表。

15.【參考】合適的字符存儲長度,不但節(jié)約數(shù)據(jù)庫表空間、節(jié)約索引存儲,更重要的是提升檢

索速度。

正例:人的年齡用unsigned tinyint(表示范圍0-255,人的壽命不會超過255歲);海龜

就必須是smallint,但如果是太陽的年齡,就必須是int;如果是所有恒星的年齡都加起來,

那么就必須使用bigint。

(二)索引規(guī)約

1.【強制】業(yè)務上具有唯一特性的字段,即使是組合字段,也必須建成唯一索引。

說明:不要以為唯一索引影響了insert速度,這個速度損耗可以忽略,但提高查找速度是明

顯的;另外,即使在應用層做了非常完善的校驗和控制,只要沒有唯一索引,根據(jù)墨菲定律,

必然有臟數(shù)據(jù)產生。

2.【強制】 超過三個表禁止join。需要join的字段,數(shù)據(jù)類型保持絕對一致;多表關聯(lián)查詢

時,保證被關聯(lián)的字段需要有索引。

說明:即使雙表join也要注意表索引、SQL性能。

3.【強制】在varchar字段上建立索引時,必須指定索引長度,沒必要對全字段建立索引,根據(jù)

實際文本區(qū)分度決定索引長度。

說明:索引的長度與區(qū)分度是一對矛盾體,一般對字符串類型數(shù)據(jù),長度為20的索引,區(qū)分

度會高達90%以上,可以使用count(distinct left(列名,索引長度))/count(*)的區(qū)分度

來確定。

4.【強制】頁面搜索嚴禁左模糊或者全模糊,如果需要請走搜索引擎來解決。

說明:索引文件具有B-Tree的最左前綴匹配特性,如果左邊的值未確定,那么無法使用此索

引。

5.【 推薦】如果有order by的場景,請注意利用索引的有序性。order by最后的字段是組合

索引的一部分,并且放在索引組合順序的最后,避免出現(xiàn)file_sort的情況,影響查詢性能。

正例:where a=?and b=?order by c;索引:a_b_c

反例:索引中有范圍查找,那么索引有序性無法利用,如:WHERE a>10ORDER BY b;索引

a_b無法排序。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——24/34

6.【推薦】利用覆蓋索引來進行查詢操作,來避免回表操作。

說明:如果一本書需要知道第11章是什么標題,會翻開第11章對應的那一頁嗎?目錄瀏覽

一下就好,這個目錄就是起到覆蓋索引的作用。

正例:能夠建立索引的種類:主鍵索引、唯一索引、普通索引,而覆蓋索引是一種查詢的一種

效果,用explain的結果,extra列會出現(xiàn):using index。

7.【推薦】利用延遲關聯(lián)或者子查詢優(yōu)化超多分頁場景。

說明:MySQL并不是跳過offset行,而是取offset+N行,然后返回放棄前offset行,返回

N行,那當offset特別大的時候,效率就非常的低下,要么控制返回的總頁數(shù),要么對超過

特定閾值的頁數(shù)進行SQL改寫。

正例:先快速定位需要獲取的id段,然后再關聯(lián):

SELECT a.* FROM表1 a, (select id from表1 where條件LIMIT 100000,20 ) b where a.id=b.id

8.【推薦】SQL性能優(yōu)化的目標:至少要達到range級別, 要求是ref級別, 如果可以是consts

最好。

說明:

1)consts單表中最多只有一個匹配行(主鍵或者唯一索引),在優(yōu)化階段即可讀取到數(shù)據(jù)。

2)ref指的是使用普通的索引(normal index)。

3)range對索引進行范圍檢索。

反例:explain表的結果,type=index,索引物理文件全掃描,速度非常慢,這個index級

別比較range還低,與全表掃描是小巫見大巫。

9.【推薦】建組合索引的時候,區(qū)分度最高的在最左邊。

正例:如果where a=?and b=?,a列的幾乎接近于唯一值,那么只需要單建idx_a索引即

可。

說明:存在非等號和等號混合判斷條件時,在建索引時,請把等號條件的列前置。如:where a>?

and b=?那么即使a的區(qū)分度更高,也必須把b放在索引的最前列。

10.【參考】創(chuàng)建索引時避免有如下極端誤解:

1)誤認為一個查詢就需要建一個索引。

2)誤認為索引會消耗空間、嚴重拖慢更新和新增速度。

3)誤認為唯一索引一律需要在應用層通過“先查后插”方式解決。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——25/34

(三)SQL規(guī)約

1.【強制】不要使用count(列名)或count(常量)來替代count(*),count(*)就是SQL92定義

的標準統(tǒng)計行數(shù)的語法,跟數(shù)據(jù)庫無關,跟NULL和非NULL無關。

說明:count(*)會統(tǒng)計值為NULL的行,而count(列名)不會統(tǒng)計此列為NULL值的行。

2.【強制】count(distinct col)計算該列除NULL之外的不重復數(shù)量。注意count(distinct

col1,col2)如果其中一列全為NULL,那么即使另一列有不同的值,也返回為0。

3.【強制】當某一列的值全是NULL時,count(col)的返回結果為0,但sum(col)的返回結果為

NULL,因此使用sum()時需注意NPE問題。

正例:可以使用如下方式來避免sum的NPE問題:SELECT IF(ISNULL(SUM(g)),0,SUM(g))

FROM table;

4.【強制】使用ISNULL()來判斷是否為NULL值。注意:NULL與任何值的直接比較都為NULL。

說明:

1)NULL<>NULL的返回結果是NULL, 而不是false。

2)NULL=NULL的返回結果是NULL, 而不是true。

3)NULL<>1的返回結果是NULL,而不是true。

5.【強制】 在代碼中寫分頁查詢邏輯時,若count為0應直接返回,避免執(zhí)行后面的分頁語句。

6.【強制】不得使用外鍵與級聯(lián),一切外鍵概念必須在應用層解決。

說明:(概念解釋)學生表中的student_id是主鍵,那么成績表中的student_id則為外鍵。

如果更新學生表中的student_id,同時觸發(fā)成績表中的student_id更新,則為級聯(lián)更新。

外鍵與級聯(lián)更新適用于單機低并發(fā),不適合分布式、高并發(fā)集群;級聯(lián)更新是強阻塞,存在數(shù)

據(jù)庫更新風暴的風險;外鍵影響數(shù)據(jù)庫的插入速度。

7.【強制】禁止使用存儲過程,存儲過程難以調試和擴展,更沒有移植性。

8.【強制】數(shù)據(jù)訂正時,刪除和修改記錄時,要先select,避免出現(xiàn)誤刪除,確認無誤才能執(zhí)

行更新語句。

9.【推薦】in操作能避免則避免,若實在避免不了,需要仔細評估in后邊的集合元素數(shù)量,控

制在1000個之內。

10.【參考】 如果有全球化需要,所有的字符存儲與表示,均以utf-8編碼,那么字符計數(shù)方法

注意:

說明:

SELECT LENGTH("輕松工作");返回為12

SELECT CHARACTER_LENGTH("輕松工作");返回為4

如果要使用表情,那么使用utfmb4來進行存儲,注意它與utf-8編碼的區(qū)別。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——26/34

11.【參考】TRUNCATE TABLE比DELETE速度快,且使用的系統(tǒng)和事務日志資源少,但TRUNCATE

無事務且不觸發(fā)trigger,有可能造成事故,故不建議在開發(fā)代碼中使用此語句。

說明:TRUNCATE TABLE在功能上與不帶WHERE子句的DELETE語句相同。

(四)ORM規(guī)約

1.【強制】在表查詢中,一律不要使用*作為查詢的字段列表,需要哪些字段必須明確寫明。

說明:1)增加查詢分析器解析成本。2)增減字段容易與resultMap配置不一致。

2.【強制】POJO類的boolean屬性不能加is,而數(shù)據(jù)庫字段必須加is_,要求在resultMap中

進行字段與屬性之間的映射。

說明:參見定義POJO類以及數(shù)據(jù)庫字段定義規(guī)定,在sql.xml增加映射,是必須的。

3.【強制】不要用resultClass當返回參數(shù),即使所有類屬性名與數(shù)據(jù)庫字段一一對應,也需

要定義;反過來,每一個表也必然有一個與之對應。

說明:配置映射關系,使字段與DO類解耦,方便維護。

4.【強制】xml配置中參數(shù)注意使用:#{},#param#不要使用${}此種方式容易出現(xiàn)SQL注

入。

5.【強制】iBATIS自帶的queryForList(String statementName,int start,int size)不推

薦使用。

說明:其實現(xiàn)方式是在數(shù)據(jù)庫取到statementName對應的SQL語句的所有記錄,再通過subList

取start,size的子集合,線上因為這個原因曾經出現(xiàn)過OOM。

正例:在sqlmap.xml中引入#start#, #size#

Map map = new HashMap();

map.put("start", start);

map.put("size", size);

6.【強制】不允許直接拿HashMap與Hashtable作為查詢結果集的輸出。

7.【強制】更新數(shù)據(jù)表記錄時,必須同時更新記錄對應的gmt_modified字段值為當前時間。

8.【推薦】不要寫一個大而全的數(shù)據(jù)更新接口,傳入為POJO類,不管是不是自己的目標更新字

段,都進行update table set c1=value1,c2=value2,c3=value3;這是不對的。執(zhí)行SQL

時,盡量不要更新無改動的字段,一是易出錯;二是效率低;三是binlog增加存儲。

9.【參考】 @Transactional事務不要濫用。事務會影響數(shù)據(jù)庫的QPS,另外使用事務的地方需

要考慮各方面的回滾方案,包括緩存回滾、搜索引擎回滾、消息補償、統(tǒng)計修正等。

10.【參考】中的compareValue是與屬性值對比的常量,一般是數(shù)字,表示相等時帶

上此條件;表示不為空且不為null時執(zhí)行;表示不為null值時

執(zhí)行。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——27/34

四、工程規(guī)約

(一)應用分層

1.【推薦】圖中默認上層依賴于下層,箭頭關系表示可直接依賴,如:開放接口層可以依賴于

Web層,也可以直接依賴于Service層,依此類推:

?開放接口層:可直接封裝Service接口暴露成RPC接口;通過Web封裝成http接口;網(wǎng)關控

制層等。

?終端顯示層:各個端的模板渲染并執(zhí)行顯示層。 當前主要是velocity渲染,JS渲染,JSP渲

染,移動端展示層等。

?Web層:主要是對訪問控制進行轉發(fā),各類基本參數(shù)校驗,或者不復用的業(yè)務簡單處理等。

?Service層:相對具體的業(yè)務邏輯服務層。

?Manager層:通用業(yè)務處理層,它有如下特征:

1)對第三方平臺封裝的層,預處理返回結果及轉化異常信息;

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

3)與DAO層交互,對DAO的業(yè)務通用能力的封裝。

?DAO層:數(shù)據(jù)訪問層,與底層MySQL、Oracle、Hbase進行數(shù)據(jù)交互。

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

2.【參考】(分層異常處理規(guī)約)在DAO層,產生的異常類型有很多,無法用細粒度異常進行

catch,使用catch(Exception e)方式,并throw new DAOException(e),不需要打印日志,

因為日志在Manager/Service層一定需要捕獲并打到日志文件中去,如果同臺服務器再打日

志,浪費性能和存儲。在Service層出現(xiàn)異常時,必須記錄日志信息到磁盤,盡可能帶上參數(shù)

信息,相當于保護案發(fā)現(xiàn)場。如果Manager層與Service同機部署,日志方式與DAO層處理

一致,如果是單獨部署,則采用與Service一致的處理方式。Web層絕不應該繼續(xù)往上拋異常,

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——28/34

因為已經處于頂層,無繼續(xù)處理異常的方式,如果意識到這個異常將導致頁面無法正常渲染,

那么就應該直接跳轉到友好錯誤頁面,盡量加上友好的錯誤提示信息。開放接口層要將異常處

理成錯誤碼和錯誤信息方式返回。

3.【參考】分層領域模型規(guī)約:

?DO(Data Object):與數(shù)據(jù)庫表結構一一對應,通過DAO層向上傳輸數(shù)據(jù)源對象。

?DTO(Data Transfer Object):數(shù)據(jù)傳輸對象,Service和Manager向外傳輸?shù)膶ο蟆?/p>

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

?QUERY:數(shù)據(jù)查詢對象,各層接收上層的查詢請求。 注:超過2個參數(shù)的查詢封裝,禁止

使用Map類來傳輸。

?VO(View Object):顯示層對象,通常是Web向模板渲染引擎層傳輸?shù)膶ο蟆?/p>

(二)二方庫規(guī)約

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

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

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

正例:com.taobao.jstorm或com.alibaba.dubbo.register

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

正例:dubbo-client/fastjson-api/jstorm-tool

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

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

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

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

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

說明:起始版本號必須為:1.0.0,而不是0.0.1

3.【強制】線上應用不要依賴SNAPSHOT版本(安全包除外);正式發(fā)布的類庫必須使用RELEASE

版本號升級+1的方式,且版本號不允許覆蓋升級,必須去中央倉庫進行查證。

說明:不依賴SNAPSHOT版本是保證應用發(fā)布的冪等性。另外,也可以加快編譯時的打包構建。

4.【強制】二方庫的新增或升級,保持除功能點之外的其它jar包仲裁結果不變。如果有改變,

必須明確評估和驗證, 建議進行dependency:resolve前后信息比對,如果仲裁結果完全不一

致,那么通過dependency:tree命令,找出差異點,進行排除jar包。

5.【強制】二方庫里可以定義枚舉類型,參數(shù)可以使用枚舉類型,但是接口返回值不允許使用枚

舉類型或者包含枚舉類型的POJO對象。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——29/34

6.【強制】依賴于一個二方庫群時,必須定義一個統(tǒng)一版本變量, 避免版本號不一致。

說明:依賴springframework-core,-context,-beans,它們都是同一個版本,可以定義一

個變量來保存版本:${spring.version},定義依賴的時候,引用該版本。

7.【強制】禁止在子項目的pom依賴中出現(xiàn)相同的GroupId,相同的ArtifactId,但是不同的

Version。

說明:在本地調試時會使用各子項目指定的版本號,但是合并成一個war,只能有一個版本號

出現(xiàn)在最后的lib目錄中。曾經出現(xiàn)過線下調試是正確的,發(fā)布到線上出故障的先例。

8.【推薦】所有pom文件中的依賴聲明放在語句塊中,所有版本仲裁放在

語句塊中。

說明:里只是聲明版本,并不實現(xiàn)引入,因此子項目需要顯式的聲

明依賴,version和scope都讀取自父pom。而所有聲明在主pom的

里的依賴都會自動引入,并默認被所有的子項目繼承。

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

10.【參考】為避免應用二方庫的依賴沖突問題,二方庫發(fā)布者應當遵循以下原則:

1)精簡可控原則。移除一切不必要的API和依賴,只包含Service API、必要的領域模型對

象、Utils類、常量、枚舉等。如果依賴其它二方庫,盡量是provided引入,讓二方庫使用

者去依賴具體版本號;無log具體實現(xiàn),只依賴日志框架。

2)穩(wěn)定可追溯原則。每個版本的變化應該被記錄,二方庫由誰維護,源碼在哪里,都需要能

方便查到。除非用戶主動升級版本,否則公共二方庫的行為不應該發(fā)生變化。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——30/34

(三)服務器規(guī)約

1.【 推薦】 高并發(fā)服務器建議調小TCP協(xié)議的time_wait超時時間。

說明:操作系統(tǒng)默認240秒后,才會關閉處于time_wait狀態(tài)的連接,在高并發(fā)訪問下,服

務器端會因為處于time_wait的連接數(shù)太多,可能無法建立新的連接,所以需要在服務器上

調小此等待值。

正例:在linux服務器上請通過變更/etc/sysctl.conf文件去修改該缺省值(秒):

net.ipv4.tcp_fin_timeout= 30

2.【 推薦】 調大服務器所支持的最大文件句柄數(shù)(File Descriptor,簡寫為fd)。

說明:主流操作系統(tǒng)的設計是將TCP/UDP連接采用與文件一樣的方式去管理,即一個連接對

應于一個fd。 主流的linux服務器默認所支持最大fd數(shù)量為1024,當并發(fā)連接數(shù)很大時很

容易因為fd不足而出現(xiàn)“open too many files”錯誤,導致新的連接無法建立。 建議將linux

服務器所支持的最大句柄數(shù)調高數(shù)倍(與服務器的內存數(shù)量相關)。

3.【推薦】給JVM設置-XX:+HeapDumpOnOutOfMemoryError參數(shù),讓JVM碰到OOM場景時輸出

dump信息。

說明:OOM的發(fā)生是有概率的,甚至有規(guī)律地相隔數(shù)月才出現(xiàn)一例,出現(xiàn)時的現(xiàn)場信息對查錯

非常有價值。

4.【參考】服務器內部重定向使用forward;外部重定向地址使用URL拼裝工具類來生成, 否則

會帶來URL維護不一致的問題和潛在的安全風險。

阿里巴巴Java開發(fā)手冊

——禁止用于商業(yè)用途,違者必究——31/34

五、安全規(guī)約

1.【強制】 隸屬于用戶個人的頁面或者功能必須進行權限控制校驗。

說明:防止沒有做水平權限校驗就可隨意訪問、操作別人的數(shù)據(jù),比如查看、修改別人的訂單。

2.【強制】用戶敏感數(shù)據(jù)禁止直接展示,必須對展示數(shù)據(jù)脫敏。

說明:查看個人手機號碼會顯示成:158****9119,隱藏中間4位,防止隱私泄露。

3.【強制】用戶輸入的SQL參數(shù)嚴格使用參數(shù)綁定或者METADATA字段值限定,防止SQL注入,

禁止字符串拼接SQL訪問數(shù)據(jù)庫。

4.【強制】用戶請求傳入的任何參數(shù)必須做有效性驗證。

說明:忽略參數(shù)校驗可能導致:

?page size過大導致內存溢出

?惡意order by導致數(shù)據(jù)庫慢查詢

?任意重定向

?SQL注入

?反序列化注入

?正則輸入源串拒絕服務ReDoS

說明:Java代碼用正則來驗證客戶端的輸入,有些正則寫法驗證普通用戶輸入沒有問題,

但是如果攻擊人員使用的是特殊構造的字符串來驗證,有可能導致死循環(huán)的效果。

5.【強制】禁止向HTML頁面輸出未經安全過濾或未正確轉義的用戶數(shù)據(jù)。

6.【強制】表單、AJAX提交必須執(zhí)行CSRF安全過濾。

說明:CSRF(Cross-site request forgery)跨站請求偽造是一類常見編程漏洞。對于存在

CSRF漏洞的應用/網(wǎng)站,攻擊者可以事先構造好URL,只要受害者用戶一訪問,后臺便在用戶

不知情情況下對數(shù)據(jù)庫中用戶參數(shù)進行相應修改。

7.【強制】在使用平臺資源,譬如短信、郵件、電話、下單、支付,必須實現(xiàn)正確的防重放限制,

如數(shù)量限制、疲勞度控制、驗證碼校驗,避免被濫刷、資損。

說明:如注冊時發(fā)送驗證碼到手機,如果沒有限制次數(shù)和頻率,那么可以利用此功能騷擾到其

它用戶,并造成短信平臺資源浪費。

8.【推薦】發(fā)貼、評論、發(fā)送即時消息等用戶生成內容的場景必須實現(xiàn)防刷、文本內容違禁詞過

濾等風控策略。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 來源與:阿里云棲 禁止用于商業(yè)用途 ps:如果需要電子書 評論你們郵箱 我會發(fā)給你們 下面感覺還是有點亂 目錄 一...
    小向資源網(wǎng)閱讀 7,652評論 0 12
  • 目錄 一、 編程規(guī)約..................................................
    owen_he閱讀 4,976評論 0 4
  • 開頭沿用我特別喜歡的一段話劇臺詞,是羅胖在奇葩說的一期節(jié)目里面表達的:沒有什么是通往真誠的道路,因為真誠是通往一切...
    胡瀑閱讀 1,469評論 0 0
  • 第一章 相遇 剛上初中的夢很青澀,她看到身旁每一個學生都會害怕,就像是一只貓到了陌生的環(huán)境停...
    Rainingrainingn閱讀 166評論 0 1
  • 真的好討厭 為什么總是一不小心又犯錯 不能太為用戶考慮 只做份內的事 但是真的好痛苦 記住自己應該做什么 不能做什...
    角落蜷縮閱讀 161評論 0 0