面試專題(分佈式系統微服務) 原

架構設計相關

0. 什麼是分佈式系統,什麼是微服務?

集羣:多機器做同一件事情;
分佈式系統: 一件事情,多系統協同完成;
微服務架構:構建分佈式系統的一種架構方式, 核心思路是:去中心化;
http://www.cnblogs.com/liuning8023/p/4493156.html
 

1. RPC和RPC框架

RPC是指遠程過程調用,實現遠程過程調用的方式有很多中,Dubbo,Rmi,Hessian等等;
RPC的核心過程包括了客戶端和服務端的通訊協議,尋址,數據序列化/反序列化;
對上述過程進行了封裝,不需要開發人員自己去定義通訊協議,去實現序列化的細節工作,
這樣的組件稱爲RPC框架;常見RPC框架有 thrift,gRpc,dubbo,motan


2. 序列化方式及作用

序列化:將java對象或者其他內存中的數據,轉換爲一種特定格式的流,使之可以在網絡中傳輸或者磁盤上存儲;
反序列化:將流以特定的格式轉爲java對象或者內存中其他形式的數據;# json,jdk serializable, Hessian,Dubbo, Protobuf,
作用:壓縮;持久化存儲;跨網絡傳輸;


3. 分佈式系統中事務的處理

參考:https://wenku.baidu.com/view/be946bec0975f46527d3e104.html
          https://segmentfault.com/a/1190000004468442
事務相關必瞭解的概念:
ACID (Atomic原子性,Consistency一致性,Isolation隔離性,Durability持久性)
CAP (一致性Consistency,可用性Availability,分區容錯性Partitiontolerance),分佈式系統來說,P是不能放棄的
BASE (Basically Available(基本可用),Soft state(軟狀態),Eventuallyconsistent(最終一致性))
分佈式事務實現方式:
1.  XA (數據庫廠商實現);2. 後臺任務定期校對數據;3. 通過消息隊列,實現最終一致(確保消息到達MQ,冪等性);4. TCC機制(Try,Confirm,Cancel)
https://www.cnblogs.com/rainwang/p/7099648.html

 

4. 系統監控

# 鏈路監控
Spring‐Cloud‐Sleuth + Zipkin
Sleuth收集微服務之間的接口調用信息以及內部方法調用。通過採樣之後,將數據傳輸致
Zipkin,由Zipkin負責存儲和可視化查詢;
# 核心概念:Trace,Span。公開課有講過Sleuth;
# 日誌監控

ELK
1)ElasticSearch搜索服務器,提供了一個分佈式多用戶能力的全文搜索引擎,基於
RESTful web接口。
2)Logstash是可以對日誌進行收集、過濾、分析,並將其存儲供以後使用;
3)Kibana 是Elasticsearch前端展示工具,可以爲 Logstash 和 ElasticSearch 提供
的日誌分析友好的 Web 界面,可以幫助您彙總、分析和搜索重要數據日誌
搭建方式參考資料: https://www.cnblogs.com/kevingrace/p/5919021.html
# 代碼性能監控
Metrics:度量;我們需要爲某個系統某個服務做監控、做統計,就需要用到Metrics;
代碼執行的吞吐量,響應時間,併發量,瞬時狀態值。
# 這個需要通過代碼埋點實現,公開課有講過Metrics+Grafana構建性能監控平臺;


5. 高可用

服務的高可用可以通過多實例,自檢測,自恢復,快速擴容機制來實現;
多實例:一個服務部署多個實例,通過負載均衡機制降低單實例的負載以及實現容錯;
自檢測:系統預留健康檢查接口,通過docker集羣模式的健康檢查機制來實現自動重啓和預警;
自恢復:對於網絡抖動的問題,需要程序有一定的容錯性,比如:熔斷機制,Eureka的自我保護措施;
快速擴容:互聯網應用的特殊性,在特定時候會出現高峯期的海量請求,此時,需要我們的分佈式系統能夠快速擴容。docker的服務編排就可以實現已有硬件資源的情況下秒級擴容;對於硬件資源,需要結合雲計算技術來實現;


6. 服務調用的負載均衡

# 服務端負載均衡:對客戶端屏蔽具體的接口地址,對外僅暴露負載均衡器,所有請求經過統一的負載服務;有硬件負載(f5,radware)和軟件負載(nginx,apache,lvs)
優勢:統一管理,控制;對外部調用友好,屏蔽了微服務地址多變的複雜性;
劣勢:性能要求高,流量大對負載服務本身有很高的要求;管理複雜,大多數服務端負載器
需要手工配置服務實例信息;
# 客戶端負載均衡:由客戶端自己選擇目標服務器,直調對應的地址;dubbo(源碼參考com.alibaba.dubbo.rpc.cluster.LoadBalance),springcloud(ribbon)都是客戶端負載均衡;
優勢:性能好,可以根據具體應用微調負載策略;易管理,服務實例信息自發現
劣勢:服務實例信息在多客戶端之間的不同步;通常是集羣內部使用;


