天天看點

重構國内遊戲賬号登入系統的思考和實踐

作者:閃念基因

背景

賬号登入系統,作為遊戲發行平台最重要的應用之一,在目前的發行平台的應用架構中,主要承載的是使用者的賬号注冊、登入、實名、防沉迷、隐私合規、風控等職責。合規作為企業經營的生命線,同時,賬号登入作為線上鍊路轉化的第一站,是以賬号登入系統的穩定性,一直面臨極高的要求。

出于穩定性需要,遊戲發行平台在很早期就實踐了兩地三中心的多活架構。目前以公司公司機房為中心,同時在華東公有雲和華南公有雲,實作了兩地三中心部署方案。依托公有雲的主要考量因素在于,早期公有雲提供的快速彈性和按量付費的能力,能夠高效的承接遊戲業務方的發展訴求;其次,對于華南地區的選擇,也是優先考慮重要合作方所處的地理位置。

基于穩定性、效率、成本的多方考量,最終實作了公司機房、華東公有雲A、華南公有雲B的混合雲架構。混合雲架構帶來便利的同時,也存在普遍的挑戰,其中最顯著在于兩個方面:

其一、資料架構,資料在雲端存儲的存在的洩露風險。在具體實施層面,資料架構的差異化,将會導緻底層的領域服務所能傳遞的API必定存在差異,主要差異展現在API的能力範圍。比如,bilibili授權登入等能力,雲上機房是無法做到實際支援的,服務端隻能将相關請求轉發至公司機房處理。

其二、PaaS平台的差異。公司基礎架構在資料庫管理平台、KV資料管理平台、消息隊列等産品支撐已相當成熟,但早期在公有雲的應用部署隻能依托雲原生的能力。這導緻在底層的依賴上,原本需要建立一個标準防腐層,屏蔽具體的實作差異,但因為業務進度的需要,導緻有所折中欠缺。

由于存在以上兩個顯著的挑戰,項目進展等因素的考慮,最終演變的應用架構如下,也是以賬号登入系統,在公司機房和公有雲機房演變出了兩套代碼倉庫(login-idc-api / login-cloud-api)。

重構國内遊戲賬号登入系統的思考和實踐

遊戲賬号登入應用的兩套代碼,疊代至今已近7年。目前應用,雖然在主觀上了解已經疊代趨于穩定,但是基于最近一年完成的疊代版本統計,全年疊代版本超過10次,版本平均耗時接近4周,包括設計、開發、測試、上線。雙代碼倉庫導緻的設計、開發、測試,部署平均耗時增加了30%~40%。其次,在雙代碼倉庫,且依賴Spring等核心元件版本較低的情況下,對齊公司基礎架構的各項産品,可預見工作量的前提之下,該系統的重構工作,已經到了不得不行的地步。

挑戰

為穩定性訴求極高、疊代長久的系統發起重構,需要巨大勇氣,得失于轉瞬之間。

  1. 重要性:承載千萬MAU,L0不可降級鍊路;支撐113個SDK版本(采樣周期:2024/02/15 - 2024/03/15)
  2. 穩定性:重構過程中SLO 4個9的約定,必須在執行之前規劃完成執行細節和過程,全面又不失細緻;
  3. 複雜度:業務本身内在的複雜度,7年來的高速發展,積累的大量技術債。

價值

1.效率:開發效率提升50%,疊代效率提升30%-40%

2.成本:節省人力(預期目前系統的生命周期至少5年)

3.品質:

  • 代碼圈複雜度:降低40%;
  • 内網調用去SLB依賴,核心鍊路接口RT 99.9Line 提升31.5%

4.文化:踐行“極緻執行”的價值觀。

實踐:如何實作重構?

戰略方向

方案一、放棄現有的兩地三中心,賬号登入全部統一到公司标準,不依賴雲廠商。該方案作為未來的長期方向,完全回公司部署符合公司長期戰略規劃,難點在于發行平台的應用架構,目前絕大多數服務還是重點依賴公有雲,短期内不具備獨立完成的可行性。

