Saas系統(tǒng)分級:
SaaS系統(tǒng)架構成熟度模型的5個級別——從“混亂”到“烏托邦”。
第0級(混亂):每次新增一個客戶竭翠,都會新增軟件的一個實例。
第1級(受控的混亂):所有客戶都運行在軟件的同一個版本上,而且任何的定制化都通過修改配置來實現(xiàn)秀睛。
第2級(多租戶[multi-tenant]币他、高層建筑[Highrise]):所有的客戶都已經(jīng)可以在軟件的同一個版本上運行了坞靶,而且他們都在同一個“實例”上運行。
第3級(多租戶蝴悉, 擴建[Build-Out]):此時你已經(jīng)擁有了多租戶彰阴、單一版本的軟件模型。不過你還是可以通過硬件擴展(scale-out)的方式來進行擴充拍冠。
第4級(烏托邦):如同第3級尿这,除非你可以找出有效的方式,以在不同的“實例”上運行不同版本的軟件倦微。
應用程序必須支持多租戶:
多租戶可以分為幾個不同的類別(如列表下方的圖所示):
1.1妻味,云中的簡單虛擬化,其中只對硬件進行共享欣福。
1.2责球,共享應用程序,對每個租戶使用不同的數(shù)據(jù)庫拓劝。
1.3雏逾,共享應用程序和數(shù)據(jù)庫(效率最高,真正的多租戶)郑临。
1. 分層設計
Saas 系統(tǒng)分層大概是:
Saas系統(tǒng)分層:租戶識別 > 應用層 > 數(shù)據(jù)訪問層 > 緩存層 > 數(shù)據(jù)庫
業(yè)務代碼都是寫在應用層栖博。
租戶識別可以用spring攔截器實現(xiàn),然后使用ThreadLocal傳遞給后端
數(shù)據(jù)庫和緩存層對應用層應該是透明的厢洞。程序員在寫代碼的時候仇让,只關心業(yè)務邏輯,不應該擔心多租戶的問題躺翻。
2. 數(shù)據(jù)隔離要透明
saas系統(tǒng)說起來很簡單丧叽,任何系統(tǒng)似乎加個tenant_id(租戶id)就變成saas系統(tǒng)了。比如原來的用戶登錄是:
改成
對于復雜業(yè)務的saas系統(tǒng)公你,這樣做法非常危險踊淳,而且開發(fā)效率很低。你想想如果那個程序員寫sql時候忘了加 “ and tenant_id =1” 陕靠,結果不堪設想迂尝。
比較好做法是在數(shù)據(jù)庫訪問層對SQL進行改寫脱茉。
在連接池根據(jù)TenatnContext改寫Sql。
這樣做好處是垄开,一來程序猿最多把系統(tǒng)搞down了琴许,也不至于信息串了互相泄露。二來將來做分表分庫也很方便溉躲,上層應用不用修改虚吟。
3. 租戶識別方案
比較好做法是通過url識別租戶。系統(tǒng)是給租戶生成一個隨機的三級域名签财,比如 abc.crm.baidu.com. 如果客戶想使用自己的域名,可以在cname到我們生成的三級域名偏塞,并在管理系統(tǒng)里面做綁定唱蒸。
這樣一個租戶可以有兩個域名,訪問saas,一個隨機生成的三級域名灸叼,另外一個租戶自己的域名.代碼里面可以根據(jù)過來的域名神汹,判斷是那個租戶然后初始化TenantContext.
如果不想通過域名來做,也可以通過登錄名來判斷古今。這種方式要涉及到租戶切換問題屁魏。
4. 智能DNS
Nginx中rewrite實現(xiàn)二級域名、三級域名捉腥、泛域名氓拼、路徑的重寫
5. 租戶管理系統(tǒng)(計費,訂購抵碟,定制桃漾,充值,催繳)
Saas系統(tǒng)是必須考慮計費系統(tǒng)和租戶控制系統(tǒng)拟逮。這個系統(tǒng)需要都是獨立設計撬统。比如那個租戶購買了那些模塊,一個月多少錢敦迄。租戶可以創(chuàng)建最多的用戶數(shù)恋追。計費到期郵件提醒等功能。
計費方式一般有兩種罚屋,周期性計費苦囱,類似月租方案,和使用量計費,用多少付多少沿后。周期性計費比較簡單沿彭。也可以兩者結合起來。
6. 定制化開發(fā)
SAAS的優(yōu)勢在于一套系統(tǒng)多人使用尖滚,似乎和定制化開發(fā)有沖突喉刘。比如A客戶想要A功能瞧柔,B客戶不想要。但定制化開發(fā)是無法避免的睦裳,比如CRM系統(tǒng)這樣復雜的系統(tǒng)造锅,不可能一套系統(tǒng)滿足所有公司的要求。定制化開發(fā)盡可能分系統(tǒng)廉邑,分模塊去做哥蔚。然后通過控制臺中配置不同租戶訂購不同模塊,那些模塊可以在前端頁面上顯示蛛蒙。不同的子系統(tǒng)需要分開部署糙箍。前端可通過nginx根據(jù)url分發(fā),比如 abc.crm.baidu.com/bi/xxx/xx這個地址牵祟,就分發(fā)到BI子系統(tǒng)深夯。不要嘗試OSGI去搞模塊化,這個是個大坑诺苹。
還有開發(fā)和產(chǎn)品咕晋,現(xiàn)有需求一定要分析清楚,不要一上線發(fā)現(xiàn)后患無窮收奔。新功能盡量做的獨立可以配置掌呜。
7. 灰度升級
SAAS付費企業(yè)客戶對系統(tǒng)問題都特別敏感。為了減少升級可能出現(xiàn)問題的影響范圍坪哄,一般都采用灰度升級策略质蕉。如果使用了url來區(qū)分不同租戶,灰度升級配置就會很方便翩肌∈伟可以配置nginx 來根據(jù)域名做分發(fā),比如租戶A(aaa.com)到實例1(版本1.0)摧阅,租戶B(bbb.com)到實例2(版本). 當需要域名配置非常多的時候汰蓉,nginx配置文檔會亂。這塊時候可以考慮使用nignx_lua來寫一些擴展模塊棒卷。
8. 容量估計
對高并發(fā)的估計顾孽,讀寫操作的頻率估計。
9. Saas平臺架構分層分析
Saas平臺架構需要完成從用戶申請鏈接saas到用戶對自己購買的功能模塊的應用整個過程比规,用戶用起saas看似簡單快捷若厚,但這個過程卻需要saas平臺架構默默完成的非常復雜的處理過程。通過對saas平臺架構的了解蜒什,可以清晰的分化數(shù)據(jù)的處理過程测秸,讓用戶也可以明白saas平臺架構處理數(shù)據(jù)的優(yōu)勢。下面介紹:saas平臺架構分為哪幾部分。
saas平臺架構之呈現(xiàn)層:
saas平臺架構的呈現(xiàn)層可以使用的客戶端可能都瀏覽器或本地客戶端霎冯。如果是瀏覽器則需要Web界面技術铃拇、交互技術等技術(如:HTMl5技術、CSS3技術沈撞、Ajax技術等)的支持慷荔,如果是軟件客戶端則需要遠程桌面技術、軟件交互技術等技術支持缠俺。
saas平臺架構之調(diào)度層:
saas平臺架構的調(diào)度層體現(xiàn)分布式系統(tǒng)的特性之一显晶。調(diào)度層首先負責識別并通過AAA認證每個用戶請求,然后根據(jù)業(yè)務處理器的負載壹士、業(yè)務特征進行合理的調(diào)度磷雇。通過應用這樣的架構SaaS平臺可以橫向擴展。此外在存儲躏救、緩存等方面為了滿足平臺的橫向擴展需求倦春,調(diào)度層也必須具有良好的可擴展性。
saas平臺架構之業(yè)務層:
saas平臺架構的業(yè)務層負責接收調(diào)度層轉(zhuǎn)發(fā)過來的請求落剪,而且還要通過對接受到的請求執(zhí)行真正的業(yè)務邏輯。一般來說業(yè)務邏輯的執(zhí)行使用一臺服務器就夠了尿庐。因此業(yè)務層實際是由一排對等的服務器組成的忠怖,每臺服務器都執(zhí)行相同的業(yè)務邏輯。
saas平臺架構之數(shù)據(jù)層:
saas平臺架構的數(shù)據(jù)庫集群用于處理存儲關系性很強并且對事務性要求很高的業(yè)務數(shù)據(jù)抄瑟,這類數(shù)據(jù)目前還要用傳統(tǒng)的數(shù)據(jù)庫集群技術來解決凡泣,saas平臺架構的數(shù)據(jù)庫集群主要是根據(jù)業(yè)務特征制定數(shù)據(jù)拆分方案。同時分布式數(shù)據(jù)庫用于存放海量但關系性不強的數(shù)據(jù)(如:用戶的操作日志等)皮假。
以上是對“Saas系統(tǒng)架構的思考,多租戶Saas架構設計分析”的介紹,從saas平臺架構處理數(shù)據(jù)可以看出saas平臺的應用有很強的優(yōu)勢侠畔,如用戶使用saas非常方便簡單只要瀏覽器或本地客戶端接口毛萌,saas平臺處理數(shù)據(jù)要經(jīng)過層層認證saas產(chǎn)品安全可靠,saas平臺優(yōu)化處理數(shù)據(jù)提高saas性能褪测。
多租戶Saas系統(tǒng)架構還應該滿足以下需求:
Saas 正在蓬勃發(fā)展猴誊,最近的銷售易被騰訊重金加持,看好 SaaS 系統(tǒng)的未來侮措!
多租戶系統(tǒng)架構
運行時架構圖:
做為SaaS的基本特征懈叹,多租戶對系統(tǒng)的很多方面都產(chǎn)生了很多深遠的影響.就數(shù)據(jù)層面的架構來說,基本上分成了多租戶共享單一數(shù)據(jù)庫分扎、單一租戶獨享單一數(shù)據(jù)庫以及介于兩者之間的單一數(shù)庫下的單一租戶獨享單一schema三種方案澄成。
這篇文章 http://msdn.microsoft.com/en-us/library/aa479086.aspx 對三種架構方案做了全面和細致的分析,里面提到的pattern都是非常實用的(特別是Name-Value Pairs模式)。
讓我印象最深刻的是,本文在分析每種方案的利弊和適用場景時墨状,視野寬廣卫漫,目光長遠,考慮到了很多過去我自己沒有想到過的因素歉胶。比如在談到數(shù)據(jù)安全時汛兜,作者舉例說對于某些類型的租戶對數(shù)據(jù)安全是非常關切的(比如銀行),這一類用戶是很難容忍將自己的數(shù)據(jù)與其他租戶放在一起的通今。再比如是否會考慮為租戶提供數(shù)據(jù)備份與恢復的增值服務供需要的租戶購買粥谬。還有就是綜合預期產(chǎn)品未來的租戶數(shù)量(10個和1000就會有質(zhì)的不同),平均每個租戶的數(shù)據(jù)量辫塌,以及單一租戶的并發(fā)訪問量等等.這些都會影響到方案的選擇.總之這是一篇關于多租戶Multi-Tenant數(shù)據(jù)架構方面非常全面的文章漏策!
nginx:主要做多域名映射,根據(jù)域名映射到不同的web Server臼氨,比如接受到域名A請求掺喻,則路由到web Server1,接受到域名B請求储矩,則路由到web server2
web server:主要是放網(wǎng)頁或者web相關的感耙,比如用戶登錄業(yè)務等,客戶多變的需求都放到這層實現(xiàn)持隧,比如有些客戶在要求自己的網(wǎng)站注冊的商家即硼,必須上傳運業(yè)執(zhí)照,有些不需要等可變的需求
basic server:后臺服務屡拨,這層的服務都是共有的只酥,對于每個用戶都不變的基礎服務都放這層,并且這層做數(shù)據(jù)庫路由呀狼,每個域名一個數(shù)據(jù)庫(每個客戶一個數(shù)據(jù)庫裂允,做數(shù)據(jù)隔離,當時個人還不同意哥艇,從事后來看绝编,這種架構確實好處比較多,特別是客戶以前就有一個網(wǎng)站貌踏,然后在往新庫里導數(shù)據(jù)瓮增,然后又刪新庫里的數(shù)據(jù)時,不擔心會把其它客戶的數(shù)據(jù)刪掉)哩俭。
DB :每個客戶一個數(shù)據(jù)庫绷跑,做到數(shù)據(jù)上的邏輯隔離和物理隔離(當時設想每個外部客戶1個域名,然后在數(shù)據(jù)庫的每個表里加平臺id以區(qū)分是那個外部客戶的數(shù)據(jù)凡资,后來架構師力排眾議砸捏,每個客戶1個數(shù)據(jù)庫谬运,做到數(shù)據(jù)隔離,Basic Server做數(shù)據(jù)庫路由)
如何做數(shù)據(jù)庫路由垦藏?
web server根據(jù)請求的url梆暖,拿到域名,然后查出平臺id掂骏。
basic server中的每個接口轰驳,都需要帶平臺id字段。
web server 調(diào)用basic server接口時弟灼,傳入平臺id级解。然后在basic server的service層,做aop田绑,根據(jù)參數(shù)里的平臺id勤哗,找到配置好的平臺id和數(shù)據(jù)庫連接信息,把連接信息放入ThreadLocal掩驱,包裝自己的DataSource芒划,在DataSource里獲得數(shù)據(jù)庫連接時,用ThreadLocal里的數(shù)據(jù)庫連接信息欧穴,獲得數(shù)據(jù)庫連接民逼,方法執(zhí)行完,清除數(shù)據(jù)庫連接(這里曾出現(xiàn)過小問題涮帘,service嵌套套用的時候拼苍,里面service方法退出清除數(shù)據(jù)庫連接,導致外面service在操作數(shù)據(jù)庫時焚辅,拿不到連接信息而報錯,后來增加了一個調(diào)用層次計數(shù))
日志監(jiān)控層
任何可以反映 SpringBoot 微服務運行狀態(tài)的數(shù)據(jù)苟鸯,對于監(jiān)控來說都是十分重要的“財產(chǎn)”同蜻,都應該盡量采集上來進行分析,從而在分析的基礎上謀求對 SpringBoot 微服務的改進早处。
對于應用日志來說湾蔓,在單機單結點的年代,我們只要登錄應用部署的服務器砌梆,然后使用 tail-f 之類的命令就可以實時地查看應用日志信息默责,并決定如何做出應對。
但對于 SpringBoot 微服務來說咸包,數(shù)量上的特征已經(jīng)決定了單機單結點的方法已經(jīng)行不通了桃序,如果還是一臺臺地去查看應用日志,我們不但會“疲于奔命”烂瘫,而且還無法及時有效地發(fā)現(xiàn)微服務作為一個邏輯服務集群整體上的狀態(tài)特征現(xiàn)在是什么樣的媒熊,我們這時候需要的是一種集中式的日志采集、存儲和分析平臺。
對于 Java 開發(fā)者來說芦鳍,ELK 技術棧正是為此而生的(E=ElasticSearch嚷往,L=Logstash,K=Kibana)柠衅,整個功能鏈路如圖 2 所示皮仁。
圖 2 基本ELK技術棧功能鏈路示意圖
不過,鑒于 ElasticSearch 對高頻度的寫入并沒有很高的承受力菲宴,在正式的生產(chǎn)環(huán)境中贷祈,我們一般會采用如圖 3 所示的部署結構。
圖 3 生產(chǎn)環(huán)境典型 ELK 技術棧功能鏈路部署示意圖
即我們使用 Kafka 作為數(shù)據(jù)采集的緩沖區(qū)裙顽,以便減輕從大量應用結點采集日志并寫入 ElasticSearch 的負擔付燥。