1. 微服務(wù)架構(gòu)介紹
1.1 什么是微服務(wù)架構(gòu)裁赠?
形像一點(diǎn)來說界阁,微服務(wù)架構(gòu)就像搭積木,每個微服務(wù)都是一個零件挂据,并使用這些零件組裝出不同的形狀。通俗來說儿普,微服務(wù)架構(gòu)就是把一個大系統(tǒng)按業(yè)務(wù)功能分解成多個職責(zé)單一的小系統(tǒng)崎逃,并利用簡單的方法使多個小系統(tǒng)相互協(xié)作,組合成一個大系統(tǒng)眉孩。
如果學(xué)科派一點(diǎn)个绍,微服務(wù)架構(gòu)就是把因相同原因而變化的功能聚合到一起,而把因不同原因而變化的功能分離開浪汪,并利用輕量化機(jī)制(通常為HTTP RESTful API)實(shí)現(xiàn)通信巴柿。
追本溯源,Martin Folwer對微服務(wù)架構(gòu)的定義是:
微服務(wù)架構(gòu)是一種架構(gòu)模式死遭,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù)广恢,服務(wù)之間互相協(xié)調(diào)、互相配合呀潭,為用戶提供最終價值钉迷。每個服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)與服務(wù)間采用輕量級的通信機(jī)制互相協(xié)作(通常是基于HTTP協(xié)議的RESTful API)钠署。每個服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu)建糠聪,并且能夠被獨(dú)立的部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等谐鼎。另外舰蟆,對具體的服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文狸棍,選擇合適的語言身害、工具對其進(jìn)行構(gòu)建。
對于我個人草戈,我更喜歡一種延續(xù)性的解釋题造,微服務(wù)架構(gòu)≈ 模塊化開發(fā)+分布式計(jì)算。不管微服務(wù)架構(gòu)的定義怎么樣猾瘸,都是在描述一個核心思想:把大系統(tǒng)拆分成小型系統(tǒng)界赔,把大事化小丢习,以降低系統(tǒng)的復(fù)雜性,從而大幅降低系統(tǒng)建設(shè)淮悼、升級咐低、運(yùn)維的風(fēng)險(xiǎn)和成本。
順帶提一下袜腥,亞馬遜創(chuàng)始人Jeff Bezos在2002年就說過:所有團(tuán)隊(duì)的模塊都要以Service Interface的方式將數(shù)據(jù)和功能開放出來见擦。不這樣做的人會被炒魷魚。這才是思路超前的大牛羹令。
需要注意的是“微服務(wù)”與“微服務(wù)架構(gòu)”是有本質(zhì)區(qū)別的鲤屡。“微服務(wù)”強(qiáng)調(diào)的是服務(wù)的大小福侈,它關(guān)注的是某一個點(diǎn)酒来。而“微服務(wù)架構(gòu)”則是一種架構(gòu)思想,需要從整體上對軟件系統(tǒng)進(jìn)行通盤的考慮肪凛。
Chris Richardson說:“微服務(wù)”是一個很糟糕的名字堰汉,它導(dǎo)致開發(fā)人員創(chuàng)建了許多粒度很小的服務(wù),每個服務(wù)擁有一個單獨(dú)的REST端點(diǎn)伟墙。不僅如此翘鸭,這個名字還暗示了微服務(wù)在開發(fā)者心目中的重要位置。例如戳葵,人們會說“我們可以用微服務(wù)來解決這個問題”就乓;我也看到了越來越多的“某某微服務(wù)框架”,而實(shí)際上拱烁,這些框架跟微服務(wù)架構(gòu)不一定有太多聯(lián)系档址,它們只是簡單的Web框架(如:spring-boot)。使用“微服務(wù)架構(gòu)”這個名字會更恰當(dāng)些邻梆。它是一種架構(gòu)風(fēng)格守伸,它把一系列協(xié)作的服務(wù)組織成一個系統(tǒng)來支撐業(yè)務(wù)。
1.2常見的微服務(wù)組件
1.服務(wù)注冊:服務(wù)提供方將自己調(diào)用地址注冊到服務(wù)注冊中心浦妄,讓服務(wù)調(diào)用方能夠方便地找到自己尼摹。
2.服務(wù)發(fā)現(xiàn):服務(wù)調(diào)用方從服務(wù)注冊中心找到自己需要調(diào)用的服務(wù)的地址。
3.負(fù)載均衡:服務(wù)提供方一般以多實(shí)例的形式提供服務(wù)剂娄,負(fù)載均衡功能能夠讓服務(wù)調(diào)用方連接到合適的服務(wù)節(jié)點(diǎn)蠢涝。并且,節(jié)點(diǎn)選擇的工作對服務(wù)調(diào)用方來說是透明的阅懦。
4.服務(wù)網(wǎng)關(guān):服務(wù)網(wǎng)關(guān)是服務(wù)調(diào)用的唯一入口和二,可以在這個組件是實(shí)現(xiàn)用戶鑒權(quán)、動態(tài)路由耳胎、灰度發(fā)布惯吕、A/B測試惕它、負(fù)載限流等功能。
5.配置中心:將本地化的配置信息(properties,
xml, yaml等)注冊到配置中心废登,實(shí)現(xiàn)程序包在開發(fā)淹魄、測試、生產(chǎn)環(huán)境的無差別性堡距,方便程序包的遷移甲锡。
6.API管理:以方便的形式編寫及更新API文檔,并以方便的形式供調(diào)用者查看和測試羽戒。
7.集成框架:微服務(wù)組件都以職責(zé)單一的程序包對外提供服務(wù)缤沦,集成框架以配置的形式將所有微服務(wù)組件(特別是管理端組件)集成到統(tǒng)一的界面框架下,讓用戶能夠在統(tǒng)一的界面中使用系統(tǒng)易稠。
8.分布式事務(wù):對于重要的業(yè)務(wù)缸废,需要通過分布式事務(wù)技術(shù)(TCC、高可用消息服務(wù)缩多、最大努力通知)保證數(shù)據(jù)的一致性呆奕。具有代表性的有spring transaction
9.調(diào)用鏈:記錄完成一個業(yè)務(wù)邏輯時調(diào)用到的微服務(wù)养晋,并將這種串行或并行的調(diào)用關(guān)系展示出來衬吆。在系統(tǒng)出錯時,可以方便地找到出錯點(diǎn)绳泉。具有代表性的有pinpoint.
10.支撐平臺:系統(tǒng)微服務(wù)化后逊抡,系統(tǒng)變得更加碎片化,系統(tǒng)的部署零酪、運(yùn)維冒嫡、監(jiān)控等都比單體架構(gòu)更加復(fù)雜,那么四苇,就需要將大部分的工作自動化⌒⒘瑁現(xiàn)在,可以通過Docker等工具來中和這些微服務(wù)架構(gòu)帶來的弊端月腋。 例如:持續(xù)集成蟀架、藍(lán)綠發(fā)布、健康檢查榆骚、性能健康等等片拍。嚴(yán)重點(diǎn),以我們兩年的實(shí)踐經(jīng)驗(yàn)妓肢,可以這么說捌省,如果沒有合適的支撐平臺或工具,就不要使用微服務(wù)架構(gòu)碉钠。
一般情況下纲缓,如果希望快速地體會微服務(wù)架構(gòu)帶來的好處卷拘,使用Spring Cloud提供的服務(wù)注冊(Eureka)、服務(wù)發(fā)現(xiàn)(Ribbon)色徘、服務(wù)網(wǎng)關(guān)(Zuul) 三個組件即可以快速入門恭金。其它組件則需要根據(jù)自身的業(yè)務(wù)選擇性使用。
1.3微服務(wù)架構(gòu)有哪些優(yōu)勢劣勢褂策?
要談優(yōu)勢横腿,就一定要有對比,我們可以嘗試著從兩個維度來對比:
1.3.1單體架構(gòu)和微服務(wù)架構(gòu)的對比
【結(jié)論】:
n對于簡單項(xiàng)目來說斤寂,單體架構(gòu)5勝8敗耿焊。
(優(yōu)勢項(xiàng):開發(fā)效率、上手難度遍搞、運(yùn)維效率罗侯、硬件需求、項(xiàng)目成本溪猿;劣勢項(xiàng):系統(tǒng)設(shè)計(jì)(高內(nèi)聚低耦合)钩杰、系統(tǒng)設(shè)計(jì)(擴(kuò)展性)、需求變更響應(yīng)速度诊县、系統(tǒng)升級效率讲弄、知識積累、非功能需求依痊、職責(zé)避除、成就感、風(fēng)險(xiǎn))
n對于復(fù)雜項(xiàng)目來說胸嘁,單體架構(gòu)2勝11敗瓶摆。
(優(yōu)勢項(xiàng):上手難度、運(yùn)維效率性宏;劣勢項(xiàng):硬件需求群井、項(xiàng)目成本、開發(fā)效率毫胜、系統(tǒng)設(shè)計(jì)(高內(nèi)聚低耦合)书斜、系統(tǒng)設(shè)計(jì)(擴(kuò)展性)、需求變更響應(yīng)速度指蚁、系統(tǒng)升級效率菩佑、知識積累、非功能需求凝化、職責(zé)稍坯、成就感、風(fēng)險(xiǎn);)
1.3.2微服務(wù)與共享庫的對比.,
1.3.3什么場景需要用微服務(wù)架構(gòu)瞧哟?
看了上面的比較混巧,微服務(wù)架構(gòu)可以說是以壓倒性的優(yōu)勢勝過單體架構(gòu)和共享庫,會讓人產(chǎn)生一種錯覺勤揩,微服務(wù)架構(gòu)就是軟件開發(fā)中的銀彈咧党。
但是,正如大家所了解的陨亡,軟件研發(fā)是一個系統(tǒng)工程傍衡,它沒有銀彈冤荆,不能夠一招鮮吃遍天尖昏。正如當(dāng)年的CMMI和敏捷方法一樣,敏捷雖好驰弄,但它不一定能適用于所有的場景遮糖,它對組織環(huán)境绣的、團(tuán)隊(duì)氛圍、溝通方式欲账、技術(shù)能力這些都是有一些要求的屡江,如果用不好,反而會帶來一些負(fù)面影響赛不。
那么惩嘉,我們什么時候需要采用微服務(wù)呢?從我個人的經(jīng)驗(yàn)來看俄删,我認(rèn)為有三種場景可以考慮使用微服務(wù)宏怔。
1.規(guī)模大(團(tuán)隊(duì)超過10人)
2.業(yè)務(wù)復(fù)雜度高(系統(tǒng)超過5個子模塊)
3.需要長期演進(jìn)(項(xiàng)目開發(fā)和維護(hù)周期超過半年)
2.微服務(wù)架構(gòu)身份認(rèn)證
2
2.1背景介紹
從單體應(yīng)用架構(gòu)到分布式應(yīng)用架構(gòu)再到微服務(wù)架構(gòu)奏路,應(yīng)用的安全訪問在不斷的經(jīng)受考驗(yàn)畴椰。為了適應(yīng)架構(gòu)的變化、需求的變化鸽粉,身份認(rèn)證與鑒權(quán)方案也在不斷的變革斜脂。面對數(shù)十個甚至上百個微服務(wù)之間的調(diào)用,如何保證高效安全的身份認(rèn)證触机?面對外部的服務(wù)訪問帚戳,該如何提供細(xì)粒度的鑒權(quán)方案?本文將會為大家闡述微服務(wù)架構(gòu)下的安全認(rèn)證與鑒權(quán)方案儡首。
【單體應(yīng)用VS微服務(wù)】
隨著微服務(wù)架構(gòu)的興起片任,傳統(tǒng)的單體應(yīng)用場景下的身份認(rèn)證和鑒權(quán)面臨的挑戰(zhàn)越來越大。單體應(yīng)用體系下蔬胯,應(yīng)用是一個整體对供,一般針對所有的請求都會進(jìn)行權(quán)限校驗(yàn)。請求一般會通過一個權(quán)限的攔截器進(jìn)行權(quán)限的校驗(yàn),在登錄時將用戶信息緩存到session中产场,后續(xù)訪問則從緩存中獲取用戶信息鹅髓。
而微服務(wù)架構(gòu)下,一個應(yīng)用會被拆分成若干個微應(yīng)用京景,每個微應(yīng)用都需要對訪問進(jìn)行鑒權(quán)窿冯,每個微應(yīng)用都需要明確當(dāng)前訪問用戶以及其權(quán)限。尤其當(dāng)訪問來源不只是瀏覽器确徙,還包括其他服務(wù)的調(diào)用時醒串,單體應(yīng)用架構(gòu)下的鑒權(quán)方式就不是特別合適了。在為服務(wù)架構(gòu)下鄙皇,要考慮外部應(yīng)用接入的場景厦凤、用戶-服務(wù)的鑒權(quán)、服務(wù)-服務(wù)的鑒權(quán)等多種鑒權(quán)場景育苟。
David
Borsos在倫敦的微服務(wù)大會上提出了四種方案:
2.2常見的四種解決方案
2.2.1單點(diǎn)登錄(SSO)
這種方案意味著每個面向用戶的服務(wù)都必須與認(rèn)證服務(wù)交互较鼓,這會產(chǎn)生大量非常瑣碎的網(wǎng)絡(luò)流量和重復(fù)的工作违柏,當(dāng)動輒數(shù)十個微應(yīng)用時博烂,這種方案的弊端會更加明顯。
2.2.2分布式Session
分布式會話方案原理主要是將關(guān)于用戶認(rèn)證的信息存儲在共享存儲中漱竖,且通常由用戶會話作為key來實(shí)現(xiàn)的簡單分布式哈希映射禽篱。當(dāng)用戶訪問微服務(wù)時,用戶數(shù)據(jù)可以從共享存儲中獲取馍惹。在某些場景下躺率,這種方案很不錯,用戶登錄狀態(tài)是不透明的万矾。同時也是一個高可用且可擴(kuò)展的解決方案悼吱。這種方案的缺點(diǎn)在于共享存儲需要一定保護(hù)機(jī)制,因此需要通過安全鏈接來訪問良狈,這時解決方案的實(shí)現(xiàn)就通常具有相當(dāng)高的復(fù)雜性了后添。
2.2.3客戶端Token
令牌在客戶端生成,由身份驗(yàn)證服務(wù)進(jìn)行簽名薪丁,并且必須包含足夠的信息遇西,以便可以在所有微服務(wù)中建立用戶身份。令牌會附加到每個請求上严嗜,為微服務(wù)提供用戶身份驗(yàn)證粱檀,這種解決方案的安全性相對較好,但身份驗(yàn)證注銷是一個大問題漫玄,緩解這種情況的方法可以使用短期令牌和頻繁檢查認(rèn)證服務(wù)等茄蚯。對于客戶端令牌的編碼方案,Borsos更喜歡使用JSON Web Tokens(JWT),它足夠簡單且?guī)熘С殖潭纫脖容^好第队。
2.2.4客戶端Token與API網(wǎng)關(guān)結(jié)合
這個方案意味著所有請求都通過網(wǎng)關(guān)哮塞,從而有效地隱藏了微服務(wù)。在請求時凳谦,網(wǎng)關(guān)將原始用戶令牌轉(zhuǎn)換為內(nèi)部會話ID令牌忆畅。在這種情況下,注銷就不是問題尸执,因?yàn)榫W(wǎng)關(guān)可以在注銷時撤銷用戶的令牌家凯。
2.3微服務(wù)常見安全認(rèn)證方案HTTP基本認(rèn)證
HTTP Basic Authentication(HTTP基本認(rèn)證)是HTTP 1.0提出的一種認(rèn)證機(jī)制,HTTP基本認(rèn)證的過程如下:
1.客戶端發(fā)送HTTP Request給服務(wù)器如失。
2.因?yàn)镽equest中沒有包含Authorization header绊诲,服務(wù)器會返回一個401 Unauthozied給客戶端,并且在Response的Header "WWW-Authenticate"中添加信息褪贵。
3.客戶端把用戶名和密碼用BASE64加密后掂之,放在Authorization Header中發(fā)送給服務(wù)器,認(rèn)證成功脆丁。
4.服務(wù)器將Authorization Header中的用戶名密碼取出世舰,進(jìn)行驗(yàn)證, 如果驗(yàn)證通過槽卫,將根據(jù)請求跟压,發(fā)送資源給客戶端。
2.3.1Session的認(rèn)證
基于Session的認(rèn)證應(yīng)該是最常用的一種認(rèn)證機(jī)制了歼培。用戶登錄認(rèn)證成功后震蒋,將用戶相關(guān)數(shù)據(jù)存儲到Session中,單體應(yīng)用架構(gòu)中躲庄,默認(rèn)Session會存儲在應(yīng)用服務(wù)器中查剖,并且將Session ID返回到客戶端,存儲在瀏覽器的Cookie中读跷。
但是在分布式架構(gòu)下梗搅,Session存放于某個具體的應(yīng)用服務(wù)器中自然就無法滿足使用了禾唁,簡單的可以通過Session復(fù)制或者Session粘制的方案來解決效览。
Session復(fù)制依賴于應(yīng)用服務(wù)器,需要應(yīng)用服務(wù)器有Session復(fù)制能力荡短,不過現(xiàn)在大部分應(yīng)用服務(wù)器如Tomcat丐枉、JBoss、WebSphere等都已經(jīng)提供了這個能力掘托。
除此之外瘦锹,Session復(fù)制的一大缺陷在于當(dāng)節(jié)點(diǎn)數(shù)比較多時,大量的Session數(shù)據(jù)復(fù)制會占用較多網(wǎng)絡(luò)資源。Session粘滯是通過負(fù)載均衡器弯院,將統(tǒng)一用戶的請求都分發(fā)到固定的服務(wù)器節(jié)點(diǎn)上辱士,這樣就保證了對某一用戶而言,Session數(shù)據(jù)始終是正確的听绳。不過這種方案依賴于負(fù)載均衡器颂碘,并且只能滿足水平擴(kuò)展的集群場景,無法滿足應(yīng)用分割后的分布式場景椅挣。
在微服務(wù)架構(gòu)下头岔,每個微服務(wù)拆分的粒度會很細(xì),并且不只有用戶和微服務(wù)打交道鼠证,更多還有微服務(wù)間的調(diào)用峡竣。這個時候上述兩個方案都無法滿足,就要求必須要將Session從應(yīng)用服務(wù)器中剝離出來量九,存放在外部進(jìn)行集中管理适掰。可以是數(shù)據(jù)庫荠列,也可以是分布式緩存攻谁,如Memchached、Redis等弯予。這正是David Borsos建議的第二種方案戚宦,分布式Session方案。
2.3.2基于Token的認(rèn)證
隨著Restful API锈嫩、微服務(wù)的興起受楼,基于Token的認(rèn)證現(xiàn)在已經(jīng)越來越普遍。Token和Session ID不同呼寸,并非只是一個key艳汽。Token一般會包含用戶的相關(guān)信息,通過驗(yàn)證Token就可以完成身份校驗(yàn)对雪。像Twitter河狐、微信、QQ瑟捣、GitHub等公有服務(wù)的API都是基于這種方式進(jìn)行認(rèn)證的馋艺,一些開發(fā)框架如OpenStack、Kubernetes內(nèi)部API調(diào)用也是基于Token的認(rèn)證迈套【桁簦基于Token認(rèn)證的一個典型流程如下:
1.用戶輸入登錄信息(或者調(diào)用Token接口,傳入用戶信息)桑李,發(fā)送到身份認(rèn)證服務(wù)進(jìn)行認(rèn)證(身份認(rèn)證服務(wù)可以和服務(wù)端在一起踱蛀,也可以分離窿给,看微服務(wù)拆分情況了)。
2.身份驗(yàn)證服務(wù)驗(yàn)證登錄信息是否正確率拒,返回接口(一般接口中會包含用戶基礎(chǔ)信息崩泡、權(quán)限范圍、有效時間等信息)猬膨,客戶端存儲接口允华,可以存儲在Session或者數(shù)據(jù)庫中。
3.用戶將Token放在HTTP請求頭中寥掐,發(fā)起相關(guān)API調(diào)用靴寂。
4.被調(diào)用的微服務(wù),驗(yàn)證Token權(quán)限召耘。
5.服務(wù)端返回相關(guān)資源和數(shù)據(jù)百炬。
基于Token認(rèn)證的好處如下:
1.服務(wù)端無狀態(tài):Token機(jī)制在服務(wù)端不需要存儲session信息,因?yàn)門oken自身包含了所有用戶的相關(guān)信息污它。
2.性能較好剖踊,因?yàn)樵隍?yàn)證Token時不用再去訪問數(shù)據(jù)庫或者遠(yuǎn)程服務(wù)進(jìn)行權(quán)限校驗(yàn),自然可以提升不少性能衫贬。
3.支持移動設(shè)備德澈。
4.支持跨程序調(diào)用,Cookie是不允許垮域訪問的固惯,而Token則不存在這個問題梆造。
5.下面會重點(diǎn)介紹兩種基于Token的認(rèn)證方案JWT/Oauth2.0。
2.3.2.1JWT介紹
JSON Web Token(JWT)是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)(RFC 7519)葬毫。來自JWT RFC 7519標(biāo)準(zhǔn)化的摘要說明:JSON Web Token是一種緊湊的镇辉,URL安全的方式,表示要在雙方之間傳輸?shù)穆暶魈瘛WT一般被用來在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息忽肛,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息烂斋,該Token也可直接被用于認(rèn)證屹逛,也可被加密。
2.3.2.2JWT認(rèn)證流程
1.客戶端調(diào)用登錄接口(或者獲取token接口)汛骂,傳入用戶名密碼罕模。
2.服務(wù)端請求身份認(rèn)證中心,確認(rèn)用戶名密碼正確香缺。
3.服務(wù)端創(chuàng)建JWT手销,返回給客戶端。
4.客戶端拿到JWT图张,進(jìn)行存儲(可以存儲在緩存中锋拖,也可以存儲在數(shù)據(jù)庫中,如果是瀏覽器祸轮,可以存儲在Cookie中)在后續(xù)請求中兽埃,在HTTP請求頭中加上JWT。
5.服務(wù)端校驗(yàn)JWT适袜,校驗(yàn)通過后柄错,返回相關(guān)資源和數(shù)據(jù)。
2.3.2.3JWT結(jié)構(gòu)
JWT是由三段信息構(gòu)成的苦酱,第一段為頭部(Header)售貌,第二段為載荷(Payload),第三段為簽名(Signature)疫萤。每一段內(nèi)容都是一個JSON對象颂跨,將每一段JSON對象采用BASE64編碼,將編碼后的內(nèi)容用.鏈接一起就構(gòu)成了JWT字符串扯饶。如下:
header.payload.signature
1.頭部(Header)
頭部用于描述關(guān)于該JWT的最基本的信息恒削,例如其類型以及簽名所用的算法等。這也可以被表示成一個JSON對象尾序。
{
"typ":"JWT",
"alg":"HS256"
}
在頭部指明了簽名算法是HS256算法钓丰。
2.載荷(payload)
載荷就是存放有效信息的地方。有效信息包含三個部分:
l標(biāo)準(zhǔn)中注冊的聲明
l公共的聲明
l私有的聲明
標(biāo)準(zhǔn)中注冊的聲明(建議但不強(qiáng)制使用):
liss:JWT簽發(fā)者
lsub:JWT所面向的用戶
laud:接收J(rèn)WT的一方
lexp:JWT的過期時間每币,這個過期時間必須要大于簽發(fā)時間
lnbf:定義在什么時間之前携丁,該JWT都是不可用的
liat:JWT的簽發(fā)時間
ljti:JWT的唯一身份標(biāo)識,主要用來作為一次性token,從而回避重放攻擊兰怠。
公共的聲明 :
公共的聲明可以添加任何的信息则北,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息.但不建議添加敏感信息,因?yàn)樵摬糠衷诳蛻舳丝山饷堋?/p>
私有的聲明 :
私有聲明是提供者和消費(fèi)者所共同定義的聲明痕慢,一般不建議存放敏感信息尚揣,因?yàn)閎ase64是對稱解密的,意味著該部分信息可以歸類為明文信息掖举。
示例如下:
{"iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.primeton.com",
"sub":"devops@primeton.com",
"GivenName": "dragon",
"Surname": "wang",
"admin": true
}
3.簽名(signature)
創(chuàng)建簽名需要使用Base64編碼后的header和payload以及一個秘鑰快骗。將base64加密后的header和base64加密后的payload使用.連接組成的字符串,通過header中聲明的加密方式進(jìn)行加鹽secret組合加密塔次,然后就構(gòu)成了jwt的第三部分方篮。
比如:HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), secret)
2.3.2.4JWT的優(yōu)點(diǎn)
1.跨語言,JSON的格式保證了跨語言的支撐
2.基于Token励负,無狀態(tài)
3.占用字節(jié)小藕溅,便于傳輸
2.3.2.5Token注銷
Token的注銷,由于Token不存儲在服務(wù)端继榆,由客戶端存儲巾表,當(dāng)用戶注銷時汁掠,Token的有效時間還沒有到,還是有效的集币。所以如何在用戶注銷登錄時讓Token注銷是一個要關(guān)注的點(diǎn)考阱。一般有如下幾種方式:
1.Token存儲在Cookie中,這樣客戶端注銷時鞠苟,自然可以清空掉
2.注銷時乞榨,將Token存放到分布式緩存中,每次校驗(yàn)Token時區(qū)檢查下該Token是否已注銷当娱。不過這樣也就失去了快速校驗(yàn)Token的優(yōu)點(diǎn)吃既。
3.多采用短期令牌,比如令牌有效期是20分鐘跨细,這樣可以一定程度上降低注銷后Token可用性的風(fēng)險(xiǎn)鹦倚。
2.3.3OAuth 2.0介紹
OAuth的官網(wǎng)介紹:An open protocol to allow secure
API authorization in a simple and standard method from desktop and web
applications。OAuth是一種開放的協(xié)議扼鞋,為桌面程序或者基于BS的web應(yīng)用提供了一種簡單的申鱼,標(biāo)準(zhǔn)的方式去訪問需要用戶授權(quán)的API服務(wù)。OAUTH認(rèn)證授權(quán)具有以下特點(diǎn):
1.簡單:不管是OAuth服務(wù)提供者還是應(yīng)用開發(fā)者云头,都很容易于理解與使用捐友;
2.安全:沒有涉及到用戶密鑰等信息,更安全更靈活溃槐;
3.開放:任何服務(wù)提供商都可以實(shí)現(xiàn)OAuth匣砖,任何軟件開發(fā)商都可以使用OAuth;
OAuth
2.0是OAuth協(xié)議的下一版本昏滴,但不向后兼容OAuth 1.0猴鲫,即完全廢止了OAuth 1.0。OAuth 2.0關(guān)注客戶端開發(fā)者的簡易性谣殊。要么通過組織在資源擁有者和HTTP服務(wù)商之間的被批準(zhǔn)的交互動作代表用戶拂共,要么允許第三方應(yīng)用代表用戶獲得訪問的權(quán)限。同時為Web應(yīng)用姻几,桌面應(yīng)用和手機(jī)宜狐,和起居室設(shè)備提供專門的認(rèn)證流程。2012年10月蛇捌,OAuth 2.0協(xié)議正式發(fā)布為RFC 6749抚恒。
2.3.3.1授權(quán)流程
OAuth
2.0的流程如下:
(A)用戶打開客戶端以后,客戶端要求用戶給予授權(quán)络拌。
(B)用戶同意給予客戶端授權(quán)俭驮。
(C)客戶端使用上一步獲得的授權(quán),向認(rèn)證服務(wù)器申請令牌春贸。
(D)認(rèn)證服務(wù)器對客戶端進(jìn)行認(rèn)證以后混萝,確認(rèn)無誤遗遵,同意發(fā)放令牌。
(E)客戶端使用令牌譬圣,向資源服務(wù)器申請獲取資源瓮恭。
(F)資源服務(wù)器確認(rèn)令牌無誤雄坪,同意向客戶端開放資源厘熟。
2.3.3.2四大角色
由授權(quán)流程圖中可以看到OAuth 2.0有四個角色:客戶端、資源擁有者维哈、資源服務(wù)器绳姨、授權(quán)服務(wù)器。
1.客戶端:客戶端是代表資源所有者對資源服務(wù)器發(fā)出訪問受保護(hù)資源請求的應(yīng)用程序阔挠。
2.資源擁有者:資源擁有者是對資源具有授權(quán)能力的人飘庄。
3.資源服務(wù)器:資源所在的服務(wù)器。
4.授權(quán)服務(wù)器:為客戶端應(yīng)用程序提供不同的Token购撼,可以和資源服務(wù)器在統(tǒng)一服務(wù)器上跪削,也可以獨(dú)立出去。
2.3.3.3客戶端的授權(quán)模式
客戶端必須得到用戶的授權(quán)(Authorization Grant)迂求,才能獲得令牌(access token)碾盐。OAuth 2.0定義了四種授權(quán)方式:authorizationcode、implicit揩局、resource owner password credentials毫玖、client credentials。
1.授權(quán)碼模式(authorization code)
授權(quán)碼模式(authorization code)是功能最完整凌盯、流程最嚴(yán)密的授權(quán)模式付枫。它的特點(diǎn)就是通過客戶端的后臺服務(wù)器,與"服務(wù)提供商"的認(rèn)證服務(wù)器進(jìn)行互動驰怎。流程如下:
1)用戶訪問客戶端阐滩,后者將前者導(dǎo)向認(rèn)證服務(wù)器。
2)用戶選擇是否給予客戶端授權(quán)县忌。
3)假設(shè)用戶給予授權(quán)掂榔,認(rèn)證服務(wù)器將用戶導(dǎo)向客戶端事先指定的"重定向URI"(redirection
URI),同時附上一個授權(quán)碼芹枷。
4)客戶端收到授權(quán)碼衅疙,附上早先的"重定向URI",向認(rèn)證服務(wù)器申請令牌鸳慈。這一步是在客戶端的后臺的服務(wù)器上完成的饱溢,對用戶不可見。
5)認(rèn)證服務(wù)器核對了授權(quán)碼和重定向URI走芋,確認(rèn)無誤后绩郎,向客戶端發(fā)送訪問令牌(access token)和更新令牌(refresh token)潘鲫。
2.簡化模式(implicit)
簡化模式(Implicit Grant Type)不通過第三方應(yīng)用程序的服務(wù)器,直接在瀏覽器中向認(rèn)證服務(wù)器申請令牌肋杖,跳過了"授權(quán)碼"這個步驟溉仑,因此得名。所有步驟在瀏覽器中完成状植,令牌對訪問者是可見的浊竟,且客戶端不需要認(rèn)證。流程如下:
1)客戶端將用戶導(dǎo)向認(rèn)證服務(wù)器津畸。
2)用戶決定是否給于客戶端授權(quán)振定。
3)假設(shè)用戶給予授權(quán),認(rèn)證服務(wù)器將用戶導(dǎo)向客戶端指定的"重定向URI"肉拓,并在URI的Hash部分包含了訪問令牌后频。
4)瀏覽器向資源服務(wù)器發(fā)出請求,其中不包括上一步收到的Hash值暖途。
5)資源服務(wù)器返回一個網(wǎng)頁卑惜,其中包含的代碼可以獲取Hash值中的令牌。
6)瀏覽器執(zhí)行上一步獲得的腳本驻售,提取出令牌露久。
7)瀏覽器將令牌發(fā)給客戶端。
3.密碼模式(Resource Owner Password Credentials)
密碼模式中芋浮,用戶向客戶端提供自己的用戶名和密碼抱环。客戶端使用這些信息纸巷,向"服務(wù)商提供商"索要授權(quán)镇草。在這種模式中,用戶必須把自己的密碼給客戶端瘤旨,但是客戶端不得儲存密碼梯啤。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統(tǒng)的一部分存哲,或者由一個著名公司出品因宇。而認(rèn)證服務(wù)器只有在其他授權(quán)模式無法執(zhí)行的情況下,才能考慮使用這種模式祟偷。流程如下:
1)用戶向客戶端提供用戶名和密碼察滑。
2)客戶端將用戶名和密碼發(fā)給認(rèn)證服務(wù)器,向后者請求令牌修肠。
3)認(rèn)證服務(wù)器確認(rèn)無誤后贺辰,向客戶端提供訪問令牌。
4.客戶端模式(Client Credentials)
客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以用戶的名義饲化,向"服務(wù)提供商"進(jìn)行認(rèn)證莽鸭。嚴(yán)格地說,客戶端模式并不屬于OAuth框架所要解決的問題吃靠。
在這種模式中硫眨,用戶直接向客戶端注冊,客戶端以自己的名義要求"服務(wù)提供商"提供服務(wù)巢块,其實(shí)不存在授權(quán)問題礁阁。流程如下:
1)客戶端向認(rèn)證服務(wù)器進(jìn)行身份認(rèn)證,并要求一個訪問令牌夕冲。
2)認(rèn)證服務(wù)器確認(rèn)無誤后氮兵,向客戶端提供訪問令牌裂逐。
2.3.4思考總結(jié)
正如David Borsos所建議的一種方案歹鱼,在微服務(wù)架構(gòu)下,我們更傾向于將Oauth和JWT結(jié)合使用卜高,Oauth一般用于第三方接入的場景弥姻,管理對外的權(quán)限,所以比較適合和API網(wǎng)關(guān)結(jié)合掺涛,針對于外部的訪問進(jìn)行鑒權(quán)(當(dāng)然庭敦,底層Token標(biāo)準(zhǔn)采用JWT也是可以的)。JWT更加輕巧薪缆,在微服務(wù)之間進(jìn)行訪問鑒權(quán)已然足夠秧廉,并且可以避免在流轉(zhuǎn)過程中和身份認(rèn)證服務(wù)打交道。當(dāng)然拣帽,從能力實(shí)現(xiàn)角度來說疼电,類似于分布式Session在很多場景下也是完全能滿足需求,具體怎么去選擇鑒權(quán)方案减拭,還是要結(jié)合實(shí)際的需求來蔽豺。
3.如何進(jìn)行容量設(shè)計(jì)
3
3.1需求緣起
互聯(lián)網(wǎng)公司,這樣的場景是否似曾相識:
場景一:pm要做一個很大的運(yùn)營活動拧粪,技術(shù)老大殺過來修陡,問了兩個問題:
(1)機(jī)器能抗住么?
(2)如果扛不住可霎,需要加多少臺機(jī)器魄鸦?
場景二:系統(tǒng)設(shè)計(jì)階段,技術(shù)老大殺過來癣朗,又問了兩個問題:
(1)數(shù)據(jù)庫需要分庫么拾因?
(2)如果需要分庫,需要分幾個庫?
技術(shù)上來說盾致,這些都是系統(tǒng)容量預(yù)估的問題主经,容量設(shè)計(jì)是架構(gòu)師必備的技能之一。常見的容量評估包括數(shù)據(jù)量庭惜、并發(fā)量罩驻、帶寬、CPU/MEM/DISK等护赊,今天分享的內(nèi)容惠遏,就以【并發(fā)量】為例,看看如何回答好這兩個問題骏啰。
3.2容量評估的步驟與方法
【步驟一:評估總訪問量】
如何知道總訪問量节吮?對于一個運(yùn)營活動的訪問量評估,或者一個系統(tǒng)上線后PV的評估判耕,有什么好的方法透绩?
答案是:詢問業(yè)務(wù)方,詢問運(yùn)營同學(xué)壁熄,詢問產(chǎn)品同學(xué)帚豪,看對運(yùn)營活動或者產(chǎn)品上線后的預(yù)期是什么。
舉例:58要做一個APP-push的運(yùn)營活動草丧,計(jì)劃在30分鐘內(nèi)完成5000w用戶的push推送狸臣,預(yù)計(jì)push消息點(diǎn)擊率10%,求push落地頁系統(tǒng)的總訪問量昌执?
回答:5000w*10% = 500w
【步驟二:評估平均訪問量QPS】
如何知道平均訪問量QPS烛亦?
答案是:有了總量,除以總時間即可懂拾,如果按照天評估煤禽,一天按照4w秒計(jì)算。
舉例1:push落地頁系統(tǒng)30分鐘的總訪問量是500w委粉,求平均訪問量QPS
回答:500w/(30*60) = 2778呜师,大概3000QPS
舉例2:主站首頁估計(jì)日均pv 8000w,求平均訪問QPS
回答:一天按照4w秒算贾节,8000w/4w=2000汁汗,大概2000QPS
提問:為什么一天按照4w秒計(jì)算?
回答:一天共24小時*60分鐘*60秒=8w秒栗涂,一般假設(shè)所有請求都發(fā)生在白天知牌,所以一般來說一天只按照4w秒評估
【步驟三:評估高峰QPS】
系統(tǒng)容量規(guī)劃時,不能只考慮平均QPS斤程,而是要抗住高峰的QPS角寸,如何知道高峰QPS呢菩混?
答案是:根據(jù)業(yè)務(wù)特性,通過業(yè)務(wù)訪問曲線評估
舉例:日均QPS為2000扁藕,業(yè)務(wù)訪問趨勢圖如下圖沮峡,求峰值QPS預(yù)估?
回答:從圖中可以看出亿柑,峰值QPS大概是均值QPS的2.5倍邢疙,日均QPS為2000,于是評估出峰值QPS為5000望薄。
說明:有一些業(yè)務(wù)例如“秒殺業(yè)務(wù)”比較難畫出業(yè)務(wù)訪問趨勢圖疟游,這類業(yè)務(wù)的容量評估不在此列。
【步驟四:評估系統(tǒng)痕支、單機(jī)極限QPS】
如何評估一個業(yè)務(wù)颁虐,一個服務(wù)單機(jī)能的極限QPS呢?
答案是:壓力測試
在一個服務(wù)上線前卧须,一般來說是需要進(jìn)行壓力測試的(很多創(chuàng)業(yè)型公司另绩,業(yè)務(wù)迭代很快的系統(tǒng)可能沒有這一步,那就悲劇了)故慈,以APP-push運(yùn)營活動落地頁為例(日均QPS2000板熊,峰值QPS5000),這個系統(tǒng)的架構(gòu)可能是這樣的:
1)訪問端是APP
2)運(yùn)營活動H5落地頁是一個web站點(diǎn)
3)H5落地頁由緩存cache察绷、數(shù)據(jù)庫db中的數(shù)據(jù)拼裝而成
通過壓力測試發(fā)現(xiàn),web層是瓶頸津辩,tomcat壓測單機(jī)只能抗住1200的QPS(一般來說拆撼,1%的流量到數(shù)據(jù)庫,數(shù)據(jù)庫500QPS還是能輕松抗住的喘沿,cache的話QPS能抗住闸度,需要評估cache的帶寬,假設(shè)不是瓶頸)蚜印,我們就得到了web單機(jī)極限的QPS是1200莺禁。一般來說,線上系統(tǒng)是不會跑滿到極限的窄赋,打個8折哟冬,單機(jī)線上允許跑到QPS1000。
【步驟五:根據(jù)線上冗余度回答兩個問題】
好了忆绰,上述步驟1-4已經(jīng)得到了峰值QPS是5000浩峡,單機(jī)QPS是1000,假設(shè)線上部署了2臺服務(wù)错敢,就能自信自如的回答技術(shù)老大提出的問題了:
(1)機(jī)器能抗住么翰灾?->峰值5000,單機(jī)1000,線上2臺纸淮,扛不住
(2)如果扛不住平斩,需要加多少臺機(jī)器?->需要額外3臺咽块,提前預(yù)留1臺更好双戳,給4臺更穩(wěn)
除了并發(fā)量的容量預(yù)估,數(shù)據(jù)量糜芳、帶寬飒货、CPU/MEM/DISK等評估亦可遵循類似的步驟。
3.3總結(jié)
互聯(lián)網(wǎng)架構(gòu)設(shè)計(jì)如何進(jìn)行容量評估:
【步驟一:評估總訪問量】->詢問業(yè)務(wù)峭竣、產(chǎn)品塘辅、運(yùn)營
【步驟二:評估平均訪問量QPS】->除以時間,一天算4w秒
【步驟三:評估高峰QPS】->根據(jù)業(yè)務(wù)曲線圖來
【步驟四:評估系統(tǒng)皆撩、單機(jī)極限QPS】->壓測很重要
【步驟五:根據(jù)線上冗余度回答兩個問題】->估計(jì)冗余度與線上冗余度差值