使用分散式Actor實現微服務
juptr.io是一個內容個性化、分享和創作平臺。透過抓取成千上萬的部落格和媒體網站(德語與英語),對這些內容進行分類,更易於個性化的內容管理、消費與討論。
這就要求:
1.抓取,儲存,查詢,分析和分類數以百萬計的檔案
2.橫向擴充套件
3.故障容錯的分散式服務架構(微)
4.java,JavaScript的互操作性
使用以下基礎棧:
1.java 8為後臺,分析和自然語言處理
2.JavaScript polymer.js在前端
3.NoSQL水平可伸縮的DataGrid用來去實現永續性和大資料分析/ NLP
當實現一個遠端服務,即使是簡單的應用程式邏輯也變得複雜。
構建分散式系統需要一些樣板構建等工作,比如定義通訊訊息和不斷更新的資料格式。
服務實現主要集中在程式碼預處理,以及從通訊訊息複製到內部資料結構的轉換上。通訊最頻繁的型別諸如httpx,TCP/IP,WebSockets會根據作業系統不同有所限制。
服務連線到這個註冊器並訂閱的程式碼:
這就要求:
1.抓取,儲存,查詢,分析和分類數以百萬計的檔案
2.橫向擴充套件
3.故障容錯的分散式服務架構(微)
4.java,JavaScript的互操作性
使用以下基礎棧:
1.java 8為後臺,分析和自然語言處理
2.JavaScript polymer.js在前端
3.NoSQL水平可伸縮的DataGrid用來去實現永續性和大資料分析/ NLP
當實現一個遠端服務,即使是簡單的應用程式邏輯也變得複雜。
構建分散式系統需要一些樣板構建等工作,比如定義通訊訊息和不斷更新的資料格式。
服務實現主要集中在程式碼預處理,以及從通訊訊息複製到內部資料結構的轉換上。通訊最頻繁的型別諸如httpx,TCP/IP,WebSockets會根據作業系統不同有所限制。
分散式Actor
為了實現分散式程式設計的生產化,我們需要:
1.抽象出網路傳輸邊界的基礎框架
2.完全自動化的通訊訊息編碼/解碼。
3.在編譯時間捕捉通訊協議不相容的改變
4.透明的流stream
5.Lambda表示式的遠端執行。
好處:
1.簡單事情簡單解決,ServiceRegistry註冊服務只用不到100行的程式碼含括服務健康檢查,可用狀態改變廣播和中央配置管理,見下面程式碼。
2.無縫銜接Java和Javascript
3.訊息只需很少努力就能臨時持久化,測試時或失敗或複製時時重放。
4.sharding分片簡單透過訊息路由邏輯實現
5. 遠端 lambda執行能夠方便且高效能分佈資料處理。
6. 高開發生產性。
下面是註冊服務的程式碼:
public class Gravity extends Actor<Gravity> { HashMap<String, List<ServiceDescription>> services = new HashMap<>(); List<Callback> listeners = new ArrayList<>(); JuptrCfg config; @Local public void init() { config = JuptrCfg.read(); checkTimeout(); // start cycle } public void registerService( ServiceDescription desc ) { List<ServiceDescription> serviceList = getServiceList(desc.getName()); serviceList.add(desc); desc.receiveHeartbeat(); if (serviceList.size()==1) broadcastAvailable(desc); } public IPromise<Map<String,ServiceDescription>> getServiceMap() { HashMap<String,ServiceDescription> servMap = new HashMap<>(); services.forEach((name, list) -> { if (list.size() > 0) servMap.put(name, list.get(0)); }); return resolve(servMap); } public void subscribe( Callback<Pair<String,ServiceDescription>> cb ) { listeners.add(cb); } protected void broadcastAvailable(ServiceDescription desc) { Pair msg = new Pair(AVAILABLE,desc); listeners.forEach( cb -> { try { cb.stream(msg); } catch (Throwable th) { Log.Info(this, th); } }); } protected void broadCastTimeOut(ServiceDescription desc) { Pair msg = new Pair(TIMEOUT,desc); for (int i = 0; i < listeners.size(); i++) { Callback cb = listeners.get(i); try { cb.stream(msg); } catch (Throwable th) { Log.Info(this, th); listeners.remove(i); i--; } } } public IPromise<JuptrCfg> getConfig() { return resolve(config); } public void receiveHeartbeat( String serviceName, String uniqueKey ) { getServiceList(serviceName).forEach(sdesc -> { if (sdesc.getUniqueKey().equals(uniqueKey)) { sdesc.receiveHeartbeat(); } }); } @Local public void checkTimeout() { services.values().forEach( list -> { int prevsiz = list.size(); for (int i = 0; i < list.size(); i++) { ServiceDescription serviceDescription = list.get(i); if ( serviceDescription.hasTimedOut() ) { list.remove(i); i--; broadCastTimeOut(serviceDescription); } } // if a service timed out, but there is a replacement, // broadcast availability if ( prevsiz != list.size() && list.size() > 0 ) { broadcastAvailable(list.get(0)); } }); if ( ! isStopped() ) { delayed(1000, () -> checkTimeout()); } } protected List<ServiceDescription> getServiceList(String serviceName) { List<ServiceDescription> slist = services.get(serviceName); if ( slist == null ) { slist = new ArrayList<>(); services.put(serviceName, slist); } return slist; } public static void main(String[] args) { Gravity gravity = Actors.AsActor(Gravity.class); gravity.init(); // publish new TCPNIOPublisher(gravity,options.getGravityPort()).publish(actor -> { Log.Info(null, actor + " has disconnected"); }); // log service activity gravity.subscribe((pair, err) -> { Log.Info(gravity.getClass(), pair.car() + " " + pair.cdr()); }); } } <p class="indent"> |
服務連線到這個註冊器並訂閱的程式碼:
ConnectableActor gravity = new TCPConnectable(Gravity.class, host, port ); gravity = (Gravity) gravityConnectable.connect((conn, err) -> { gravityDisconnected(conn,err); }).await(); // make this service available to all cluster members gravity.registerService(getServiceDescription()); // listen to events emitted by gravity gravity.subscribe( (pair, err) -> serviceEvent(pair.car(), pair.cdr(), err) ); <p class="indent"> |
相關文章
- [開源] Golang 實現的分散式 WebSocket 微服務Golang分散式Web微服務
- go-zero微服務實戰系列(十、分散式事務如何實現)Go微服務分散式
- 分散式與微服務分散式微服務
- 微服務架構 | 11.1 整合 Seata AT 模式實現分散式事務微服務架構模式分散式
- 微服務實踐之分散式定時任務微服務分散式
- 使用JOTM實現分散式事務的例子分散式
- 使用Spring Boot實現分散式事務Spring Boot分散式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- PHP 微服務之【分散式事務】PHP微服務分散式
- PHP 微服務之 [分散式事務]PHP微服務分散式
- 微服務架構中分散式事務實現方案怎樣何取捨微服務架構分散式
- Java開發微服務實現分散式架構應用總結Java微服務分散式架構
- 微服務之分散式配置中心微服務分散式
- 微服務分散式企業框架微服務分散式框架
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 微服務分散式事務4種解決方案實戰微服務分散式
- 微服務分散式事務元件 Seata(一)微服務分散式元件
- 微服務分散式事務Saga框架微服務分散式框架
- 分散式檔案上傳(微服務)分散式微服務
- 分散式、微服務、叢集,個人理解分散式微服務
- 基於微服務框架Micronaut和Eventuate Tram實現分散式事務的開源案例微服務框架分散式
- 微服務架構 | 11. 分散式事務微服務架構分散式
- 分散式政企應用如何快速實現雲原生的微服務架構改造分散式微服務架構
- 使用 Redis 實現分散式鎖Redis分散式
- 使用CRDT實現分散式事務的資料推薦分散式
- node.js 中使用redis實現分散式事務鎖Node.jsRedis分散式
- spring cloud微服務分散式雲架構--hystrix的使用SpringCloud微服務分散式架構
- 深度解析spring cloud分散式微服務的實現SpringCloud分散式微服務
- 基於RocketMQ實現分散式事務MQ分散式
- PHP 微服務之 [分散式事務] 閱讀提示PHP微服務分散式
- PHP 微服務之【分散式事務】閱讀提示PHP微服務分散式
- 微服務架構分散式事務管理問題微服務架構分散式
- 比較微服務中的分散式事務模式微服務分散式模式
- 微服務的分散式事務模式比較 | RedHat微服務分散式模式Redhat
- 微服務架構下分散式session管理微服務架構分散式Session
- 微服務分散式架構之redis篇微服務分散式架構Redis
- 架構解密:從分散式到微服務架構解密分散式微服務
- 微服務開發的意義 微服務與分散式的關係微服務分散式