螞蟻金服一面:十道經(jīng)典面試題解析

源 / 文/ 撿田螺的小男孩
前言
最近編程討論群有位小伙伴去螞蟻金服面試了,以下是面試的真題,跟大家一起來討論怎么回答。

點(diǎn)擊上方“撿田螺的小男孩”,選擇“設(shè)為星標(biāo)”,干貨不斷滿滿
1. 用到分布式事務(wù)嘛?為什么用這種方案,有其他方案嘛?
什么是分布式事務(wù)
談到事務(wù),我們就會(huì)想到數(shù)據(jù)庫事務(wù),很容易就想到原子性、一致性、持久性、隔離性。

分布式事務(wù)跟數(shù)據(jù)庫事務(wù)有點(diǎn)不一樣,它是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上。簡(jiǎn)單來說,分布式事務(wù)指的就是分布式系統(tǒng)中的事務(wù),它的存在就是為了保證不同數(shù)據(jù)庫節(jié)點(diǎn)的數(shù)據(jù)一致性。
分布式事務(wù)基礎(chǔ)
分布式事務(wù)需要需要知道CAP理論和BASE理論。
CAP理論
一致性(C:Consistency):一致性是指數(shù)據(jù)在多個(gè)副本之間能否保持一致的特性。例如一個(gè)數(shù)據(jù)在某個(gè)分區(qū)節(jié)點(diǎn)更新之后,在其他分區(qū)節(jié)點(diǎn)讀出來的數(shù)據(jù)也是更新之后的數(shù)據(jù)。
可用性(A:Availability):可用性是指系統(tǒng)提供的服務(wù)必須一直處于可用的狀態(tài),對(duì)于用戶的每一個(gè)操作請(qǐng)求總是能夠在有限的時(shí)間內(nèi)返回結(jié)果。這里的重點(diǎn)是"有限時(shí)間內(nèi)"和"返回結(jié)果"。
分區(qū)容錯(cuò)性(P:Partition tolerance):分布式系統(tǒng)在遇到任何網(wǎng)絡(luò)分區(qū)故障的時(shí)候,仍然需要能夠保證對(duì)外提供滿足一致性和可用性的服務(wù)。
一個(gè)分布式系統(tǒng)中,CAP理論它只能同時(shí)滿足(一致性、可用性、分區(qū)容錯(cuò)性)中的兩點(diǎn)。
BASE 理論
BASE 理論, 是對(duì)CAP中AP的一個(gè)擴(kuò)展,對(duì)于我們的業(yè)務(wù)系統(tǒng),我們考慮犧牲一致性來換取系統(tǒng)的可用性和分區(qū)容錯(cuò)性。BASE是Basically Available(基本可用),Soft state(軟狀態(tài)),和 Eventually consistent(最終一致性)三個(gè)短語的縮寫。
基本可用是指,通過支持局部故障而不是系統(tǒng)全局故障來實(shí)現(xiàn)的;
Soft State表示狀態(tài)可以有一段時(shí)間不同步;
最終一致,最終數(shù)據(jù)是一致的就可以了,而不是實(shí)時(shí)保持強(qiáng)一致。
分布式事務(wù)的幾種解決方案
2PC(二階段提交)方案,事務(wù)的提交分為兩個(gè)階段:準(zhǔn)備階段和提交執(zhí)行方案。
TCC(即Try、Confirm、Cancel),它采用了補(bǔ)償機(jī)制,核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作。
本地消息表,它的核心思想就是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理。
最大努力通知,實(shí)現(xiàn)最大努力通知,可以采用MQ的ack機(jī)制。
Saga事務(wù),它的核心思想是將長(zhǎng)事務(wù)拆分為多個(gè)本地短事務(wù),由Saga事務(wù)協(xié)調(diào)器協(xié)調(diào),如果正常結(jié)束那就正常完成,如果某個(gè)步驟失敗,則根據(jù)相反順序一次調(diào)用補(bǔ)償操作。
業(yè)界目前使用本地消息表這種方案是比較多的,它的核心思想就是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理??梢钥匆幌禄镜膶?shí)現(xiàn)流程圖吧:

對(duì)于消息發(fā)送方:
首先需要有一個(gè)消息表,記錄著消息狀態(tài)相關(guān)信息。
業(yè)務(wù)數(shù)據(jù)和消息表在同一個(gè)數(shù)據(jù)庫,即要保證它倆在同一個(gè)本地事務(wù)。
在本地事務(wù)中處理完業(yè)務(wù)數(shù)據(jù)和寫消息表操作后,通過寫消息到MQ消息隊(duì)列。
消息會(huì)發(fā)到消息消費(fèi)方,如果發(fā)送失敗,即進(jìn)行重試。
消息消費(fèi)方:
處理消息隊(duì)列中的消息,完成自己的業(yè)務(wù)邏輯。
此時(shí)如果本地事務(wù)處理成功,則表明已經(jīng)處理成功了。
如果本地事務(wù)處理失敗,那么就會(huì)重試執(zhí)行。
如果是業(yè)務(wù)上面的失敗,給消息生產(chǎn)方發(fā)送一個(gè)業(yè)務(wù)補(bǔ)償消息,通知進(jìn)行回滾等操作。
生產(chǎn)方和消費(fèi)方定時(shí)掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發(fā)送一遍。如果有靠譜的自動(dòng)對(duì)賬補(bǔ)賬邏輯,這種方案還是非常實(shí)用的。
2.JDK6、7、8分別提供了哪些新特性
JDK 6 新特性

Desktop類(它允許一個(gè)Java應(yīng)用程序啟動(dòng)本地的另一個(gè)應(yīng)用程序去處理URI或文件請(qǐng)求)
使用JAXB2來實(shí)現(xiàn)對(duì)象與XML之間的映射
輕量級(jí) Http Server API
插入式注解處理API(lombok框架基于這個(gè)特性實(shí)現(xiàn))
STAX(是JDK6中一種處理XML文檔的API)
JDK 7的新特性

switch 支持String字符串類型
try-with-resources,資源自動(dòng)關(guān)閉
整數(shù)類型如(byte,short,int,long)能夠用二進(jìn)制來表示
數(shù)字常量支持下劃線
泛型實(shí)例化類型自動(dòng)推斷,即”<>”
一個(gè)catch中捕獲多個(gè)異常類型,用(|)分隔開
增強(qiáng)的文件系統(tǒng)
Fork/join 框架
JDK8 的新特性

lambada表達(dá)式
函數(shù)式接口
方法引用
默認(rèn)方法
Stream API
Optional
Date Time API(如LocalDate)
重復(fù)注解
Base64
JVM的新特性(如元空間Metaspace代替持久代)
3. https原理,工作流程
HTTPS = HTTP + SSL/TLS,即用SSL/TLS對(duì)數(shù)據(jù)進(jìn)行加密和解密,Http進(jìn)行傳輸。
SSL,即Secure Sockets Layer(安全套接層協(xié)議),是網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。
TLS,即Transport Layer Security(安全傳輸層協(xié)議),它是SSL3.0的后續(xù)版本。

