一種多租戶系統架構
一種多租戶系統架構
背景:
去年的時候,因為某些特殊原因,有幸帶了一個組,參與了B2B平臺的開發。說是B2B平臺,因為這套程序開發完了后,可以拿給多個客戶使用。客戶可以搭建一套具有京東商城風格,那樣的網站。然后允許商家在網站上注冊,開店,或者賣東西,買東西,網站的用戶定位為商家。
在需求分析完后,分為了三個組。
第一個組是商城組,主要負責:商家注冊,登錄,前端商城主站搭建,商品詳情頁,搜索頁,購物車,下單頁,商品評價,仲裁等功能
第二個組是商家組:主要負責商家基本信息維護,商品維護,sku的庫存,上下架,訂單管理,發貨地址管理,會員管理,店鋪裝修,店鋪主站等
第三個組是平臺管理,主要負責:類目,品牌管理,商家信息申請審核,店鋪審批,商品發布審核,訂單結算,商品價格管理,以及主站首頁輪播圖,樓層等管理。還有就是給我們自己運營人員用的一些功能:比如域名和平臺id等功能的管理。
運行時架構圖:
nginx:主要做多域名映射,根據域名映射到不同的web Server,比如接受到域名A請求,則路由到web Server1,接受到域名B請求,則路由到web server2
web server:主要是放網頁或者web相關的,比如用戶登錄業務等,客戶多變的需求都放到這層實現,比如有些客戶在要求自己的網站注冊的商家,必須上傳運業執照,有些不需要等可變的需求
basic server:后臺服務,這層的服務都是共有的,對于每個用戶都不變的基礎服務都放這層,并且這層做數據庫路由,每個域名一個數據庫(每個客戶一個數據庫,做數據隔離,當時個人還不同意,從事后來看,這種架構確實好處比較多,特別是客戶以前就有一個網站,然后在往新庫里導數據,然后又刪新庫里的數據時,不擔心會把其它客戶的數據刪掉)。
DB :每個客戶一個數據庫,做到數據上的邏輯隔離和物理隔離(當時設想每個外部客戶1個域名,然后在數據庫的每個表里加平臺id以區分是那個外部客戶的數據,后來架構師力排眾議,每個客戶1個數據庫,做到數據隔離,Basic Server做數據庫路由)
如何做數據庫路由?
web server根據請求的url,拿到域名,然后查出平臺id。basic server中的每個接口,都需要帶平臺id字段。Web server 調用basic server接口時,傳入平臺id。然后在basic server的service層,做aop,根據參數里的平臺id,找到配置好的平臺id和數據庫連接信息,把連接信息放入ThreadLocal,包裝自己的DataSource,在DataSource里獲得數據庫連接時,用ThreadLocal里的數據庫連接信息,獲得數據庫連接,方法執行完,清楚數據庫連接(這里曾出現過小問題,service嵌套套用的時候,里面service方法退出清楚數據庫連接,導致外面service在操作數據庫時,拿不到連接信息而報錯,后來增加了一個調用層次計數)