02.25 去互聯網公司面試,面試官問我SpringCloud,附答案

下面整理了一些面試的過程中被問到的Spring相關的題目,只因簡歷上寫了熟練使用SpringBoot,SpringCloud。希望為即將準備面試的胖友提供一些幫助,平時還是要多關注一些細節的地方!

SpringBoot的優勢是什麼? 自動配置/依賴的原理是什麼?

SpringBoot可以快速一鍵搭建一個基於Spring的生產就緒的應用框架,簡化Spring應用的初始搭建以及開發過程:

  • 最大的優勢在於簡化配置和簡化編碼方面,簡化了之前開發Spring應用繁瑣的配置,它內部集成了常用的第三方庫配置,SpringBoot中這些第三方庫幾乎可以零配置的開箱即用,大部分SpringBoot應用都只需要非常少量的配置代碼和極簡的maven pom 文件的配置,使得開發者可以更專注於業務邏輯的開發。
  • 簡化部署,SpringBoot內置了Tomcat, 我們只需要把項目打成jar包就可以一鍵啟動
  • 簡化監控,我們可以直接使用spring-boot-start-actuator對服務進行運行期性能和健康的監控

自動配置原理

SpringBoot自動配置自帶了很多了配置類,自動配置建立在spring條件化配置基礎之上的:

  1. 首先SpringBoot的主配置類上的@SpringBootApplication 開啟了自動配置功能@EnableAutoConfiguration
  2. @EnableAutoConfiguration 利用AutoConfigurationImportSelector將META-INF/spring.factories裡面配置的所有xxxAutoConfiguration的配置類都加入容器中,用他們來做自動配置。spring-boot-autoconfiguration的jar 文件裡面包含了很多的配置類,比如jpa, mvc,redis,neo4j。用戶可以自己選擇是否在程序裡面使用他們,這些配置類構成了Springboot的自動配置。 儘管這些配置存在與應用程序的ClassPath中,但是在滿足某些條件之前應用會忽略這個配置,比如: Spring啟動的時候會做幾百次這樣的檢查,比如檢查Jdbctemplate是不是在Classpath裡面,如果是就會配置一個對應的jdbcTemplate的配置Bean。 所有的這些配置都是儘量的不讓開發者自己去寫配置。


去互聯網公司面試,面試官問我SpringCloud,附答案


SpringCloud裡你還對哪些組件比較熟悉?

服務註冊中心Eureka

服務提供者向服務註冊中心進行服務的註冊,並週期性的發送心跳來更新服務信息,服務消費者拉取服務註冊中心的服務列表並維護在本地,並從服務列表中拉取一個服務進行消費。

Eureka本身支持高可用,可以通過集群的方式部署,Eureka Server之間也可以相互註冊,相互同步服務信息。

  • 失效服務的剔除: 比如超過30s沒有心跳的服務,就會被Eureka標記為不可用
  • 自我保護機制: ​ 當Eureka 與其它服務之間的心跳大面積失敗的時候,它會認為可能是自己的問題,比如自己網絡不好,就會把註冊的信息保護起來。這時如果有消費者來訪問,可能就會拿到真正過期的服務的情況。

Ribbon負載均衡器

  • Ribbon 是一個基於HTTP的客戶端負載均衡器,可以在客戶端負載均衡訪問服務提供者列表提供的服務
  • Ribbon 提供了一系列完善的配置項如連接超時,重試等,Ribbon會自動的某種算法去連接機器


去互聯網公司面試,面試官問我SpringCloud,附答案


Fegin

  • 微服務之間聲明式的調用,整合了Ribbon和Eureka,關鍵機制是使用了動態代理,讓用戶不用自己去寫HTTP請求,讓客戶端覺得調用本地接口就像調用其它服務一樣。 首先,對於某個接口定義了@FeginClient 註解,Fegin就會針對這個接口創建一個動態代理 接著,調用接口的時候,本質上是調用Fegin創建的動態代理 Fegin 會根據接口上的@RequestMapping等註解,來動態構造要請求的服務的地址 針對這個地址,發起請求,解析響應

Zuul

Zuul的原理: 通過一個統一的Servlet入口ZuulServlet攔截所有的請求,然後通過ZuulFilter鏈對請求做攔截和過濾處理。Zuul大部分功能都是通過過濾器來實現的,Zuul中定義了4種標準的過濾器,這些過濾器對應於請求的典型生命週期:

  1. PRE: 請求路由到某個服務之前調用,可以實現身份驗證等
  2. ROUTING: 用於構建發送給微服務的請求,並通過HttpClient 或 Ribbon 請求微服務
  3. POST: 在請求路由到微服務以後執行,可以為響應結果添加Http Header, 將結果發送給客戶端
  4. ERROR: 在其它階段發生錯誤的時候執行該過濾器