客戶端發(fā)起Https請(qǐng)求,連接到服務(wù)器的443端口。
服務(wù)器必須要有一套數(shù)字證書(證書內(nèi)容有公鑰、證書頒發(fā)機(jī)構(gòu)、失效日期等)。
服務(wù)器將自己的數(shù)字證書發(fā)送給客戶端(公鑰在證書里面,私鑰由服務(wù)器持有)。
客戶端收到數(shù)字證書之后,會(huì)驗(yàn)證證書的合法性。如果證書驗(yàn)證通過,就會(huì)生成一個(gè)隨機(jī)的對(duì)稱密鑰,用證書的公鑰加密。
客戶端將公鑰加密后的密鑰發(fā)送到服務(wù)器。
服務(wù)器接收到客戶端發(fā)來的密文密鑰之后,用自己之前保留的私鑰對(duì)其進(jìn)行非對(duì)稱解密,解密之后就得到客戶端的密鑰,然后用客戶端密鑰對(duì)返回?cái)?shù)據(jù)進(jìn)行對(duì)稱加密,醬紫傳輸?shù)臄?shù)據(jù)都是密文啦。
服務(wù)器將加密后的密文返回到客戶端。
客戶端收到后,用自己的密鑰對(duì)其進(jìn)行對(duì)稱解密,得到服務(wù)器返回的數(shù)據(jù)。
4. 講講java jmm volatile的實(shí)現(xiàn)原理
volatile關(guān)鍵字是Java虛擬機(jī)提供的的最輕量級(jí)的同步機(jī)制,它作為一個(gè)修飾符,用來修飾變量。它保證變量對(duì)所有線程可見性,禁止指令重排,但是不保證原子性。
volatile是如何保證可見性的呢?我們先來看下java內(nèi)存模型(jmm)
Java虛擬機(jī)規(guī)范試圖定義一種Java內(nèi)存模型,來屏蔽掉各種硬件和操作系統(tǒng)的內(nèi)存訪問差異,以實(shí)現(xiàn)讓Java程序在各種平臺(tái)上都能達(dá)到一致的內(nèi)存訪問效果。
為了更好的執(zhí)行性能,java內(nèi)存模型并沒有限制執(zhí)行引擎使用處理器的特定寄存器或緩存來和主內(nèi)存打交道,也沒有限制編譯器進(jìn)行調(diào)整代碼順序優(yōu)化。所以Java內(nèi)存模型會(huì)存在緩存一致性問題和指令重排序問題的。
Java內(nèi)存模型規(guī)定所有的變量都是存在主內(nèi)存當(dāng)中,每個(gè)線程都有自己的工作內(nèi)存。這里的變量包括實(shí)例變量和靜態(tài)變量,但是不包括局部變量,因?yàn)榫植孔兞渴蔷€程私有的。
線程的工作內(nèi)存保存了被該線程使用的變量的主內(nèi)存副本,線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行,而不能直接操作操作主內(nèi)存。并且每個(gè)線程不能訪問其他線程的工作內(nèi)存。

volatile變量,保證新值能立即同步回主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新,所以我們說volatile保證了多線程操作變量的可見性。
指令重排是指在程序執(zhí)行過程中,為了提高性能, 編譯器和CPU可能會(huì)對(duì)指令進(jìn)行重新排序。volatile是如何禁止指令重排的?在Java語言中,有一個(gè)先行發(fā)生原則(happens-before)
程序次序規(guī)則:在一個(gè)線程內(nèi),按照控制流順序,書寫在前面的操作先行發(fā)生于書寫在后面的操作。
管程鎖定規(guī)則:一個(gè)unLock操作先行發(fā)生于后面對(duì)同一個(gè)鎖額lock操作
volatile變量規(guī)則:對(duì)一個(gè)變量的寫操作先行發(fā)生于后面對(duì)這個(gè)變量的讀操作
線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法先行發(fā)生于此線程的每個(gè)一個(gè)動(dòng)作
線程終止規(guī)則:線程中所有的操作都先行發(fā)生于線程的終止檢測(cè),我們可以通過Thread.join()方法結(jié)束、Thread.isAlive()的返回值手段檢測(cè)到線程已經(jīng)終止執(zhí)行
線程中斷規(guī)則:對(duì)線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生
對(duì)象終結(jié)規(guī)則:一個(gè)對(duì)象的初始化完成先行發(fā)生于他的finalize()方法的開始
傳遞性:如果操作A先行發(fā)生于操作B,而操作B又先行發(fā)生于操作C,則可以得出操作A先行發(fā)生于操作C
實(shí)際上volatile保證可見性和禁止指令重排都跟內(nèi)存屏障有關(guān)。我們來看一段volatile使用的demo代碼
public class Singleton {
private volatile static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
編譯后,對(duì)比有volatile關(guān)鍵字和沒有volatile關(guān)鍵字時(shí)所生成的匯編代碼,發(fā)現(xiàn)有volatile關(guān)鍵字修飾時(shí),會(huì)多出一個(gè)lock addl $0x0,(%esp),即多出一個(gè)lock前綴指令,lock指令相當(dāng)于一個(gè)「內(nèi)存屏障」
lock指令相當(dāng)于一個(gè)內(nèi)存屏障,它保證以下這幾點(diǎn):
1.重排序時(shí)不能把后面的指令重排序到內(nèi)存屏障之前的位置
2.將本處理器的緩存寫入內(nèi)存
3.如果是寫入動(dòng)作,會(huì)導(dǎo)致其他處理器中對(duì)應(yīng)的緩存無效。
第2點(diǎn)和第3點(diǎn)就是保證volatile保證可見性的體現(xiàn)嘛,第1點(diǎn)就是禁止指令重排列的體現(xiàn)。內(nèi)存屏障又是什么呢?
內(nèi)存屏障四大分類:(Load 代表讀取指令,Store代表寫入指令)
內(nèi)存屏障類型
抽象場(chǎng)景
描述
LoadLoad屏障 | Load1; LoadLoad; Load2 | 在Load2要讀取的數(shù)據(jù)被訪問前,保證Load1要讀取的數(shù)據(jù)被讀取完畢。 |
StoreStore屏障 | Store1; StoreStore; Store2 | 在Store2寫入執(zhí)行前,保證Store1的寫入操作對(duì)其它處理器可見 |
LoadStore屏障 | Load1; LoadStore; Store2 | 在Store2被寫入前,保證Load1要讀取的數(shù)據(jù)被讀取完畢。 |
StoreLoad屏障 | Store1; StoreLoad; Load2 | 在Load2讀取操作執(zhí)行前,保證Store1的寫入對(duì)所有處理器可見。 |
為了實(shí)現(xiàn)volatile的內(nèi)存語義,Java內(nèi)存模型采取以下的保守策略
在每個(gè)volatile寫操作的前面插入一個(gè)StoreStore屏障。
在每個(gè)volatile寫操作的后面插入一個(gè)StoreLoad屏障。
在每個(gè)volatile讀操作的后面插入一個(gè)LoadLoad屏障。
在每個(gè)volatile讀操作的后面插入一個(gè)LoadStore屏障。
有些小伙伴,可能對(duì)這個(gè)還是有點(diǎn)疑惑,內(nèi)存屏障這玩意太抽象了。我們照著代碼看下吧:

內(nèi)存屏障保證前面的指令先執(zhí)行,所以這就保證了禁止了指令重排啦,同時(shí)內(nèi)存屏障保證緩存寫入內(nèi)存和其他處理器緩存失效,這也就保證了可見性,哈哈~
5. 講一講7層網(wǎng)絡(luò)模型,tcp的為什么要三次握手
計(jì)算機(jī)網(wǎng)路體系結(jié)構(gòu)有三層:OSI七層模型、TCP/IP四層模型、五層體系結(jié)構(gòu),如圖:

七層模型,亦稱OSI(Open System Interconnection),國(guó)際標(biāo)準(zhǔn)化組織(International Organization for Standardization)制定的一個(gè)用于計(jì)算機(jī)或通信系統(tǒng)間互聯(lián)的標(biāo)準(zhǔn)體系。
應(yīng)用層:網(wǎng)絡(luò)服務(wù)與最終用戶的一個(gè)接口,常見的協(xié)議有:HTTP FTP SMTP SNMP DNS.
表示層:數(shù)據(jù)的表示、安全、壓縮。,確保一個(gè)系統(tǒng)的應(yīng)用層所發(fā)送的信息可以被另一個(gè)系統(tǒng)的應(yīng)用層讀取。
會(huì)話層:建立、管理、終止會(huì)話,對(duì)應(yīng)主機(jī)進(jìn)程,指本地主機(jī)與遠(yuǎn)程主機(jī)正在進(jìn)行的會(huì)話.
傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號(hào),以及流控和差錯(cuò)校驗(yàn),協(xié)議有TCP UDP.
網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇,協(xié)議有ICMP IGMP IP等.
數(shù)據(jù)鏈路層:在物理層提供比特流服務(wù)的基礎(chǔ)上,建立相鄰結(jié)點(diǎn)之間的數(shù)據(jù)鏈路。
物理層:建立、維護(hù)、斷開物理連接。
6.說說線程池的工作原理
面試官如果要我們講下線程池工作原理的話,大家講下以下這個(gè)流程圖就可以啦:

為了形象描述線程池執(zhí)行,加深大家的理解,我打個(gè)比喻:
核心線程比作公司正式員工
非核心線程比作外包員工
阻塞隊(duì)列比作需求池
提交任務(wù)比作提需求

當(dāng)產(chǎn)品提個(gè)需求,正式員工(核心線程)先接需求(執(zhí)行任務(wù))
如果正式員工都有需求在做,即核心線程數(shù)已滿),產(chǎn)品就把需求先放需求池(阻塞隊(duì)列)。
如果需求池(阻塞隊(duì)列)也滿了,但是這時(shí)候產(chǎn)品繼續(xù)提需求,怎么辦呢?那就請(qǐng)外包(非核心線程)來做。
如果所有員工(最大線程數(shù)也滿了)都有需求在做了,那就執(zhí)行拒絕策略。
如果外包員工把需求做完了,它經(jīng)過一段(keepAliveTime)空閑時(shí)間,就離開公司了。
7.你們數(shù)據(jù)庫的高可用是怎么實(shí)現(xiàn)的?
高可用,即High Availability,是分布式系統(tǒng)架構(gòu)設(shè)計(jì)中必須考慮的因素之一,它通常是指,通過設(shè)計(jì)減少系統(tǒng)不能提供服務(wù)的時(shí)間。單機(jī)部署談不上高可用,因?yàn)?strong style="color: rgb(14, 136, 235);">單點(diǎn)故障問題。高可用都是多個(gè)節(jié)點(diǎn)的,我們?cè)诳紤]MySQL數(shù)據(jù)庫的高可用的架構(gòu)時(shí),需要考慮這幾個(gè)方面:
如果數(shù)據(jù)庫節(jié)點(diǎn)宕機(jī),需要盡快回復(fù),保證業(yè)務(wù)不受宕機(jī)影響。
從數(shù)據(jù)庫節(jié)點(diǎn)的數(shù)據(jù),盡可能跟主節(jié)點(diǎn)數(shù)據(jù)實(shí)時(shí)保持一致,至少保證最終一致性。
數(shù)據(jù)庫節(jié)點(diǎn)切換時(shí),數(shù)據(jù)不能缺失。
7.1 主從或主主半同步復(fù)制
用雙節(jié)點(diǎn)數(shù)據(jù)庫,搭建單向或者雙向的半同步復(fù)制。架構(gòu)如下:

通常會(huì)和proxy、keepalived等第三方軟件同時(shí)使用,即可以用來監(jiān)控?cái)?shù)據(jù)庫的健康,又可以執(zhí)行一系列管理命令。如果主庫發(fā)生故障,切換到備庫后仍然可以繼續(xù)使用數(shù)據(jù)庫。
這種方案優(yōu)點(diǎn)是架構(gòu)、部署比較簡(jiǎn)單,主機(jī)宕機(jī)直接切換即可。缺點(diǎn)是完全依賴于半同步復(fù)制,半同步復(fù)制退化為異步復(fù)制,無法保證數(shù)據(jù)一致性;另外,還需要額外考慮haproxy、keepalived的高可用機(jī)制。
7.2 半同步復(fù)制優(yōu)化
半同步復(fù)制機(jī)制是可靠的,可以保證數(shù)據(jù)一致性的。但是如果網(wǎng)絡(luò)發(fā)生波動(dòng),半同步復(fù)制發(fā)生超時(shí)會(huì)切換為異步復(fù)制,異復(fù)制是無法保證數(shù)據(jù)的一致性的。因此,可以在半同復(fù)制的基礎(chǔ)上優(yōu)化一下,盡可能保證半同復(fù)制。如雙通道復(fù)制方案

優(yōu)點(diǎn):這種方案架構(gòu)、部署也比較簡(jiǎn)單,主機(jī)宕機(jī)也是直接切換即可。比方案1的半同步復(fù)制,更能保證數(shù)據(jù)的一致性。
缺點(diǎn):需要修改內(nèi)核源碼或者使用mysql通信協(xié)議,沒有從根本上解決數(shù)據(jù)一致性問題。
7.3 高可用架構(gòu)優(yōu)化
保證高可用,可以把主從雙節(jié)點(diǎn)數(shù)據(jù)庫擴(kuò)展為數(shù)據(jù)庫集群。Zookeeper可以作為集群管理,它使用分布式算法保證集群數(shù)據(jù)的一致性,可以較好的避免網(wǎng)絡(luò)分區(qū)現(xiàn)象的產(chǎn)生。

優(yōu)點(diǎn):保證了整個(gè)系統(tǒng)的高可用性,擴(kuò)展性也較好,可以擴(kuò)展為大規(guī)模集群。
缺點(diǎn):數(shù)據(jù)一致性仍然依賴于原生的mysql半同步復(fù)制;引入Zookeeper使系統(tǒng)邏輯更復(fù)雜。
7.4 共享存儲(chǔ)
★

優(yōu)點(diǎn):部署簡(jiǎn)單,價(jià)格合適,保證數(shù)據(jù)的強(qiáng)一致性 缺點(diǎn):對(duì)IO性能影響較大,從庫不提供讀操作
7.5 分布式協(xié)議

優(yōu)點(diǎn):不依賴于第三方軟件,可以實(shí)現(xiàn)數(shù)據(jù)的強(qiáng)一致性; 缺點(diǎn):配置較復(fù)雜;需要使用NDB儲(chǔ)存引擎;至少三節(jié)點(diǎn);
8. 讀寫分離的場(chǎng)景下,怎么保證從數(shù)據(jù)庫讀到最新的數(shù)據(jù)?

寫請(qǐng)求是直接寫主庫,然后同步數(shù)據(jù)到從庫 讀請(qǐng)求一般直接讀從庫,除飛強(qiáng)制讀主庫

A發(fā)起寫請(qǐng)求,更新主庫數(shù)據(jù),并在緩存中設(shè)置一個(gè)標(biāo)記,表示數(shù)據(jù)已更新,標(biāo)記格式為:userId+業(yè)務(wù)Id。 設(shè)置此標(biāo)記,設(shè)置過期時(shí)間(估值為主庫和從庫同步延遲的時(shí)間) B發(fā)起讀請(qǐng)求,先判斷此請(qǐng)求,在緩存中有沒有更新標(biāo)記。 如果存在標(biāo)記,走主庫;如果沒有,請(qǐng)求走從庫。
9. 如何保證MySQL數(shù)據(jù)不丟?
binlog日志
statement:每一條會(huì)修改數(shù)據(jù)的sql都會(huì)記錄到binlog中,不建議使用。 row:基于行的變更情況記錄,會(huì)記錄行更改前后的內(nèi)容,推薦使用。 mixed:混合statement和row兩個(gè)模式,不建議使用。