7. 分佈式配置中心

類似產品有很多:360 Qconf,百度 Disconf,淘寶 Diamond
參考:https://www.cnblogs.com/zhangxh20/p/5464103.html
我們着重講了springcloudconfig 分佈式配置中心,用來解決多配置的問題;
將配置文件統一存儲在gitlab,svn,filesystem,並支持敏感信息的加密存儲(configserver或者client均可解密)


8. 服務註冊與發現機制

這種機制目的是實現:服務提供者的自注冊,服務消費者的主動發現服務提供者;
服務註冊:服務提供者啓動實例時,將信息存儲到註冊中心;
註冊中心:保存服務提供者或者消費者的實例信息(服務名稱,IP,端口,方法地址等等)
服務發現:服務消費者,通過服務名在註冊中心的信息中查詢出具體的服務提供者實例信息。


9. 分佈式系統如何拆分?

業務線(訂單系統,積分系統,審計系統,支付系統,結算系統,推廣系統….)
技術棧(php,java,nodejs,go)

架構分層 (前臺,中臺,後臺; 存儲服務,緩存服務,MQ服務,搜索引擎服務….)

 

SpringCloud

1. 微服務是如何保護自己的

http://blueskykong.com/2017/10/19/security1/

信息加密

通過Https實現信息傳輸的加密(nginx,tomcat都可以配置https);
對代碼侵入性很小。因爲微服務集羣不直接對外提供服務,由統一的網關來提供業務API(zuul,nginx都可以的)。

權限校驗方案

· 單點登錄

# 每個應用都必須接入單點登錄,大型系統中,需要集成單點登錄帶來的複雜工作和性能損耗;

· 分佈式session方案

流程: 客戶端 ‐> 獲取session ‐> 請求微服務 ‐> 查詢共享存儲中授權信息 ‐> 校驗權限 ‐> 提供服務 ‐> 給予響應
分佈式session保存方案,根據session去查找共享存儲中對應的權限信息來實現權限校驗;
# 共享存儲的高可用和安全性是個問題,類似直接redis,memcache來做;

· token方案

1. 客戶端 ‐> uaa認證 ‐> 獲取token
2. 客戶端 ‐> 微服務 ‐> 校驗token

token包含必要的授權信息,一次獲取,多次使用,相對獨立,實現簡單,不需要cookie;長度有限,不能撤銷,需要設置過期時間;
# 可以在網關層做;也可以構建成通用的組件,放在每個微服務上面去做;
# 根據不同的業務場景:token可以發放一次,也可以在每次請求的時候去申請,這樣能夠實現分控需要的賬戶禁用,黑名單等功能

 

2. 微服務網關

zuul是springcloud提供的成熟的路由方案;根據請求的路徑不同,網關會定位到指定的微服務,並代理請求到不同的微服務接口;對外屏蔽了微服務接口調用的複雜性。
三個重要概念:動態路由表,路由定位,反向代理
反向代理:客戶端請求到網關,網關受理後,再對目標服務發起請求,拿到響應之後,再響應給客戶端;
動態路由表:zuul支持eureka路由,手動配置的路由,這兩種都支持動態更新;
路由定位:根據請求路徑,zuul有一套自身的服務定位規則以及路由匹配的表達式;
# 應用場景: 對外暴露,權限校驗,服務聚合,日誌審計

 

3. 各服務之間如何調用

服務對外以http接口形式暴露,所以調用有多種方式;
Fegin是cloud提供的一種服務調用客戶端;
Resttemplate也可以快速的發起服務調用;
同時,也可以手動獲取對應接口的具體地址,通過平常的httpclient進行調用;
# Feign和Resttemplate 都可以集成負載均衡,失敗重試,熔斷的功能;

 

4.如何保證服務健康的情況
1. Spring Boot‐Actuator 可以用來監控我們的項目,可以通過HealthEndPoint/health來查看應用的健康狀況;
SpringBoot在集成很多組件時,都會實現一個健康檢查的接口,如ElasticsearchHealthIndicator,RedisHealthIndicator,RabbitHealthIndicator等。
2. 在微服務集羣中,我們通常還會通過sleuth來進行服務調用的鏈路追蹤,可以通過抽樣看到服務調用的異常情況;
3. 日誌信息也是我們監控服務監控情況的一個重要手段,常用通過ELK實現日誌收集,分析和查看;
4. 在通過docker部署微服務時,我們可以利用docker的健康檢查機制,實現服務的自動重啓;

 

5. 容錯機制