方案二、推動主站賬号團隊,打通公司和公有雲的資料架構,實作領域能力的對等,但存在資料安全風險,考慮到項目收益和跨團隊的工作成本,并非目前最高ROI的選擇。

方案三、将雙代碼倉庫中,有關于資料架構和PaaS的差異,以重構的辦法實作相容,達到最終的代碼倉庫統一。

思考過程

重構的前提

回顧Martin Flower有關重構的著作《重構 改善既有代碼的設計》一文中,将”重構“以名詞、動詞兩種方式定義如下:

重構(名詞):對軟體内部結構的一種調整,目的是在不改變軟體可觀察行為的前提下,提高其可了解性,降低其修改成本。

重構(動詞):使用一系列重構手法,在不改變軟體可觀察行為的前提下,調整其結構。

這本關于重構的經典,在兩種定義方式中,提到了3個關鍵概念,”調整“、”結構“、”不改變軟體可觀察行為“。這3個關鍵詞組合起來,約等于行動指南。”不改變軟體的可觀察行為“作為前提,如何了解可觀察行為,Martin并未在技術和業務上做過明确的定義,是以在這個概念的了解上,不免要多一些執行者的個人了解和思考。

如果把應用架構視為目前的結構,對于“可觀察行為”的了解,從以下幾個角度嘗試去思考:

1.系統職責,前後端分離的應用架構之下,傳遞這些職責的API是一類可觀察的行為;

2.系統依賴項,是一類可觀察的行為,包括兩個大部分:

  • bilibili賬号的領域服務、遊戲發行的領域服務、第三方服務(比如:極驗服務提供商)
  • PaaS基礎架構(公司的資料庫、KV資料系統、消息隊列等等;公有雲的雲MySQL、Redis、Kafka等等)

3.系統的橫向服務。從分層架構的層次上來說,目前定位是應用服務層BFF,本不應該出現較大的橫向影響,但是過往高速演進的過程中,承載了部分領域服務的職責(比如:查詢遊戲資訊、查詢活躍遊戲、查詢使用者資訊等),是以姑且對于這一類概括為橫向的影響。

形形色色的差異

目前應用架構下,雙倉庫在邏輯子產品、應用内分層(J2EE的3層模型)的特點,展示如圖:

重構國内遊戲賬号登入系統的思考和實踐

在不可變的前提之下,試圖通過對齊雙倉庫代碼差異,以求得統一的思路,單從Service這一層來說(其依賴的bilibili賬号服務API超過80個),了解起來已足夠讓人頭大,其變更風險也是極其巨大,更何況還有JDBC ORM、Redis在技術選型和使用限制上的差異。如此風險再加上即将投入較大的工作量,勢必提案困難重重。基于靜态的子產品和應用内代碼分層來看,這巨大的差異看似是無法“暴力”抹平。

消失的複雜度

柳暗花明時刻,來源于應用運作時的一個事實:“生産環境多次高可用切流”。這個事實不僅實作了對SDK上遊異地多活的承諾,而且經過了生産環境的多次驗證。簡而言之,雙倉庫在Controller、Service這兩個最業務邏輯最複雜,技術債積累最多的分層,雖各有千秋,但殊途同歸。

由此推理,重構過程中的最大的認知注意力負擔,可以直接從這兩層忽視。這兩層注意力的移除,同時也利好DB和Redis的相容工作量,作為基礎架構中最重要的兩個元件,完全無需再關注各類RedisTemplate/Jedis,Key命名、JdbcTemplate/Mybatis 、SQL的之間的邏輯差異,因為他們隻是Controller和Service最終呈現出來的一部分。

在混沌中聚焦

SDK API鍊路:由于Controller、Service複雜度的消失,那麼剩餘的不可變的可觀察行為,就隻集中在DAO。DAO差異的本質來源于混合雲部署架構的挑戰(資料架構、PaaS差異),那麼實作政策也就清晰了,在DAO層基于運作時ZONE來辨別依賴的bilibili賬号API調用即可。參考六邊形架構,對于外部依賴和業務邏輯的隔離方式,實作核心業務邏輯對于外部API和PaaS解耦,以此降低變更侵入的影響面。

重構國内遊戲賬号登入系統的思考和實踐

PaaS的差異在業務邏輯層Service(或者少量的Controller)已經被消化,是以無需再考慮邏輯上的差異,隻需關注架構和資料庫的版本相容性。

領域類和通知類API鍊路:這條鍊路雖然不是核心,但這是混合雲資料架構差異的展現。生産環境的調用集中在公司機房,能力”較小“的公有雲應用,向公司應用融合靠攏,也正因如此,統一之後的代碼倉庫是以公司機房代碼倉為基準。

轉發類API鍊路:這條鍊路差異化的本質也是來源于混合雲部署的資料架構差異,在目前的融合方案中無法解決,是以隻能沿用現有的轉發政策,但轉發後續可向上移交至API GW實作,這個已在計劃當中。

具體實作

重構國内遊戲賬号登入系統的思考和實踐

公司機房原倉庫為基準,在公有雲A/B可用區部署,可用區選擇與目前兩地三中心保持一緻。依賴的DB Schema在三機房原本就相同,是以可直接複用已有的DB執行個體。Redis,因其均有讀寫操作,避免灰階過程對于線上應用的資料污染,是以部署單獨的Redis叢集用于資料隔離,待完成灰階之後,一并下線原應用和原Redis叢集。

資料驗證

産品視角

  1. 基于使用者次元,驗證比對新老叢集的資料寫入和查詢;
  2. 基于遊戲次元,驗證比對新老叢集的資料寫入和查詢;
  3. 生産環境SDK,基于測試域名,實作核心SDK産品回歸驗證,覆寫全量用例;
  4. 其他非SDK API,實作全量的單測覆寫,基于接口實作驗收。

資料視角

  1. 資料庫:基于Job任務,實作源與目标資料源内容比對;
  2. 緩存:純緩存場景,灰階期間隔離部署,復原後不影響業務邏輯。緩存未命中直接遠端調用;
  3. 埋點/報表:基于灰階過程觀察遊戲次元的報表趨勢,并與過往資料進行比對。

釋出方案

釋出計劃設計,嚴格遵守公司安全生産要求:可灰階、可觀測、可恢複。

可灰階

灰階過程一共分為兩個大步:

Step1

在公司機房執行灰階部署,分批部署導入生産流量,發現異常立即復原。

Step2

在公有雲A執行全量釋出,但未接流;通過SLB規則配置,基于域名、規則的重要性、API的量級(調用量/周)制定規則級的SLB釋出計劃。公有雲B部署同樣重複此步驟。

可觀測

觀測的主要次元:業務和SLO、日志、性能

觀測1:原公有雲A應用流量切流後分布和成功率

重構國内遊戲賬号登入系統的思考和實踐

觀測2:新公有雲A應用流量切流後分布和成功率

重構國内遊戲賬号登入系統的思考和實踐

觀測3:新公有雲A應用錯誤碼分布

重構國内遊戲賬号登入系統的思考和實踐

觀測4:新公有雲A應用API性能

重構國内遊戲賬号登入系統的思考和實踐

觀測5:新公有雲A應用JVM性能

重構國内遊戲賬号登入系統的思考和實踐

可恢複

1.公司機房應用執行灰階部署,如遇異常立即復原,且不産生髒資料

2.新的公有雲A/B應用,通過SLB基于規則分批釋出,如遇異常立即復原,復原後流量指向原有對應機房服務叢集,Redis寫産生的髒資料不影響復原後業務邏輯

3.新的公有雲可用區,申請單獨的Redis執行個體,用于隔離不同代碼倉庫,不同Key命名風格的資料,避免復原過程中髒資料,對于原可用區服務的影響。

參考資料

  • 《B站安全生産專項建設實踐》
  • 《重構 改善既有代碼的設計》Martin Flower
  • 《Complexity Has to Live Somewhere》

作者:豐富

來源-微信公衆号:哔哩哔哩技術

出處:https://mp.weixin.qq.com/s/ZL1fsBQUlCRKE0nEQm8Msg

繼續閱讀