write:指把日志寫到文件系統(tǒng)的page cache,并沒有把數(shù)據(jù)持久化到磁盤,因此速度較快。 fsync,實(shí)際的寫盤操作,即把數(shù)據(jù)持久化到磁盤。

redo log日志

物理上是在MySQL進(jìn)程內(nèi)存中,存在redo log buffer中, 物理上在文件系統(tǒng)的page cache里,寫到磁盤 (write),但是還沒有持久化(fsync)。 存在hard disk,已經(jīng)持久化到磁盤。
設(shè)置為0時(shí),表示每次事務(wù)提交時(shí)都只是把redo log留在redo log buffer 中 ; 設(shè)置為1時(shí),表示每次事務(wù)提交時(shí)都將 redo log 直接持久化到磁盤; 設(shè)置為2時(shí),表示每次事務(wù)提交時(shí)都只是把redo log 寫到page cache。
10. 高并發(fā)下如何設(shè)計(jì)秒殺系統(tǒng)?

頁面靜態(tài)化 按鈕至灰控制 服務(wù)單一職責(zé) 秒殺鏈接加鹽 限流 分布式鎖 MQ異步處理 限流&降級(jí)&熔斷
為了防止某個(gè)用戶請(qǐng)求過于頻繁,我們可以對(duì)同一用戶限流; 為了防止黃牛模擬幾個(gè)用戶請(qǐng)求,我們可以對(duì)某個(gè)IP進(jìn)行限流; 為了防止有人使用代理,每次請(qǐng)求都更換IP請(qǐng)求,我們可以對(duì)接口進(jìn)行限流。 為了防止瞬時(shí)過大的流量壓垮系統(tǒng),還可以使用阿里的Sentinel、Hystrix組件進(jìn)行限流。
if(jedis.set(key_resource_id, uni_request_id, "NX", "EX", 100s) == 1){ //加鎖
try {
do something //業(yè)務(wù)處理
}catch(){
}
finally {
//判斷是不是當(dāng)前線程加的鎖,是才釋放
if (uni_request_id.equals(jedis.get(key_resource_id))) {
jedis.del(lockKey); //釋放鎖
}
}
}

if redis.call('get',KEYS[1]) == ARGV[1] then
return redis.call('del',KEYS[1])
else
return 0
end;
限流,就是限制請(qǐng)求,防止過大的請(qǐng)求壓垮服務(wù)器; 降級(jí),就是秒殺服務(wù)有問題了,就降級(jí)處理,不要影響別的服務(wù); 熔斷,服務(wù)有問題就熔斷,一般熔斷降級(jí)是一起出現(xiàn)。
參考資料
五大常見的MySQL高可用方案: https://zhuanlan.zhihu.com/p/25960208
[2]讀寫分離數(shù)據(jù)庫如何保持?jǐn)?shù)據(jù)一致性: https://blog.csdn.net/baidu_36161424/article/details/107712388
[3]《我們一起進(jìn)大廠》系列-秒殺系統(tǒng)設(shè)計(jì): https://juejin.cn/post/6844903999083151374#heading-11
[4]《極客時(shí)間:MySQL45講實(shí)戰(zhàn)》: http://gk.link/a/10vPr
[5]MySQL是如何保證不丟數(shù)據(jù)的(一): https://cloud.tencent.com/developer/article/1674625
好文推薦


字節(jié)跳動(dòng)小組長(zhǎng)無意中得知整個(gè)部門的薪資!自己只有28K!手下人卻拿35K!怎么辦?

某程序員求助:盒馬優(yōu)選面試通過,卻被告知在阿里黑名單里,無法入職!自己只用過花唄借唄,都按時(shí)還款,為什么會(huì)進(jìn)入黑名單?

知乎高贊:一個(gè)程序員的水平能差到什么程度?
END


頂級(jí)程序員:topcoding
做最好的程序員社區(qū):Java后端開發(fā)、Python、大數(shù)據(jù)、AI
一鍵三連「分享」、「點(diǎn)贊」和「在看」
