2015-10-09 28 views
0

我正在看微服務,以及將我們的一些代碼遷移到此體系結構的可能性。我瞭解一般概念,但正在努力研究它如何爲我們的例子起作用。如何將Java界面遷移到微服務?

假設我有一個名爲RatingEngine的接口和一個名爲RatingEngineImpl的實現,它們都在我的單片應用程序中運行。原理很簡單 - RatingEngineImpl可以運行在不同的機器上,並且可以通過(比方說)一個REST API通過單片應用程序訪問,並通過http使用json序列化DTO。我們甚至有一個界面來幫助解耦。

但我怎麼真的去做這件事?據我所見,我需要爲rump monolith(即現在的客戶端)創建一個新的接口實現,該接口調用接口方法,將它們轉換爲REST調用,並通過網絡將它們發送到新的'評級引擎服務'。然後,我還需要實現一個新的http服務器,每個接口方法都有一個端點,然後對DTO進行反序列化(方法參數)並將呼叫路由到位於服務器內部的原始RatingEngineImpl。然後它將響應序列化並將其發送回客戶端。

因此,這似乎是一個可怕的很多管道代碼。它還增加了維護開銷,因爲如果您在界面中調整方法,則需要在另外兩處進行更改。

我錯過了什麼嗎?有沒有一些聰明的方法可以使這種樣板代碼構建自動化?

回答

1

不,不幸的是,你不會錯過任何實質性的東西。微服務架構自帶成本。引起你注意的一個(樣板代碼)是列表中的一個衆所周知的項目。 This是Martin Fowler的一篇很好的文章,解釋了這個想法的各種優缺點。它包括像主題:

  • 增加了複雜性
  • 提高了運營成本 - 維持
  • 鬥爭,以保持一致性(同時允許特殊情況下,在特殊的方式處理)

...等等更多。

+0

我聽說,你可以採用彈簧和/或RestEasy的神奇地處理一些吧你... – mdarwin

+0

有專爲使您的生活中的許多工具* *更容易(用於部署,監控的巧妙功能,溝通等),但他們不會爲你做出難題。要有效採用這種技術,主要先決條件是在工具中具有一定的成熟度。從平臺虛擬化到REST服務體驗。如果你正在尋找特定的工具,你需要深入調查你的需求。 –

0

有一些框架可以減少這樣的樣板代碼。我在當前項目中使用Spring Boot(儘管不適用於微服務)。如果你已經有了基於Spring的項目,那麼它真的簡化了微服務(或基於Spring的其他非微服務應用程序)的開發。結帳的一些例子:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples

+0

我們的代碼目前沒有彈簧。但是如果我理解正確的話,你可以註解界面,實現或者兩者,並且spring啓動會神奇地監聽http,反序列化DTO,並且在實現中將調用路由到正確的方法。你能指點我一個成功的例子嗎? – mdarwin

+0

*「[,..]和春季啓動會奇蹟般地收聽http,反序列化DTO,並將呼叫路由到[*]」* - 我們應該將它放在Java開發人員的聖誕願望清單中:http:/ /www.javalobby.org/java/forums/t84854.html –

2

微服務模式並不建議你移動每個服務,你必須它自己可部署。只有移動自我維持的邏輯,才能從它自己的發佈週期中受益。即如果您的RatingEngine需要每週評級邏輯更新,但其他系統都相當穩定 - 它可能會受益於它自己的服務。

是的 - 微服務增加了複雜性,但並不是真正的HTTP服務器的鍋爐代碼。有很多框架來解決這個問題。 Vert.x是一個很好的。其他的是Spring Boot,Apache Camel等等。一個完整的微服務安裝可以像Vert.x一樣。

public class RatingService extends AbstractVerticle implements RatingEngine{ 
    public void start() { 
    vertx.createHttpServer().requestHandler(req -> { 
     req.response() 
     .putHeader("content-type", "application/json") 
     .end(computeCurrentRating().encodePrettily()); 
    }).listen(8080); 
    } 

    @Override 
    public int getRating(){ 
   return 4; // or whatever. 
    } 

    protected JsonObject computeCurrentRating(){ 
    return new JsonObject().put("rating", getRating()); 
    } 
} 

即使是Java內置框架JAX-RS也可以在不太多的代碼行中進行微服務。

微服務的真正努力工作是在客戶端添加錯誤處理邏輯。你可以處理它 - 如果調用RatingService給出拒絕連接異常的一些常見的陷阱

  • 微服務可能會下降?您能否估計客戶端的「評級」以防止進一步處理?您是否可以重複使用舊的回覆來評估評分? ..或者至少 - 你需要發出錯誤信號來支持員工。

  • Reactive app?你能等多長時間?對內存方法的調用將在納秒內返回,對外部HTTP服務的調用可能需要數秒或數分鐘,具體取決於多種因素。只要應用程序是「被動的」,並且可以在沒有「評級」的情況下繼續工作 - 並且在用戶可用時提供評級 - 那沒問題。如果您正在等待阻止呼叫評級服務,超過幾毫秒。 - 響應時間成爲障礙。在Java中創建被動應用程序並不像在node.js中那樣方便/常見。被動的方法可能會觸發整個系統的重製。

  • 容忍客戶端單元/集成測試單個項目很容易。測試一個複雜的微服務網絡不是。你可以做的最好的事情是讓你的客戶電話不太挑剔。模式驗證等實際上是不好的事情。在XML中,使用單個XPath從響應中獲取所需的數據,而不是更少。這樣,微服務響應中的更改將不需要更新所有客戶端。在這方面JSON比XML更容易處理。

+0

Tak Petter的詳細回覆。我現有的java界面適合哪裏?示例類是否也實現了'RatingEngine'?或者計算方法是否簡單地委託給'RatingEngineImpl'? – mdarwin

+0

嗯..好吧,我真的不會試圖去適應界面。客戶端可能甚至沒有Java接口的標記,因爲微服務架構建議您可以混合和匹配任何語言/平臺。 「接口」將是一些json或XML消息。但是,當然,您可以直接在服務中實現該接口。我已經更新了這個例子。在許多框架中,可以通過簡單的方法在java中調用「透明」。即客戶端在普通接口中調用一個方法,並將其代理到一些HTTP休息調用。這有點OT,但檢查vert.x等。 –