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軟件架構模式的幾個特色:算法
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框架須要考慮下面幾個要點服務器
服務註冊/發現是實現SOA的重中之重,負載均衡、Heatbeat都是基於這一基礎實現的。咱們能夠經過使用zookeeper來實現服務的註冊和發現。zookeeper wiki給出的定義以下:網絡
ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.架構
從定義上看zookeeper可以:app
除此以外zookeeper具備其餘一些特色:負載均衡
主要使用zookeeper的命名服務去實現服務中心的功能,服務註冊/發現的架構以下所示:框架
在此架構中有三種角色: 服務提供者,服務註冊中心,服務消費者:
心跳是檢驗服務是否可用必不可少的服務,若是出現問題,將該服務提供者從該服務的提供者列表中移除;反之,則加入到服務的提供者列表中。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—Remote Procedure Call Protocol,是應用實現進程間調用的一種經常使用手段。經過指定服務對外的IP地址和端口id,本地計算機可以訪問到遠端機器的資源。經常使用的RPC框架包括Java RMI, thrift, Google protobuf等。用戶在選擇不一樣的RPC框架能夠從序列化,性能,語言支持幾個方面去考慮,好比Java RMI只能在java生態圈中使用,沒法對接其餘語言提供的RPC服務,而thrift在語言支持方面就至關全面,經過編寫thrift描述接口文檔,能夠實現不一樣程序之間的調用。