您好,登錄后才能下訂單哦!
億級用戶中心的設計方法教程,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
用戶中心,顧名思義就是管理用戶的地方,幾乎是所有互聯網公司最為核心的子系統之一。它的核心功能是登錄與注冊,主要功能是修改密碼、換綁手機號碼、獲取用戶信息、修改用戶信息和一些延伸服務,同時還有登錄之后生成Token以及校驗Token的功能。下面我們從幾個維度來拆解用戶中心。
用戶中心既需要為用戶提供服務,也會承擔其他業務的頻繁調用;既然需要為用戶提供服務,它就會自帶一些業務邏輯,比如用戶在登錄過程中需要風控或短信的校驗,那么就會存在不可用的風險。而比如獲取用戶信息的接口,則沒有那么多的依賴,可能只需要調用數據庫或者緩存就可以。獲取用戶信息接口要求穩定,而核心的登錄注冊接口也需要穩定,但是當我們在接口層面加一些策略或者修改的時候,不希望因為上線問題導致整個服務不可用,而且上線后,需要對整個服務功能做全量的回歸,導致資源嚴重浪費。
因此,基于業務特性,我們可以將用戶中心拆成3個獨立的微服務: 網關服務,核心服務,異步消費者服務。網關服務,提供http服務,聚合了各種業務邏輯和服務調用,比如登錄時候需要校驗的風控或者短信;核心服務,處理簡單的業務邏輯以及數據存儲,核心服務處在調用鏈路的終端,幾乎不依賴調用其他服務,比如校驗Token或者獲取用戶信息,他們就只依賴于redis或者數據庫;而異步消費者服務,則處理并消費異步消息。下文會詳細介紹。
這樣的設計之后,當有新功能上線時,核心服務和異步消費服務幾乎不需要重新發布,只需要發布網關服務,依賴我們核心服務的第三方非常放心,層級也非常的清晰。當然,這樣做的代價就是服務的調用鏈路變長了。由于涉及到網關和核心服務,就需要發布兩個服務,而且要做兼容性測試。
用戶中心的接口涉及到用戶的核心信息,安全性要求高;同時,承接了較多第三方的調用,可用性要求也高。因此,對用戶中心的接口做以下設計:
首先,接口可以拆分為面向Web和面向App的接口。Web接口需要做到跨域情況下的單點登錄,加密、驗簽和token校驗的方式也同App端的不一樣。
其次,對核心接口做特殊處理。比如登錄接口,在邏輯和鏈路上做了一些優化。為什么要對這些接口做特殊處理呢?假如用戶不能登錄,用戶會非常恐慌,客訴量會立馬上來。
那怎么做呢?一方面,我們將用戶核心信息表做簡單。用戶的信息當中會包含userId、手機號碼、密碼、頭像、昵稱等字段,假如把用戶的這些所有信息都保存在一張表中,那么這張表將會異常龐大,變更字段變得異常困難。因此,需要將用戶表拆分,將核心的信息保存在用戶表中,比如userId、username、手機號碼、密碼、鹽值(隨機生成)等;而一些如性別,頭像,昵稱等信息保存在用戶資料表中。
另一方面,我們需要將登錄的核心鏈路做短,短到只依賴于讀庫。一般情況下,用戶登錄后,需要記錄用戶登錄信息,調用風控或者短信等服務。對于登錄鏈路來說,任何一個環節出現問題都有可能導致用戶無法登錄,那么怎么樣才能做到最短的鏈路呢?方法就是依賴的服務可自動降級。比如說反欺詐校驗出問題了,那么它自動降級后使用它的默認策略,極端情況下只做密碼校驗,主庫掛了之后還能到從庫讀取用戶信息。
最后就是接口的安全性校驗。對App接口我們需要做防重放和驗簽。驗簽可能大家比較熟悉,但是對防重放這個概念可能相對陌生。防重放,顧名思義就是防止請求重復發送。用戶請求在特定時間段內只能請求一次。即使用戶請求被攻擊者挾持,在一段時間內也無法重復請求。如果攻擊者想要篡改用戶請求再發送,對不起,請求不會通過。得益于大數據的支持,結合終端,我們還可以把每個用戶行為畫像存儲在系統中(或者調用第三方服務)。用戶發起請求后,我們的接口會根據用戶畫像對用戶進行諸如手機號碼校驗、實名認證、人臉或者活體校驗。
隨著用戶的增長,數據超過了1億,怎么辦?常見的辦法就是分庫分表。我們來分析一下用戶中心常見的一些表結構:用戶信息表,第三方登錄關聯表,用戶事件表。從上述表中可以看出來,用戶相關的數據表增長相對緩慢,因為用戶增長是有天花板的。用戶事件表的增長是呈指數級增長,因為每個用戶登錄、變更等密碼及變更手機號碼等操作是不限次數。
因此,首先我們可以先把用戶信息表垂直切分。正如上面說的,將用戶ID、密碼、手機號、鹽值等常見字段從用戶信息表中拆分,其他用戶相關的信息用單獨一張表。另外,把用戶事件表遷移至其他庫中。相比于水平切分,垂直切分的代價相對較少,操作起來相對簡單。用戶核心信息表由于數據量相對較少,即使是億級別的數據,利用數據庫緩存的機制,也能夠解決性能問題。
其次,我們可以利用前后臺業務的特性采用不同的方式來區別對待。對于用戶側前臺訪問:用戶通過username/mobile登錄或者通過uid來查詢用戶信息。用戶側信息的訪問通常是單條數據的查詢,我們可以通過索引多次查詢來解決一致性和高可用問題。對于運營側后臺訪問:根據年齡、性別、登錄時間段、注冊時間段等來進行查詢,基本上都是批量分頁查詢。但是由于是內部系統,查詢量低,對一致性要求低。如果用戶側和運營側的查詢采用同一個數據庫,那么運營側的排序查詢會導致整個庫的CPU上升,查詢效率下降,影響到用戶側。因此,運營側使用的數據庫可以是和用戶側同樣的MySQL離線庫,如果想要增加運營側的查詢效率,可以采用ES非關系型數據庫。ES支持分片與復制,方便水平分割和擴展,復制保證了ES的高可用與高吞吐,同時能夠滿足運營側的查詢需求。
最后,如果還是要水平切分來保證系統的性能,那么我們采取什么樣的切分方式呢?常見的方法有索引表法和基因法。索引表法的思路主要是UID能夠直接定位到庫,但是手機號碼或者username是無法直接定位到庫的,需要建立一個索引表來記錄mobile與UID或者username與UID的映射關系的方式來解決這個問題。通常這類數據比較少,可以不用分庫分表,但是相比直接查詢,多了一次數據庫查詢的同時,在新增數據的時候還多了一次映射關系的插入,事務變大。基因法的思路是我們將username或者mobile融入到UID中。具體做法如下:、
用戶注冊時,根據用戶的手機號碼,利用函數生成N bit的基因mobile_gen,使得mobile_gen=f(mobile);
生成M bit全局唯一的id,作為用戶標識;
拼接M和N,作為UID賦給用戶;
根據N bit來取余來插入到特定數據庫;
查找用戶數據的時候,將用戶UID的后N bit取余來落到最終的庫中。
從上述過程中看,基因法只適用于某類經常查詢的場景,比如用手機號碼登錄,如果用戶使用username登錄就比較麻煩了。因此大家以根據自己的業務場景來選擇不同的方式水平切分。
用戶登錄之后,另一個重要的事情就是Token的生成與校驗。用戶的Token分為兩類, 一類是web端登陸生成的Token, 這個Token可以和Cookie結合, 達到單點登陸的效果,在此不細說了。另外一類就是APP端登錄生成的Token。用戶在我們的APP輸入用戶名密碼之后,服務端會對用戶的用戶名密碼進行校驗,成功之后從系統配置中心獲取加密算法的版本以及秘鑰,并按照一定的格式排列用戶ID,手機號、隨機碼以及過期時間,經過一系列的加密之后,生成了Token之后并將其存入Redis緩存。而Token的校驗就是把用戶ID和Token組合并校驗是否在Redis中存在。那么假如Redis不可用了怎么辦呢?這里有一個高可用和自動降級的設計。當Redis不可用的時候, 服務端會生成一個特殊格式的Token。當校驗Token的時候,會對Token的格式進行一個判斷。
假如判斷為Redis不可用時生成的Token,那么服務端會對Token進行解密,而Token的生成是由用戶ID,手機號、隨機碼和過期時間等數據按照特定順序排列并加密而來的, 那么解密出來的數據中也包含了ID,手機號碼,隨機碼和過期時間。服務端會根據獲取到的數據查詢數據庫, 比對之后告訴用戶是否登錄成功。由于內存緩存redis和數據庫緩存性能的差距,在redis不可用的情況下,降級有可能會導致數據庫無法及時響應,因此需要在降級的方法上加入限流。
數據安全對用戶中心來說非常重要。敏感數據需要脫敏處理,對密碼更是要做多重的加密處理。應用雖然有自己的安全策略,但如果把黑客限制在登錄之前,那應用的安全性將得到大幅度的提升。互聯網上用戶明文數據遭到泄露的案件屢屢發生,因此各大企業對數據安全的認識也提到了前所未有的高度。而即使使用了MD5和salt的加密方式,依然可以使用彩虹表的方式來破解。那么用戶中心對用戶信息是怎么保存的呢?
首先,正如上文中提到的用戶密碼、手機號等登錄信息和其他的信息分離,而且在不同的數據庫中。其次,對用戶設置的密碼進行了黑名單校驗,只要符合條件的弱密碼,都會拒絕提交,因為不管使用了什么加密方式的弱密碼,都極其容易破解。為什么呢?因為人的記性很差,大部分人總是最傾向于選擇生日,單詞等來當密碼。6位純數字可以生成100萬個不同的密碼,8位小寫字母和數字的組合大概可以生成2.8萬億個不同的密碼。一個規模為7.8萬億的密碼庫足以覆蓋大部分用戶的密碼,對于不同的加密算法都可以擁有這樣一個密碼庫,這也就是為什么大部分網站都建議用戶使用8位以上數字加字母密碼的原因。當然,如果一方面加了鹽值,另一方面對密鑰分開保管,破解難度會指數級增加。
最后,可以用bcrypt/scrypt的方式來加密。bcrypt算法是基于Blowfish塊密鑰算法來實現的,bcrypt內部實現了隨機加鹽處理,使用bcrypt之后每次加密后的密文都不一樣,同時還會使用內存初始化hash過程。由于使用內存,雖然在CPU上運行很快,但是在GPU上并行運算并不快。隨著新的FPGA集成了大型RAM,解決了內存密集IO的問題,但是破解難度依然不小。而scrypt算法彌補了bcrypt算法的不足,它將CPU計算與內存使用開銷都指數級提升了。bcrypt和scrypt算法能夠有效抵御彩虹表,但是安全性的提升帶來了用戶登錄性能的下降。用戶登錄注冊并不是一個高并發的接口,所以影響并不會特別大。因此在安全和性能方面需要依據業務類型和大小來做平衡,并不是所有的應用都需要使用這種加密方式來保護用戶密碼。
此處的異步消費,就是上文提到的異步消費服務。用戶在做完登錄注冊等操作后,需要記錄用戶的操作日志。同時,用戶注冊登錄完畢后,下游業務需要對用戶增加積分,贈送禮券等獎勵操作。這些系統如果都同步依賴于用戶中心,那么整個用戶中心將異常龐大,鏈路非常冗長,也不符合業內的“大系統做小“的原則。依賴的服務不可用之后將會造成用戶無法登錄注冊。因此,用戶中心在用戶操作完之后,將用戶事件入庫后發送至MQ,第三方業務監聽用戶事件。用戶中心和下游業務解耦,同時用戶操作事件入庫后,在MQ不可用或者消息丟失的時候可做補償處理。用戶的畫像數據也在很大程度上來源于此處的數據。
用戶中心涉及到用戶的登錄注冊更改密碼等核心功能,能否及時發現系統的問題成為關鍵指標,因此對業務的監控顯得尤為重要。需要對用戶中心重要接口的QPS、機器的內存使用量、垃圾回收的時間、服務的調用時間等做詳細的監控。當某個接口的調用量下降的時候,監控會及時發出報警。除了這些監控之外,還有對數據庫Binlog的寫入,前端組件,以及基于ZipKin全鏈路調用時間的監控,實現從用戶發起端到結束端的全面監控,哪怕出現一點問題,監控隨時會告訴你哪里出問題了。比如運營互動推廣注冊量下降的時候,用戶中心就會發出報警,可以及時通知業務方改正問題,挽回損失。
關于億級用戶中心的設計方法教程問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。