java分布式系統操作「java 分布式有哪些技術」

應用架構演進

這裡的架構演進應該是從服務化的角度來說,應該說隨着業務發展,應用規模擴大,系統的一些公共服務就會抽取出來,獨立開發,部署,維護,用來解決並發,擴展,維護的問題。

傳統垂直架構

有的地方也叫單體應用,以mvc模式開發:

  1. 所有應用代碼統一打包,代碼所有接口本地api調用,很少存在遠程服務調用;
  2. 單機或主備,應用做集群部署;
  3. DB主從等。

這種並沒有什麼不好,發展初期大多是這樣,體量沒那麼大,也不需要考慮高並發大流量可擴展性什麼的,簡單粗暴,解決業務需求就好,活下去才能活的更好。

但是必須明白這種簡單架構存在的一些問題:

1. 業務不斷發展,功能逐漸增多,應用的開發維護成本變高,部署效率降低,隨便改個代碼,編譯一次十幾分鐘就浪費了。悲劇,我們有個系統才開發3年,就碰到這種情況,一次打包編譯部署,13分鐘結束。

2. 不同的人負責不同的部分,一些通用代碼、公共代碼就各寫各的,不能復用,如果只是util還好,但是一些外部服務的都有重複,那就happy了(不過這種情況的出現,不一定是架構問題,更多可能是管理);

3. 不斷地上新需求,不斷地改代碼,有時測試不到位,指定哪裡埋了bug,上生產後系統就down了,牽一髮而動全身;

4. 可維護性,可靠性,擴展性變差。

既然有這些問題,就要解決啊,業務就會提要求,你要解決啊,要不然影響我業務發展,影響我ipo上市啊,苦逼的碼農開始幹活了。

不提應用的拆分主從那些手段,但從拆分後應用交互看,原來的本地api交互變成的遠程api的調用,這裡就出現了rpc,當然也有走esb,webservice。其實拆分後挺麻煩的,光一個分布式事務就能折騰死人。

RPC架構

Remote Procedure Call,遠程方法調用,屏蔽底層實現細節,像調用本地方法一樣調用遠程服務。

上個作者的圖:

Java編程良心推薦——分布式架構原理解析

這個圖對於大多數rpc框架通用,實現的幾個技術點:

1. 服務提供者發布服務:服務接口定義,數據結構,服務提供者信息等;

2. 客戶端遠程調用:通常是使用jdk的代碼代理攔截;

3. 底層通信:現在應該更多是使用netty吧,當然也有走支持http的;

4. 序列化:關注序列化反序列性能,xml,json,hessiaon,pb,protostuff,kryo等;

作者給了個socket實現簡單demo,來實現遠程調用,說明上面幾個技術點。

常用的rpc框架

1. Thrift;

2. Hadoop的Avro-RPC;

3. Hessian;

4. gRPC;

單論rpc的話,沒太多可說的,可是如果加上服務治理,那複雜度就幾何倍數增長了。服務治理裡面東西太多了,動態註冊,動態發現,服務管控,調用鏈分析等等問題這些問題,單憑rpc框架解決不了,所以現在常用的說的服務化框架,通常指的是rpc+服務治理2個點。

SOA服務化架構

感覺soa架構應該是在rpc之前出現,用來解決異構系統的交互,通常的實現是通過ESB,WSDL來處理。其粒度通常來說是比較粗的。也存在服務治理方面的問題。

微服務

MSA也是一種服務化架構風格,正流行ing,服務劃分

1. 原子服務,粒度細;

2. 獨立部署,主要是容器;

分享篇文章:雲棲肥俠的文章 微服務(Microservice)那點事 。

MSA與SOA的對比:

  1. 服務拆分粒度:soa首要解決的是異構系統的服務化,微服務專註服務的拆分,原子服務;
  2. 服務依賴:soa主要處理已有系統,重用已有的資產,存在大量服務間依賴,微服務強調服務自治,原子性,避免依賴耦合的產生;
  3. 服務規模:soa服務粒度大,大多數將多個服務合併打包,因此服務實例數有限,微服務強調自治,服務獨立部署,導致規模膨脹,對服務治理有挑戰;
  4. 架構差異:微服務通常是去中心化的,soa通常是基於ESB的;
  5. 服務治理:微服務的動態治理,實時管控,而soa通常是靜態配置治理;
  6. 交付:微服務的小團隊作戰。

感覺在有了docker後,微服務這個概念突然火了起來,總結就是微服務+容器+DevOps。

Java編程良心推薦——分布式架構原理解析

分布式服務框架入門

背景

應用從集中式走向分布式

隨着業務的發展導致功能的增多,傳統的架構模式開發,測試,部署整個流程變長,效率變低,後台服務的壓力變大,只能通過硬件擴容來暫時緩解壓力,但解決不了根本性問題:

  1. 應用規模變大,開發維護成本變高,部署效率降低;
  2. 代碼復用:原來是本地api調用,導致一些公用功能可能是按需開發,不統一,隨意等問題;
  3. 交付面臨困難:主要是業務變得複雜,新增修改測試變得困難,拉長整個流程。

通用法寶:拆分,大系統拆小系統,獨立擴展和伸縮。

  1. 縱向:分業務模塊;
  2. 橫向:提煉核心功能,公共業務;

需要服務治理

大拆小,核心服務提煉後,服務的數量變多,而且需要一些運行態的管控,這時候就需要服務治理:

  1. 服務生命周期管理;
  2. 服務容量規劃;
  3. 運行期治理;
  4. 服務安全。

服務框架介紹

Dubbo

阿里開源的Dubbo應該是業界分布式服務框架最出名的了吧,看過公司的rpc框架,Dubbo的擴展性比我們的好的多了,我們的框架每次升級,改動都很多,改天要看下Dubbo的源碼了解了解擴展性。

Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析

HSF

淘寶的體量決定了他對極致性能的追求,HSF跨機房特性挺牛。

Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析

Coral Service

這個沒聽說過,孤陋寡聞了。

Java編程良心推薦——分布式架構原理解析

框架設計

架構原理

萬變不離其中,這張圖可以概括rpc的一些通用原理:

Java編程良心推薦——分布式架構原理解析

細化了下:

Java編程良心推薦——分布式架構原理解析
  1. rpc層:底層的通訊框架,通訊協議,序列化和反序列化;
  2. 服務發布訂閱;
  3. 服務治理;

功能

Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析

性能

Java編程良心推薦——分布式架構原理解析

可靠性

Java編程良心推薦——分布式架構原理解析

分布式的,面試會問,用池子的話講就是,知識點啊。

服務治理

Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析

通訊框架

技術點

  1. 長連接:主要是鏈路的創建過程到最後的關閉,耗時耗資源;每次調用都要創建的話,調用時延的問題,很可能鏈路創建的耗時比代碼真正執行時長還多;
  2. BIO還是NIO:主要是線程模型的選擇,推薦篇文章 IO – 同步,異步,阻塞,非阻塞 (亡羊補牢篇);
  3. 自研還是使用開源NIO框架:一般來說還是使用開源吧,技術成熟,社區支持,現在netty和mina使用較多了吧。
Java編程良心推薦——分布式架構原理解析

在功能設計方面,作者基於netty給了demo服務端和客戶端的代碼,個人理解:

1. 通用性api;

2. 擴展性,封裝底層,提供上層接口,隔離協議和底層通訊;

可靠性設計

談分布式系統必談可靠性。

鏈路有效性

通過心跳來確認雙方c、s存活,保證鏈路可用,心跳檢測機制分為3個層面:

1. tcp層面,即tcp的keep-alive,作用於整個tcp協議棧;

2. 協議層的心跳檢測,主要存在於長連接協議中,例如smpp協議;

3. 應用層的心跳,業務雙方的定時發送心跳消息;

第2個沒聽說過,常用的是1,3。一般使用netty的話用的是netty的讀寫空閑來實現心跳。

斷連

不管因為網絡掛了還是服務端宕機,還是心跳超時什麼的,導致鏈路不可用關閉,這時候就需要鏈路重連,需要注意的一點就是短連後,不要立即重連,留時間給系統釋放資源,可以scheduler處理。

消息緩存重發

底層消息不會立即發送(也會導致半包粘包),斷鏈後,導致消息丟失,看有無業務需求,有就支持斷鏈後消息重發。

資源釋放

主要是斷鏈後,一定要保證資源銷毀和釋放,當然也包括一些線程池,內存等的釋放。

性能設計

性能差的三宗罪

對於底層通訊框架來說,主要是下面幾個:

1. 通訊模型的選擇,主要是阻塞非阻塞那些東西;

2. 序列化反序列化(後面有章單講序列化);

3. 線程模型,主要是服務端選擇什麼樣的線程模型來處理消息。

通信性能三原則

既然有上面的3個問題,那就針對這些做優化了:

  1. 傳輸:BIONIOAIO的選擇;
  2. 選擇自定義協議棧,便於優化;
  3. 服務端線程模型,單線程處理還是線程池,線程池是一個,還是分優先級,Reactor還是其他什麼的。

高性能之道這節作者講了netty的優勢。

序列化與反序列化

也就是通常所說的編碼、解碼。通常的通訊框架會提供編解碼的接口,也會內置一些常用的序列化反序列化工具支持。

與通訊框架和協議的關係,感覺可以理解為:通訊框架是通道,其上跑的碼流數據是利用各種序列化編碼後的各種協議。

功能設計

各種序列化框架需要考慮的主要有:

  • 序列化框架本身的功能的豐富,支持的數據類型;
  • 多語言的支持;
  • 兼容性,往大了說:
  1. 服務接口的前後兼容;
  2. 協議的兼容;
  3. 支持的數據類型的兼容。
  • 性能,目的是最少的資源,最快的速度,最大的壓縮:
  1. 序列化後碼流大小;
  2. 序列化的速度;
  3. 序列化的資源佔用。

在擴展性這節,作者講了netty的對序列化的一些內置支持,但實際開發中,一般不太會使用這些東西,都會提供序列化反序列接口,自行擴展定義,所以擴展性特重要。

常用的序列化,xml,json,hessian,kryo,pb,ps,看需求需要支持那種,具體可以搜索各序列化的性能和壓縮後大小。

協議棧

這一章最主要的是講了自定義協議棧的設計,已經交互的過程,其他講的可靠性設計什麼的跟之前通訊框架一章有重複。

通信模型

Java編程良心推薦——分布式架構原理解析

服務提供者和消費者之間採用單鏈路,長連接通信,鏈路創建流程:

1. 客戶端發送握手請求,攜帶節點ID等認證信息;

2. 服務端校驗:節點ID有效性,重複登錄,ip地址黑白名單等,通過後,返回握手應答信息;

3. 鏈路建立後,客戶端發送業務消息;

4. 客戶端服務端心跳維持鏈路;

5. 服務端退出時,關閉連接,客戶端感知連接關閉,關閉客戶端連接。

協議消息定義

Java編程良心推薦——分布式架構原理解析
Java編程良心推薦——分布式架構原理解析

通過attachment兼容了擴展性。作者還講了將消息頭的通用序列化和消息體的自定義序列化,看需求吧,我們公司的框架沒做這部分支持,做了簡化,將消息頭和消息體統一封裝,然後再加一個序列化方式組成一條消息發送。

安全性設計

  1. 內部的,不一定需要認證,也有基於系統,域名,ip的黑白名單,安全認證的;
  2. 外部開發平台的話,基於秘鑰認證;

服務路由

服務路由指的是服務提供者集群部署,消費端如何從服務列表中選擇合適的服務提供者提供服務進行調用。

透明化路由

  1. 基於zk的服務註冊中心的發布訂閱;
  2. 消費者本地緩存服務提供者列表,註冊中心宕機後,不影響已有的使用,只是影響新服務的註冊和老服務的下線。

負載均衡

  • 隨機
  • 輪循
  • 服務調用時延
  • 一致性Hash
  1. 有個一致性hash算法,挺有意思的,redis的客戶端shard用的
Java編程良心推薦——分布式架構原理解析
  • 黏滯連接
  1. 這個應該不太常用,服務提供者多數無狀態,一旦有狀態,不利於擴展

這些都是點對點的連接,負載均衡大多會在客戶端執行,有種場景會取決於服務端負載,就是服務端服務配置的是域名。

本地路由優先策略

  • injvm:jvm也提供了消費端的服務,可以改成優先本jvm,對於消費端來說,不需關注提供者;
  • innative:injvm比較少,多得是可能是這種,一個物理機部署多個虛擬機,或者一個容器部署多個服務提供者,消費者不需遠程調用,本機,本地或本機房優先。

路由規則

除了上面提供的各種路由負載均衡,還容許自定義路由規則:

– 條件路由:主要是通過條件表達式來實現;

– 腳本路由:通過腳本解析實現。

其實應該還有一種客戶端通過代碼自定義路由選擇。這些主要是為了擴展性。

路由策略定製

自定義路由場景:

1. 灰度;

2. 引流;

路由策略:

1. 框架提供接口擴展;

2. 配置平台提供路由腳本配置;

配置化路由

  1. 本地配置:包括服務提供者和消費者,全局配置3種;
  2. 註冊中心:路由策略統一註冊到服務註冊中心,集中化管理;
  3. 動態下發:配置後動態下發各服務消費端。

集群容錯

指的是服務調用失敗後,根據容錯策略進行自動容錯處理。

集群容錯場景

  • 通信鏈路故障:
  1. 通信過程中,對方宕機導致鏈路中斷;
  2. 解碼失敗等原因Rest掉鏈接;
  3. 消費者read-write socketchannel發生IOException導致鏈路中斷;
  4. 網絡閃斷故障;
  5. 交換機異常導致鏈路中斷;
  6. 長時間Full GC導致;
  • 服務端超時:
  1. 服務端沒有及時從網絡讀取客戶端請求消息,導致消息阻塞;
  2. 服務端業務處理超時;
  3. 服務端長時間Full GC;
  • 服務端調用失敗:
  1. 服務端解碼失敗;
  2. 服務端流控;
  3. 服務端隊列積壓;
  4. 訪問權限校驗失敗;
  5. 違反SLA策略;
  6. 其他系統異常;

業務執行異常不屬於服務端異常。

容錯策略

Java編程良心推薦——分布式架構原理解析

這圖不錯,關係很清晰。

  • 失敗自動切換(Failover):
  1. 調用失敗後切換鏈路調用;
  2. 服務提供者的防重;
  3. 重試次數和超時時間的設置。
  • 失敗通知(FailBack):失敗後直接返回,由消費端自行處理;
  • 失敗緩存(Failcache):主要是失敗後,緩存重試重發,注意:
  1. 緩存時間、緩存數量;
  2. 緩存淘汰算法;
  3. 定時重試的周期T、重試次數;
  • 快速失敗(Failfast):失敗不處理,記錄日誌分析,可用於大促期間,對非核心業務的容錯。

容錯策略擴展

  1. 容錯接口的開放;
  2. 屏蔽底層細節,用戶自定義;
  3. 支持擴展。

其實還有一點,感覺也挺重要,就是支持容錯後本地mcok。調用失敗後的鏈路切換和快速失敗肯定要支持,緩存重發可以不用。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/251130.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-13 17:21
下一篇 2024-12-13 17:21

相關推薦

發表回復

登錄後才能評論