淺談SOA

概念

wiki對於SOA定義以下:java

A service-oriented architecture (SOA) is a design pattern in which application components provide services to other components via a communications protocol, typically over a network. The principles of service-orientation are independent of any vendor, product or technologylinux

從定義上看,能夠總結出SOA軟件架構模式的幾個特色:算法

  1. 面向服務劃分系統--將龐大的業務系統拆分紅高內聚的服務單元,每一個單元對外提供服務服務能力,服務與服務之間經過相互協做共同實現業務價值
  2. 鬆耦合---SOA框架中能夠應用多種技術,服務消費方不依賴於服務提供者的技術實現(好比Java服務提供方,Python服務消費者)。雙方能夠經過thrift, proto-buffer或者消息隊列等框架來實現消息的互通。
  3. 系統的可靠性依賴外部網絡特質---傳統的單進程系統拆分紅多進程系統之間的相互協做,進程之間經過RPC進行通訊,增長了網絡開銷。

SOA系統中,最基礎的單元是服務,那麼什麼是服務呢?
Service Is a logical representation of a repeatable business activity that has a specified outcome (e.g., check customer credit, provide weather data, consolidate drilling reports). 從定義上看,服務是對業務活動的邏輯表達。服務能力一般使用API接口來進行抽象,造成所謂的"契約",外部模塊經過遵循契約來得到相應的能力。緩存

概念說完了,那麼來聊聊如何去構建一個SOA框架。構建SOA框架須要考慮下面幾個要點服務器

  1. 服務註冊/發現
  2. 負載均衡:使用合理的框架或是算法實現流量均勻的負載到集羣節點上
  3. Heatbeat
  4. 服務監控(Metric, 熔斷機制(好比: 過去一分鐘,http調用失敗率超過60%,斷定服務不可用,移出或打標籤))
  5. RPC框架

服務註冊/發現

服務註冊/發現是實現SOA的重中之重,負載均衡、Heatbeat都是基於這一基礎實現的。咱們能夠經過使用zookeeper來實現服務的註冊和發現。zookeeper wiki給出的定義以下:網絡

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.架構

從定義上看zookeeper可以:app

  1. 做爲配置信息的存儲服務器
  2. 命名服務
  3. 分佈式的協調服務

除此以外zookeeper具備其餘一些特色:負載均衡

  1. 奇數個服務節點(和leader選舉算法有關)
  2. 提供多種語言的API
  3. 技術比較成熟
  4. 使用linux文件存儲結構,樹狀組織
  5. 使用watch機制push數據節點變動消息

主要使用zookeeper的命名服務去實現服務中心的功能,服務註冊/發現的架構以下所示:框架

在此架構中有三種角色: 服務提供者,服務註冊中心,服務消費者:

  1. 服務提供者註冊本身的服務,註冊信息包含系統信息,服務名稱,服務的ip和端口號,服務請求的url, 服務的權重等
  2. 註冊中心提供註冊服務的中心存儲,和向服務消費者push服務變動通知
  3. 服務消費者在啓動時獲取所需服務註冊信息(根據系統名稱+服務名稱),將服務註冊信息緩存在本地,監聽服務信息的變動,更新本地的緩存。服務消費者根據本地緩存的服務提供者信息負載,來轉發請求。對服務提供方提供心跳檢測。

心跳檢測

心跳是檢驗服務是否可用必不可少的服務,若是出現問題,將該服務提供者從該服務的提供者列表中移除;反之,則加入到服務的提供者列表中。Heatbeat實現原理比較簡單,啓動後臺線程按期的向provier發送http請求,屢次連續失敗將Provider從調度列表中移出。

負載均衡

負載能夠經過兩種方式實現,一種是經過硬件分流,簡單方便,不過成本較高;
另外一種方式是採用軟負載,軟負載的兩種方式:

a,中心控制-軟負載服務器。全局視角,能夠得出全局最優解。可是有單點問題存在。方式

b,客戶端控制—客戶端本身選擇特定的service的provider,經過收集provider相關的信息,按照可選的一系列選擇算法,進行工做。好處是更加貼近consumer,可以作出針對於本機的個性化選擇;問題是,每一個選擇都是針對一個consumer進行的,consumer之間互相不知情,容易致使選擇衝突(eg,兩個provider a和b,若是在某一特定時刻,全部的consumer都指定了a,致使a的服務質量較差,全部的consumer感知到這一狀況,按照通常算法都會將下一次的請求發給b,此時,全部的請求都積壓在b端,致使b的服務質量較差;而後,下一次又會同時指向a。形成了網絡的震盪和服務資源的浪費)

下面介紹一種簡單的輪詢算法,JAVA實現以下所示:

ServiceInstanceManager---維護ServiceInstance實例類

private final AtomicInteger counter = new AtomicInteger(0);

public String getUrl(){
    List list = this.manager.getAvailableProviders();
    if(list != null && !list.isEmpty()) {
        int tmpCount = this.counter.getAndIncrement();
        int index = tmpCount % list.size();
        index = index >= 0 ? index:index + list.size();
        String url = (String)list.get(index);
        logger.debug("Service({}), invoke counter({}), url({})!", new Object[]{this.service, Integer.valueOf(tmpCount), url});
        return url;
    } else {
        throw new LoadBalanceException(String.format("Service(%s) has no available provider!", new Object[]{this.service}));
    }
}

RPC

RPC—Remote Procedure Call Protocol,是應用實現進程間調用的一種經常使用手段。經過指定服務對外的IP地址和端口id,本地計算機可以訪問到遠端機器的資源。經常使用的RPC框架包括Java RMI, thrift, Google protobuf等。用戶在選擇不一樣的RPC框架能夠從序列化,性能,語言支持幾個方面去考慮,好比Java RMI只能在java生態圈中使用,沒法對接其餘語言提供的RPC服務,而thrift在語言支持方面就至關全面,經過編寫thrift描述接口文檔,能夠實現不一樣程序之間的調用。

相關文章
相關標籤/搜索