# Ribbon 負載均衡&重試
通過服務名獲取實例信息,根據負載策略選擇合適的實例去訪問;
服務調用失敗時,可以配置重試次數,以及實例切換的次數;
# Hystrix熔斷機制
限流,降級,熔斷;
限流:限制接口訪問併發量,限制緩衝區大小,超出限制,調用Fallback方法
熔斷:出錯率超過閾值,一定時間內不再請求該接口。(超時、run方法拋出異常)
降級:凡是沒有正常的從接口中拿到數據,就會調用Fallback方法,獲取一個結果
# 通過命令模式的封裝,SpringCloud內部自動集成,且可作用於任意JAVA方法上,不關心方法的具體實現。代表着(http、redis、db操作都可以做熔斷);

 

6. SpringCloud中的服務註冊與發現機制

兩個角色eurekaServer, eurekaClient
server提供httpapi服務,存儲服務實例的信息,並且具備主動剔除服務(心跳檢測)和server高可用的功能;
client集成在具體的微服務中,在服務啓動時,將服務實例信息post到server上;client也會定時同步server上面其他service信息;
# eureka的工作大多是後臺thread在定時工作,任務執行的間隔時間都可以通過配置文件進行配置;

 

7. SpringCloud的實施推廣

# 集成SpringMVC項目
微服務改造的過渡期,在傳統的SpringMvc項目中,引入部分SpringCloud的特性,即可通過微改造變成微服務;
# 其他語言的項目加入SpringCloud微服務系統
Eureka提供HttpApi,使得非java語言加入到SpringCloud微服務集羣成爲可能;

 

Dubbo

http://dubbo.io/books/dubbo­user­book/ 
http://dubbo.io/books/dubbo­dev­book 
http://dubbo.io/books/dubbo­admin­book/

1. 如果註冊中心集羣都掛掉,發佈者和訂閱者之間還能通信麼?

# 有緩存;
註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地緩存通訊
新的服務將無法發現;服務下架後仍舊有被調用的可能;

2. dubbo連接註冊中心和直連的區別

註冊中心: 消費者動態發現服務提供者,實現軟負載均衡和集羣容錯;
直連:不能動態增減提供者;開發、測試環境可通過指定Url方式繞過註冊中心直連指定的服務地址,快速測試

3. dubbo服務的容錯機制

# http://dubbo.io/books/dubbo‐user‐book/demos/fault‐tolerent‐strategy.html
Failover Cluster:失敗自動切換,當出現失敗,重試其它服務器,默認兩次;
Failfast Cluster:失敗立即報錯
Failsafe Cluster:失敗安全,出現異常時,直接忽略
Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發
Forking Cluster:並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較
高的讀操作,但需要浪費更多服務資源
Broadcast Cluster:播調用所有提供者,逐個調用,任意一臺報錯則報錯
# 要注意分佈式事務

4. 具體問題示例1:關於服務調用超時
# 超時是針對消費端還是服務端?
dubbo的超時是爭對客戶端的,由於是一種NIO模式,消費端發起請求後得到一個ResponseFuture,然後消費端一直輪詢這個ResponseFuture直至超時或者收到服務端的返回結果
# 超時在哪設置,優先級是什麼?
http://dubbo.io/books/dubbo‐user‐book/configuration/xml.html
# 實現原理
消費端發起遠程請求後,線程不會阻塞等待服務端的返回,而是馬上得到一個ResponseFuture(ReponseFuture的實現類:DefaultFuture),消費端通過不斷的輪詢機制判斷結果是否有返回。因爲是通過輪詢,輪詢有個需要特別注要的就是避免死循環,所以爲了解決這個問題就引入了超時機制,只在一定時間範圍內做輪詢,如果超時時間就返回超時異常

5. 服務提供者能實現失效踢出是什麼原理

源碼參考  RegistryService, 文檔參考http://dubbo.io/books/dubbo‐user‐book/references/registry/introduction.html
# redis ‐ 髒數據由監控中心刪除
# zookeeper ‐ 的臨時節點

6. dubbo通訊協議

# 什麼是通訊協議
客戶端服務端之間進行數據流轉的一種約定,將數據按照標準格式來組裝;
# 協議內容
頭部信息(調用控制協議16B) + body(序列化)
head = 魔數(2) + 標識(1) + 響應狀態(1) + 消息ID(8) + 內容長度(4)
body = dubbo版本 + 服務接口路徑 + 服務版本號 + 服務方法名 + 參數描述符 + 參數值序列化 + 隱式參數

7. 大概率的問題

# dubbo文檔,仔細閱讀一遍,面試官可能隨便抽取一個。
# dubbo配置的方式和屬性

http://dubbo.io/books/dubbo‐user‐book/configuration/
# dubbo底層協議
http://dubbo.io/books/dubbo‐user‐book/references/protocol/introduction.html
# dubbo服務註冊與發現流程
http://dubbo.io/books/dubbo‐user‐book/references/registry/introduction.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章