去互聯網公司面試,面試官問我SpringCloud,附答案


  • 客戶端只需要請求Zuul網關就可以了,無需要調用特定微服務,由Zuul網關負責轉發請求,這樣開發就可以得到簡化,易於做監控,易於安全認證(比如不需要再每一個微服務上都進行認證)負載均衡等。

Config

微服務數量比較多的時候,配置管理就比較複雜了,SpringCloud Config通過分佈式配置中心來統一管理配置文件並可以實時更新。Config Server用於配置屬性的存儲,Config Client用於服務屬性的讀取。

Bus

當配置文件需要動態更新的時候,可以通過Bus在不關閉服務的情況下更新我們的配置。

Hystrix 熔斷限流降級

  • 防止因服務提供者的不可用導致服務調用者的不可用,並將不可用逐漸放大雪崩的過程。

Hystrix熔斷過程講一下? Hystrix實現原理講一下? 線程池和信號量熔斷區別?

  • 熔斷過程:當用戶請求量大或者緩存擊穿,會照成後端服務提供者的瞬間超負荷允許,引起服務不可用,當Hystrix檢查到超時或者出現異常的時候,就會執行fallback方法而不是讓client一直等待或重試。
  • 服務降級過程: 當服務壓力劇增時,可以根據流量情況對一些服務的頁面做降級,比如返回一個默認值或者返回一個提示,讓用戶稍後重試之類。如果目標服務情況好轉則恢復正常調用。

Hystrix的實現可以基於線程池或信號量的方式:

  • 基於線程池: 在服務和請求之間增加了一個線程池,用戶的請求將不再直接訪問服務,而是先經過熔斷器,然後通過線程池中空閒線程來訪問服務,如果這個時候熔斷器是打開的,說明已經熔斷了,直接進行降級處理。 當線程池飽和並且請求隊列阻塞的時候,可以提前拒絕服務。
  • 基於信號量:當請求進入熔斷器時,會有一個計數的信號量,每來一個請求數,計數器加1,結果大於最大請求的時候,就返回false,發生信號量拒絕事件,執行降級邏輯。當請求離開熔斷器時,執行release(),計數器減1。信號量模式下,接收請求和執行下游依賴在同一個線程內完成,不存在線程上下文切換帶來的性能開銷。

線程池和信號量熔斷區別?

  • 資源消耗方面,信號量只是個計數器,資源消耗小,如果有數百個服務實例,線程池做隔離的開銷過大,會有上下文的切換開銷
  • 信號量的調用時同步的,每次調用都會阻塞調用方的線程直到結果返回,不支持異步,不支持超時,線程池支持超時返回
  • 信號量是達到最大請求量閾值時熔斷,線程池時達到最大線程數熔斷

Hystrix/Feign/Ribbon之間如何配合的, 代碼上架構是怎樣的?

Fegin 通過代理模式自動將所有的方法用Hystrix進行了包裝,目的是在調用方實施針對被調用微服務的熔斷邏輯,針對被調用服務設置超時時間,一旦超時就會進入熔斷邏輯,而這個故障指標信息也會返回給Hystrix組件,hystrix根據故障信息打開斷路器,之後所有針對該微服務的請求都會直接進入熔斷邏輯,直到故障恢復關閉斷路器為止。

  • 首先Ribbon從Eureka Client 裡面獲取對應的服務註冊表,比如服務的ip 和 端口
  • 然後Ribbon使用默認的的Round Robin算法,從中選擇一臺機器
  • Fegin就會針對這臺機器,構造代理併發起http請求


去互聯網公司面試,面試官問我SpringCloud,附答案


總結

SpringCloud SpringBoot 這套技術棧,大家平時自己使用的過程,可能覺得比較簡單,不過了解其底層實現細節,對我們寫出高性能的服務架構肯定大有裨益。比如在瞭解原理後,我們知道Hystrix在有大量的請求時,如果默認使用線程池可能會頻繁的線程切換,更加重系統性能,這時候可以考慮切換了。

2020年最新源碼分析課程資料,關注私信【555】獲取,還可領取更多Java面試題資料和Java架構學習資料


分享到:


相關文章: