一些题目以及答案
對(duì)外提供的API如何保證冪等?
舉例說明:銀聯(lián)提供的付款接口:需要接入商戶提交付款請(qǐng)求時(shí)附帯: source來源,seq序列號(hào)source+seq在數(shù)據(jù)庫(kù)里面做準(zhǔn)一索引,防止多次付款(井發(fā))時(shí),只能處理一個(gè)請(qǐng)求
重點(diǎn):對(duì)外提供接口為了支持寫等調(diào)用,接口有兩個(gè)字段必須傳,一個(gè)是來源 source,個(gè)是來源方序列號(hào)seq,這個(gè)兩個(gè)字段在提供方系統(tǒng)里面做聯(lián)合唯一索引,這樣當(dāng)?shù)谌秸{(diào)用時(shí),先在本方系統(tǒng)里面查詢一下,是否已經(jīng)處理過,返回相應(yīng)處理結(jié)果;沒有處理過,進(jìn)行相應(yīng)處理,返回結(jié)果
注意,為了冪等友好,一定要先查詞一下,是否處理過該筆業(yè)務(wù),不查詢直接插入業(yè)務(wù)系統(tǒng),會(huì)報(bào)錯(cuò),但實(shí)際已經(jīng)處理
先做一個(gè)說明,從理論上來說,給緩存設(shè)置過期時(shí)間,是保證最終一致性的解決方案。這種方案下,我們可以對(duì)存入始存的る據(jù)置過期時(shí)間,所有的寫操作以數(shù)據(jù)庫(kù)為準(zhǔn),對(duì)媛存操作只是盡最大努力更新即可。也就是說如果數(shù)據(jù)寫成功,存更新失敗,那么只要到達(dá)過明時(shí)間,則后面的讀請(qǐng)求自然會(huì)從數(shù)據(jù)庫(kù)中讀取新值然后回填媛存因此,接下來討論的思路不依賴于給媛存設(shè)置過明時(shí)間這個(gè)方察在這里,我們討論三種更新策略:
1.先更新緩存,再更新數(shù)據(jù)庫(kù)。(不可取)
2.先更新數(shù)據(jù)庫(kù),再更新媛存。(不可取)
3.先刪除緩存,再更新數(shù)據(jù)庫(kù)。(不可取)
4.先更新數(shù)據(jù)庫(kù),再刪除緩存,(可取,有問題情解大前提:
先讀緩存,如果緩存沒有,才從數(shù)據(jù)庫(kù)讀取
(1)先更新數(shù)據(jù)庫(kù),再更新緩存
這套方案,大家是普遍反對(duì)的,為什么呢?有如下兩點(diǎn)原因。原因一(線程安全角度)
同時(shí)有請(qǐng)求A和請(qǐng)求B進(jìn)行更新操作,那么會(huì)出現(xiàn)
(1)線程A更新了數(shù)據(jù)庫(kù)
(2)線程B更新了敬據(jù)庫(kù)
(3)線程B更新了緩存
(4)線程A更新了緩存
這就出現(xiàn)請(qǐng)求A更新存應(yīng)該比請(qǐng)求B更新存早才對(duì),但是因?yàn)榫W(wǎng)絡(luò)等原因,B卻比A更早更新緩了存。這就導(dǎo)致了臟數(shù)據(jù),因此不考慮。原因二(業(yè)務(wù)場(chǎng)景角度)有如下兩點(diǎn):
tn日
寫數(shù)據(jù)庫(kù)場(chǎng)比較多
(3守?fù)?jù)庫(kù),再刪緩存
首先,先說一下。老外提出了一個(gè)緩存更新套路,名為《 Cache- Aside pattern》。其中就指出
?失效:應(yīng)用程序先從 cache取數(shù)據(jù),沒有得到,則從數(shù)據(jù)庫(kù)中取數(shù)據(jù),成功后,放到媛存中。
?命中:應(yīng)用程序從 cachet中取數(shù)據(jù),取到后返回。
?更新:先把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中,成功后,再讓緩存失效。
另外,知名社交網(wǎng)站 facebook也在論文《 Scaling Memcache at Facebook》中提出,他們用的也是先更新數(shù)據(jù)庫(kù),再媛存的策略。這種情況不存在井發(fā)問題么?
不是的。假設(shè)這會(huì)有兩個(gè)請(qǐng)求,一個(gè)請(qǐng)求A做查詢操作,一個(gè)請(qǐng)求B做更新操作,那么會(huì)有如下情形產(chǎn)生
(1)緩存剛好失效
(2)請(qǐng)求A查詢數(shù)據(jù)庫(kù),得個(gè)舊值
(3)請(qǐng)求B將新值寫入數(shù)據(jù)庫(kù)
4)請(qǐng)求B除媛存
(5)請(qǐng)求A將查到的日值寫入媛存
ok,如果發(fā)生上述情況,確實(shí)是會(huì)發(fā)生臟數(shù)據(jù)。然而,發(fā)生這種情況的概率又有多少呢?
發(fā)生上述情況有一個(gè)先天性條件,就是步驟(3)的寫數(shù)據(jù)庫(kù)操作比步驟(2)的讀數(shù)據(jù)庫(kù)操作耗時(shí)更短,才有可能使得步驟(4)先于步驟(5)。可是,大家想想,數(shù)據(jù)庫(kù)的讀操作的速度遠(yuǎn)快于寫操作的(不然做讀寫分離干嘛,做讀寫分離的意義就是因?yàn)樽x操作比較快,耗資源少),因此步驟(3)耗時(shí)比步驟(2)更短,這一情形很難出現(xiàn)
假設(shè),有人非要抬杠,有強(qiáng)迫癥,一定要解決怎么辦?如何解決上述井發(fā)問題?
首先,給存設(shè)有效時(shí)間是一種方案。其次,采用策略(2)里給出的異步延時(shí)除策略,保證讀請(qǐng)求完成以后,再進(jìn)行刪除操作。
認(rèn)證和授權(quán)的區(qū)別Authentication(認(rèn)證)是驗(yàn)證您的身份的憑據(jù)(例如用戶名和密碼),通過這個(gè)憑據(jù),系統(tǒng)得以知道你就是你,也就是說系統(tǒng)存在你這個(gè)用戶。所以, Authentication被稱為身份/用戶驗(yàn)證
Authorization(授權(quán))發(fā)生在 Authentication(認(rèn)證)之后。授權(quán),它主要掌管我們?cè)L問系統(tǒng)的權(quán)限。比如有些特定資源只能具有特定權(quán)限的人才能訪問比如 admin,有些對(duì)系統(tǒng)資源操作比如期除、添加、更新只能特定人才具
這兩個(gè)般在我們的系統(tǒng)中被結(jié)合在一起使用,目的就是為了保護(hù)我們系統(tǒng)的安全性
什么是 Token?什么是JMT?如何基于 Token進(jìn)行身份驗(yàn)證?
我們知道 Session信息需要保存一份在服務(wù)器端。這種方式會(huì)帶來一些麻煩,比如需要我們保證保存 Session信思服務(wù)器的可用性、不適合移動(dòng)端(不依賴 Cookie)等
有沒有一種不需要自己存放 Session信息就能實(shí)現(xiàn)身份驗(yàn)證的方式呢?使用 Token即可!WT( SON Web
Token)就是這種方式的實(shí)現(xiàn),通過這種方式服務(wù)器端就不需要保存 Session數(shù)據(jù)了,只用在客戶端保存服務(wù)端返回給客戶的 Token就可以了,擴(kuò)履性得到提升
MT本質(zhì)上就一段簽名的SON格式的數(shù)據(jù)。由于它是帯有簽名的,因此接收者便可以驗(yàn)證它的真實(shí)性
下面是RFC7519對(duì)MT做的較為正式的定義。
JSON Web Token (WT) is a compact, Url-safe means of representing claims to be transferred between twoparties. The claims in a WT are encoded as a JSON object that is used as the payload of a )SON Web
Signature UWS)structure or as the plaintext of a JSON Web Encryption(WE)structure, enabling the claimsto be digitally signed or integrity protected with a Message Authentication Code(MAC)and/or encrypted.
–JSON Web Token (WT)
MT由3部分構(gòu)成
Header描述MT的元數(shù)據(jù)。定義了生成簽名的算法以及 Token的類型。
Payload(負(fù)載):用來存放實(shí)際需要傳進(jìn)的數(shù)據(jù)
Signature(簽名):服務(wù)器通過 Payload、 Header和一個(gè)密鑰 secret)使用 Header里面指定的簽名算法(認(rèn)是
HMAC SHA256)生成
在基于 Token進(jìn)行身份驗(yàn)證的的應(yīng)用程序中,服務(wù)器通過 Payload、 Headers和一個(gè)密鑰 secret)的建令牌( Token)并將 Token發(fā)送給客戶端,客戶端將 Token保存在 Cookie或者 totalstorage里面,以后客戶端發(fā)出
為什么 Cookie無法防止CSRF攻擊,而 token可以
CSRF( Cross Site Request Forgery)-般被甜譯為站請(qǐng)求偽造。那么什么是站請(qǐng)求偽造呢?說簡(jiǎn)單一點(diǎn)用你的身份去發(fā)送一些對(duì)你不友好的請(qǐng)求,舉個(gè)簡(jiǎn)單例子:
小壯登錄了某網(wǎng)上銀行,他來到了網(wǎng)上銀行的帖子區(qū),看到一個(gè)帖子下面有一個(gè)鏈接寫著科學(xué)理財(cái),年收益率70%°,小杜好奇的點(diǎn)開了這個(gè)鏈接,結(jié)果發(fā)現(xiàn)自己的賬戶少了10000元,這是這么回事呢?原來黑客在鏈接中藏了一個(gè)請(qǐng)求,這個(gè)請(qǐng)求直接利用小社的身份給銀行發(fā)送了一個(gè)轉(zhuǎn)賬請(qǐng)求也就是通過你的 Cookie向銀行發(fā)出請(qǐng)求<asrc=htpi/www.mybank.com/Transfer?banked=11&money.=10000科學(xué)理財(cái),年收益率70%<,原因是進(jìn)行 Session認(rèn)證的時(shí)候,我們一般使用 Cookie來存儲(chǔ) Session,當(dāng)我們登陸后后端生成個(gè) Session放在
Cookie中返回給客戶端,服務(wù)端通過 Redis或者其他存儲(chǔ)工具記錄保存著這個(gè)5 ession,客戶端登錄以后每次請(qǐng)求都會(huì)帶上這個(gè) Session,服務(wù)端通過這個(gè) Session來標(biāo)示你這個(gè)人。如果別人通過 cookie拿到了 Session后就可以代皆你的身份訪問系統(tǒng)了
Session認(rèn)證中 Cookie中的 Session是由覽器發(fā)送到服務(wù)端的,借助這個(gè)特性,攻擊者就可以通過讓用戶誤點(diǎn)攻擊鏈接,達(dá)到攻擊效果
但是,我們使用 token的話就不會(huì)存在這個(gè)問題,在我們登錄成功獲得 token之后,一般會(huì)選擇存放在locastorage中。然后我們?cè)谇岸送ㄟ^某些方式會(huì)始每個(gè)發(fā)到后端的請(qǐng)求加上這個(gè) token.這樣就不會(huì)出現(xiàn)CSRF同的問題。因?yàn)?即使有個(gè)你點(diǎn)擊了非法鏈接發(fā)送了請(qǐng)求到服務(wù)端,這個(gè)非法請(qǐng)求是不會(huì)攜帯 token的,所以這個(gè)請(qǐng)求將是非法的。
分布式架構(gòu)下, Session共享有什么方案?
1.不要有 session:但是確實(shí)在某些場(chǎng)景下,是可以沒有 session的,其實(shí)在很多接口類系統(tǒng)當(dāng)中,都提倡【API無狀態(tài)服務(wù)】:也就是每一次的接口訪問,都不依于 session、不依賴于前一次的接口訪問,用W的
2.存入 cookies中:將 session存儲(chǔ)到 cookie中,但是缺點(diǎn)也很明顯,例如每次請(qǐng)求都得帶著 session,數(shù)據(jù)存儲(chǔ)在toker
客戶端本地,是有風(fēng)險(xiǎn)的
3. session同步:對(duì)個(gè)服務(wù)器之間同步 session,這樣可以保證每個(gè)服務(wù)器上都有全部的 session信息,不過當(dāng)服
務(wù)器數(shù)量比較多的時(shí)候,同步是會(huì)有延退甚至同步失敗
4.我們現(xiàn)在的系統(tǒng)會(huì)把 session放到 Redis.中存儲(chǔ),雖然架構(gòu)上変得復(fù)雜,并且需要多訪問一次 Redis,但是這種方案來的好處也是很大的:實(shí)現(xiàn) session共享,可以水平擴(kuò)展(増加加 Redis服務(wù)器),服務(wù)器重啟 session不丟失(不過也要注意 session在 Redist中的刷新/失效機(jī)制),不僅可以跨服務(wù)器 sessi0n共享,甚至可以跨平臺(tái)
(例如口網(wǎng)頁端和AP端滿)進(jìn)行共享
5.使用 Nginx(或其他復(fù)雜均衡軟硬件)中的p綁定策略,同個(gè)p只能在指定的同一個(gè)機(jī)器訪問,但是這樣做風(fēng)險(xiǎn)也比較大,而且也是去了負(fù)載均的意
springcloudi核心組件有哪些,分別有什么作用
服務(wù)注冊(cè)與發(fā)現(xiàn)ー- Netflix Eureka、 Nacos、 Zookeeper客戶端負(fù)載均衡一一 Netflix Ribbon、 Springcloud Loadbalancer
服務(wù)熔斷
Netflix Hystrix、 Alibaba Sentinel、 Resilience.4服務(wù)網(wǎng)關(guān)ー- Netflix Zuu、 Springcloud Gateway服務(wù)接口調(diào)用一- Netflix Feign、 Resttemplate、 Openfeint鏈路追琮ー- Netflix Sleuth、 Skywalking、 Pinpoint聚合 Hystrix監(jiān)控?cái)?shù)據(jù)一- Netflix Turbine監(jiān)控中心- Springboot Admin
配置中心ー- Spring Cloud Config、 Apollo, nacos
注冊(cè)中心的原理是什么
服務(wù)啟動(dòng)后向 Eureka注冊(cè), Eureka Server會(huì)將注冊(cè)信息向其他 Eureka Server進(jìn)行同步,當(dāng)服務(wù)費(fèi)者要調(diào)用服務(wù)提供者,則向務(wù)注冊(cè)中心獲取服務(wù)提供者地址,然后會(huì)將服務(wù)提供者地址存在本地,下次再調(diào)用時(shí),則直接
從本地存中獲取服務(wù)列表來亮成服務(wù)調(diào)用
總結(jié)
- 上一篇: 【学习笔记】mybatis自定义插件案例
- 下一篇: nacos+openfeign服务提供和