面试题汇总-分布式(一)
目錄
分布式
1、分布式的與缺點
2、談談業務中使用分布式的場景
3、Session 分布式方案
4、分布式鎖的場景及分布是鎖的實現方案
5、分布式事務
6、集群與負載均衡的算法與實現
7、說說分庫與分表設計、分庫與分表帶來的分布式困境與應對之策
?
微服務
1、前后端分離是如何做的
2、如何解決跨域(CSRF)
3、微服務哪些框架
4、你怎么理解 RPC 框架
5、說說 RPC 的實現原理
6、說說 Dubbo 的實現原理
7、你怎么理解 RESTful(Resource?REpresentational State Transfer)
8、說說如何設計一個良好的 API(Application Programming Interface,應用程序編程接口)
9、如何理解 RESTful API 的冪等性
10、如何保證接口的冪等性
11、說說 CAP 定理、 BASE 理論(見分布式)
12、怎么考慮數據一致性問題(分布式事務)
13、說說最終一致性的實現方案
14、你怎么看待微服務
15、微服務與 SOA 的區別
16、如何拆分服務
17、微服務如何進行數據庫管理
18、如何應對微服務的鏈式調用異常
19、對于快速追蹤與定位問題
20、微服務的安全
安全問題
1、安全要素與 STRIDE 威脅
2、防范常見的 Web 攻擊
3、服務端通信安全攻防
4、HTTPS 原理剖析
5、HTTPS 降級攻擊
6、授權與認證
7、基于角色的訪問控制
8、基于數據的訪問控制
性能優化
1、性能指標有哪些
2、如何發現性能瓶頸
3、性能調優的常見手段、說說你在項目中如何進行性能調優
分布式
1、分布式的與缺點
分布式的與缺點
2、談談業務中使用分布式的場景
系統為什么使用分布式:
隨著互聯網的發展,傳統單工程項目的很多性能瓶頸越發凸顯,性能瓶頸可以有幾個方面:
1、應用服務層:隨著用戶量的增加,并發量增加,單項目難以承受如此大的并發請求導致的性能瓶頸。
2、底層數據庫層:隨著業務的發展,數據庫壓力越來越大,導致的性能瓶頸。
場景1:應用系統集群的 Session 共享
應用系統集群最簡單的就是服務器集群,比如:Tomcat 集群。應用系統集群的時候,比較凸顯的問題是 Session 共享,Session 共享我們一是可以通過服務器插件來解決。另外一種也可以通過 Redis 等中間件實現。
場景2:應用系統的服務化拆分
服務化拆分,是目前非?;馃岬囊环N方式?,F在都在提微服務。通過對傳統項目進行服務化拆分,達到服務獨立解耦,單服務又可以橫向擴容。服務化拆分遇到的經典問題就是分布式事務問題。目前,比較常用的分布式事務解決方案有幾種:消息最終一致性、TCC 補償型事務等。
場景3:底層數據庫的壓力分攤
如果系統的性能壓力出現在數據庫,那我們就可以讀寫分離、分庫分表等方案進行解決。
3、Session 分布式方案
第一種:使用硬件F5做粘性會話(不會,只是知道可以這么干),成本太高,后期也不好維護。
第二種:使用Nginx的ip_hash特性做粘性會話,可以讓用戶每次訪問都轉發到該用戶第一次訪問的web容器上,但是當該web容器上的應用掛了,nginx不會將該用戶的請求轉發到別的web容器,體驗不好。
第三種:基于cookie實現,將session直接存儲到cookie中(安全問題,雖然可以加密存儲,但是覺得不能將敏感數據放在客戶端)
第四種:使用容器擴展來實現,大家比較容易接受的是通過容器插件來實現,比如基于Tomcat的memcached-session-manager / tomcat-redis-session-manager,基于Jetty的jetty-nosql-memcache / jetty-session-redis等等。好處是對項目來說是透明的,無需改動代碼。不過前者目前還不支持Tomcat 8,或者說不太完善。此方法過于依賴容器,一旦容器升級或者更換意味著又得從新來過。并且代碼不在項目中,對開發者來說維護也是個問題(如果你使用的是weblogic、jboss、websphere等商業web容器,根本沒有這種第三方容器擴展,web容器換了廠商就不行了)。
第五種:自己實現一套會話管理,將session讀取/存儲到Redis或其他nosql或數據庫(網站用戶量大的情況下,頻繁dml數據,對db壓力大)中。很顯然這個方案靈活性最大,但開發需要一些額外的時間。弄懂了會挺不錯的。
第六種:使用框架的會話管理工具spring-session,可以理解是替換了Servlet那一套會話管理,既不依賴容器,又不需要改動代碼,并且是用了spring-data-redis那一套連接池,可以說是最完美的解決方案。當然,前提是項目要使用Spring Framework才行。
第七種:如果項目中使用shiro這種自帶session(非httpsession)的權限框架,需要重寫shiro的SessionDao將session存入redis(或其他)來實現session共享,可以自己重寫(也不是很麻煩)或者找現成的(shiro-redis微笑臉,省的自己造輪子了,知道原理就行)。
4、分布式鎖的場景及分布是鎖的實現方案
https://www.cnblogs.com/zhisheng/p/8947996.html
5、分布式事務
https://www.cnblogs.com/jiangyu666/p/8522547.html
6、集群與負載均衡的算法與實現
什么是負載均衡:
負載均衡,英文名稱為Load Balance,指由多臺服務器以對稱的方式組成一個服務器集合,每臺服務器都具有等價的地位,都可以單獨對外提供服務而無須其他服務器的輔助。通過某種負載分擔技術,將外部發送來的請求均勻分配到對稱結構中的某一臺服務器上,而接收到請求的服務器獨立地回應客戶的請求。負載均衡能夠平均分配客戶請求到服務器陣列,借此提供快速獲取重要數據,解決大量并發訪問服務問題,這種集群技術可以用最少的投資獲得接近于大型主機的性能。
負載均衡分為軟件負載均衡和硬件負載均衡,前者的代表是阿里章文嵩博士研發的LVS,后者則是均衡服務器比如F5。
負載均衡的常用算法:
1、隨機(Random)
通過隨機數生成算法選取一個服務器,然后把連接發送給它。
2、輪詢(Round Robin)
輪詢調度算法的原理:
每一次把來自用戶的請求輪流分配給內部中的服務器,從1開始,直到N(內部服務器個數),然后重新開始循環。算法的優點是其簡潔性,它無需記錄當前所有連接的狀態,所以它是一種無狀態調度。
缺點:不考慮每臺服務器的處理能力
3、加權輪詢(Weight Round Robin)
由于每臺服務器的配置、安裝的業務應用等不同,其處理能力會不一樣。所以,我們根據服務器的不同處理能力,給每個服務器分配不同的權值,使其能夠接受相應權值數的服務請求。
4、Source Hashing(源地址Hash)
源地址散列調度算法是一種靜態映射算法,它通過一個散列(Hash)函數將一個源IP地址映射到一臺服務器,若該服務器是可用的并且沒有超負荷,將請求發送到該服務器,否則返回空。它采用的散列函數與目標地址散列調度算法的相同。它的算法流程與目標地址散列調度算法的基本相似,除了將請求的目標IP地址換成請求的源IP地址,所以這里不一個一個敘述。
5、Destination hashing(目標地址Hash)
目標地址散列調度算法也是針對目標IP地址的負載均衡,它是一種靜態映射算法,通過一個散列(Hash)函數將一個目標IP地址映射到一臺服務器。目標地址散列調度算法先根據請求的目標IP地址,作為散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。
6、一致哈希(consistent-hash)
一致哈希(consistent-hash)
7、Least-Connection(最少連接)
最少連接調度算法是把新的連接請求分配到當前連接數最小的服務器,最小連接調度是一種動態調度短算法,它通過服務器當前所活躍的連接數來估計服務器的負載均衡,調度器需要記錄各個服務器已建立連接的數目,當一個請求被調度到某臺服務器,其連接數加1,當連接中止或超時,其連接數減一,在系統實現時,我們也引入當服務器的權值為0時,表示該服務器不可用而不被調度。
Dubbo負載均衡:https://www.cnblogs.com/javanoob/p/dubbo_loadbalance.html
7、說說分庫與分表設計、分庫與分表帶來的分布式困境與應對之策
分庫分表的基本思想
?
微服務
1、前后端分離是如何做的
淘寶前后分離實踐:https://2014.jsconfchina.com/slides/herman-taobaoweb/index.html#/57
https://blog.csdn.net/fuzhongmin05/article/details/81591072
https://blog.csdn.net/weixin_37539378/article/details/79956760
https://blog.csdn.net/belalds/article/details/81571830
前后端分離的優勢:
1、可以實現真正的前后端解耦,前端服務器使用nginx。前端/WEB服務器放的是css,js,圖片等等一系列靜態資源(甚至你還可以css,js,圖片等資源放到特定的文件服務器,例如阿里云的oss,并使用cdn加速),前端服務器負責控制頁面引用&跳轉&路由,前端頁面異步調用后端的接口,后端/應用服務器使用tomcat(把tomcat想象成一個數據提供者),加快整體響應速度。(這里需要使用一些前端工程化的框架比如nodejs,react,router,react,redux,webpack)
2、發現bug,可以快速定位是誰的問題,不會出現互相踢皮球的現象。頁面邏輯,跳轉錯誤,瀏覽器兼容性問題,腳本錯誤,頁面樣式等問題,全部由前端工程師來負責。接口數據出錯,數據沒有提交成功,應答超時等問題,全部由后端工程師來解決。雙方互不干擾,前端與后端是相親相愛的一家人。
3、在大并發情況下,我可以同時水平擴展前后端服務器,比如淘寶的一個首頁就需要2000+臺前端服務器做集群來抗住日均多少億+的日均pv。
4、減少后端服務器的并發/負載壓力。除了接口以外的其他所有http請求全部轉移到前端nginx上,接口的請求調用tomcat,參考nginx反向代理tomcat。且除了第一次頁面請求外,瀏覽器會大量調用本地緩存。
5、即使后端服務暫時超時或者宕機了,前端頁面也會正常訪問,只不過數據刷不出來而已。
6、也許你也需要有微信相關的輕應用,那樣你的接口完全可以共用,如果也有app相關的服務,那么只要通過一些代碼重構,也可以大量復用接口,提升效率。(多端應用)
7、頁面顯示的東西再多也不怕,因為是異步加載。
8、nginx支持頁面熱部署,不用重啟服務器,前端升級更無縫。
9、增加代碼的維護性&易讀性(前后端耦在一起的代碼讀起來相當費勁)。
10、提升開發效率,因為可以前后端并行開發,而不是像以前的強依賴。
11、在nginx中部署證書,外網使用https訪問,并且只開放443和80端口,其他端口一律關閉(防止黑客端口掃描),內網使用http,性能和安全都有保障。
12、前端大量的組件代碼得以復用,組件化,提升開發效率,抽出來!
前后端分離注意事項
1、相關會議前后端工程師必須全部參加,并且需要制定好接口文檔,后端工程師要寫好測試用例,不要讓前端工程師充當你的專職測試,推薦使用chrome的插件postman或soapui或jmeter,service層的測試用例拿junit寫。ps:前端也可以玩單元測試嗎?
2、上述的接口并不是java里的interface,說白了調用接口就是調用你controler里的方法。
3、加重了前端團隊的工作量,減輕了后端團隊的工作量,提高了性能和可擴展性。
4、我們需要一些前端的框架來解決類似于頁面嵌套,分頁,頁面跳轉控制等功能。
5、如果頁面上有一些權限等等相關的校驗,那么這些相關的數據也可以通過ajax從接口里拿。
6、對于既可以前端做也可以后端做的邏輯,我建議是放到前端,為什么?因為你的邏輯需要計算資源進行計算,如果放到后端去run邏輯,則會消耗帶寬&內存&cpu等等計算資源,你要記住一點就是服務端的計算資源是有限的,而如果放到前端,使用的是客戶端的計算資源,這樣你的服務端負載就會下降(高并發場景)。類似于數據校驗這種,前后端都需要做!
7、前端需要有機制應對后端請求超時以及后端服務宕機的情況,友好的展示給用戶。
2、如何解決跨域(CSRF)
https://segmentfault.com/a/1190000015597029
3、微服務哪些框架
匯總微服務架構落地的15種框架?
4、你怎么理解 RPC 框架
RPC簡介及框架選擇
5、說說 RPC 的實現原理
RPC入門總結(一)RPC定義和原理
RPC的經典調用的流程
(1)服務消費方(client)以本地調用方式調用服務;?
(2). client stub接收到調用后負責將方法、參數等組裝成能夠進行網絡傳輸的消息體;?
(3). client stub找到服務地址,并將消息發送到服務端;?
(4). server stub收到消息后進行解碼;?
(5). server stub根據解碼結果 反射調用 本地的服務;?
(6). 本地服務執行并將結果返回給server stub;?
(7). server stub將返回結果打包成消息并發送至消費方;?
(8). client stub接收到消息,并進行解碼;?
(9). 服務消費方得到最終結果。
6、說說 Dubbo 的實現原理
https://blog.csdn.net/gangsijay888/article/details/88630019
7、你怎么理解 RESTful(Resource?REpresentational State Transfer)
怎么理解 RESTful
8、說說如何設計一個良好的 API(Application Programming Interface,應用程序編程接口)
(1)要明確
這也許是最重要一點。如果你有一個方法getUser,如果不明確它可能引起一些副作用,最終會導致很多問題。比如getUser明確的只是返回一個用戶,不會對用戶的id進行增加。
盡可能多的提供更多的行為。不要指望用戶會潛水你的源碼,以發現隱藏的行為。
(2)讓a p i表面積盡可能小
沒有人喜歡臃腫的程序,如果你能夠暴露更少的api就能完成工作,這對于每個人都是一個很好的體驗。
是否人們真的要求你寫這個新的api?一直到它是一個真正需要有人去解決的問題的時候,你才可以去做它。
(3)減少樣板
盡可能的在內部處理各種細節,以減少客戶端的負擔??蛻舳苏{用的時候做的越少,漏洞才可能越少。
喜歡干凈的代碼?那就保持你的api很干凈,那么,你的api的客戶調用就會很簡潔。
(4)降低依賴
盡可能的保證你的代碼人自我封閉,你有更多的依賴,就意味著潛在的問題會影響到下游代碼。
如果你希望從另外一個模塊里,獲取一塊功能,那么盡可能的只提取你需要的。在代碼重用和緊耦合和之間有一個平衡,如果功能比較小,那么就值得你自己重新實現它。
(5)返回有意義的錯誤狀態
返回null是毫無意義的,他什么也意味不了。錯誤信息要能夠有可以進行改善的提示。Error.USER_NOT_CREATED 或Error.USER_DELETED都是有意義的。
(6)異常應該有真正的含義
如果你使用的語言沒有異常,祝賀你,函數式語言在提供有意義的錯誤狀態方面會做的更好。
一場已經在java領域被濫用,getUser時如果沒有發現用戶,不要拋UserNotFoundException,而是返回一個正常的錯誤狀態。
比一個蹦潰的程序更壞的事情是,不要因為一個不確定的狀態導致崩潰。
(7)對所有的事情要建立文檔
文檔是無聊的,但必不可少,良好的文檔會保存你的理智思考,會避免api消費的很多問題。
一個好的文檔包括:
1.有關模塊是如何工作的高層次概述
2.公共方法和接口的javadoc
3.如何使用api的案例
不是所有的抽象都需要文檔的,一些小類就不需要案例代碼。
文檔必須是演進,如果有很多問題問同樣的事情,你就可能需要把它加到文檔里。
太多的文檔也是浪費時間,因為你必須保持不斷的更新,但是如果仍沒有人使用,它就沒有什么價值,所以要保證足夠的重點和適當的文檔。
(8)編寫測試
這是是正確性的證明,文檔和示例代碼都可以包括進去。它為中國提供了巨大的價值,能夠讓你在事情改變時候,很自信的快速移動。
那些想對你的api實現深入研究的人總是,通過閱讀測試實現的,能夠更多的了解你的代碼行為和意圖。這些都是文檔無法實現的。
(9)變得可測試
測試你的代碼是一回事兒,讓人們對你的api更容易地編寫測試代碼又是另外一回事兒。
你需要有針對調試和產品環境的不同配置。
(10)允許用戶選擇
不是每一個客戶端都以同樣的方式調用你的api,有些人可能喜歡同步調用,而另外一些人更喜歡一部回調。
讓用戶選擇他們自己喜歡的方式,你的api就更容易集成到他們現有的編程環境中,更可能地被使用。
(11)不要給用戶太多的選擇
不要給用戶太多的選擇,否則他們就有選擇障礙,總是提供合理的默認行為,也就是你的api默認的使用方式。
api應該鼓勵規范行為,不要讓消費者修改內部狀態,如果你無意中暴露一些怪異的行為,它會產生一些不可預見的后果。
給出態度的選擇就會失去重點,在正確和靈活之間要進行平衡和選擇。
總之,設計一個api是一種藝術,需要更多的實踐。
如何設計一個良好的API
9、如何理解 RESTful API 的冪等性
https://blog.csdn.net/garfielder007/article/details/55684420
10、如何保證接口的冪等性
冪等策略分析:https://www.cnblogs.com/geyifan/p/6128425.html
11、說說 CAP 定理、 BASE 理論(見分布式)
https://www.cnblogs.com/jiangyu666/p/8522547.html
12、怎么考慮數據一致性問題(分布式事務)
https://www.cnblogs.com/jiangyu666/p/8522547.html
13、說說最終一致性的實現方案
14、你怎么看待微服務
微服務究竟該如何理解
15、微服務與 SOA 的區別
微服務架構 vs. SOA架構
16、如何拆分服務
服務的拆分是一個非常有學問的技術活,要圍繞業務模塊進行拆分,拆分粒度應該保證微服務具有業務的獨立性與完整性,盡可能少的存在服務依賴,鏈式調用。但是,在實際開發過程中,有的時候單體架構更加適合當前的項目。實際上,微服務的設計并不是一蹴而就的,它是一個設計與反饋過程。因此,我們在設計之初可以將服務的粒度設計的大一些,并考慮其可擴展性,隨著業務的發展,進行動態地拆分也是一個不錯的選擇。
如何拆分服務
17、微服務如何進行數據庫管理
https://www.jianshu.com/p/cd726b32342e
18、如何應對微服務的鏈式調用異常
一般情況下,每個微服務之間是獨立的,如果某個服務宕機,只會影響到當前服務,而不會對整個業務系統產生影響。但是,服務端可能會在多個微服務之間產生一條鏈式調用,并把整合后的信息返回給客戶端。在調用過程中,如果某個服務宕機或者網絡不穩定可能造成整個請求失敗。因此,為了應對微服務的鏈式調用異常,我們需要在設計微服務調用鏈時不宜過長,以免客戶端長時間等待,以及中間環節出現錯誤造成整個請求失敗。此外,可以考慮使用消息隊列進行業務解耦,并且使用緩存避免微服務的鏈式調用從而提高該接口的可用性。
19、對于快速追蹤與定位問題
https://blog.51cto.com/wks97/2074615
https://www.jianshu.com/p/904c48e6bc0c
20、微服務的安全
如何做一個優秀的微服務訪問安全設計方案
https://blog.csdn.net/qq_36807862/article/details/81284327
微服務安全和治理
安全問題
1、安全要素與 STRIDE 威脅
http://blog.720ui.com/2017/security_stride/
2、防范常見的 Web 攻擊
Web常見幾種攻擊與預防方式
3、服務端通信安全攻防
服務端通信安全攻防詳解
4、HTTPS 原理剖析
HTTPS 原理解析
5、HTTPS 降級攻擊
http://blog.jobbole.com/106792/
6、授權與認證
7、基于角色的訪問控制
基于角色的訪問控制
8、基于數據的訪問控制
http://blog.720ui.com/2017/msa_rbac_data/
性能優化
1、性能指標有哪些
性能測試監控關鍵指標說明:
資源指標
CPU使用率:指用戶進程與系統進程消耗的CPU時間百分比,長時間情況下,一般可接受上限不超過85%。
內存利用率:內存利用率=(1-空閑內存/總內存大小)*100%,一般至少有10%可用內存,內存使用率可接受上限為85%。
磁盤I/O: 磁盤主要用于存取數據,因此當說到IO操作的時候,就會存在兩種相對應的操作,存數據的時候對應的是寫IO操作,取數據的時候對應的是是讀IO操作,一般使用% Disk Time(磁盤用于讀寫操作所占用的時間百分比)度量磁盤讀寫性能。
網絡帶寬:一般使用計數器Bytes Total/sec來度量,Bytes Total/sec表示為發送和接收字節的速率,包括幀字符在內。判斷網絡連接速度是否是瓶頸,可以用該計數器的值和目前網絡的帶寬比較。
系統指標:
并發用戶數:某一物理時刻同時向系統提交請求的用戶數。
在線用戶數:某段時間內訪問系統的用戶數,這些用戶并不一定同時向系統提交請求。
平均響應時間:系統處理事務的響應時間的平均值。事務的響應時間是從客戶端提交訪問請求到客戶端接收到服務器響應所消耗的時間。對于系統快速響應類頁面,一般響應時間為3秒左右。
事務成功率:性能測試中,定義事務用于度量一個或者多個業務流程的性能指標,如用戶登錄、保存訂單、提交訂單操作均可定義為事務,如下圖所示:
單位時間內系統可以成功完成多少個定義的事務,在一定程度上反應了系統的處理能力,一般以事務成功率來度量,計算公式如下所示:
超時錯誤率:主要指事務由于超時或系統內部其它錯誤導致失敗占總事務的比率。
2、如何發現性能瓶頸
https://blog.csdn.net/sd4015700/article/details/50467346
https://www.jianshu.com/p/87ef6d1c3398
3、性能調優的常見手段、說說你在項目中如何進行性能調優
常見性能優化方法的一些總結
前端常見的性能優化手段
常見網站性能優化手段的8中方法
?
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的面试题汇总-分布式(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL数据库 单表数据记录查询
- 下一篇: 从图书馆进入网络刷题练习与考试平台