(二)日志規(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)防刷、文本內容違禁詞過
濾等風控策略。