假設一個ProductSpeed有兩個不同的構造器:
public class ProductSpeed {
public ProductSpeed(String name) {
...
}
public ProductSpeed(String name, int order)) {
}
}
第一個構造器是使用在不相關的産品的訂單中。
第二個構造器是我們關注的,因為我們在向使用者顯示這些産品時首先進行一下排序。
産生這兩個構造器的原因是:這個對象可能産生于兩個不同的系統,隻是在一個系統中有排序要求存在,而另外一個沒有這個要求。
我們實際做的是一個對象兩個不同的版本,但是我們不能取名為:ProductSpeedForSystem1′ 和 ‘ProductSpeedForSystem2′!
在領域驅動設計DDD中,我們可以認為ProductSpeed是存在兩個不同有界上下文中(共享核心),如果是在一個大型整塊系統中,它們是分别位于不同的包下面。
下面我們就要區分這兩個不同的上下文,進一步我們會發現以第二個構造函數建立的ProductSpeed對象其實和系統其他應用并沒有互動,隻是為用戶端排序而存在,直接服務于用戶端,向外服務,而不是向内部元件提供互動(向内不能稱為"服務"了),是以這個獨立的上下文可以成為一個微服務。
原來我們是通過一個整塊API提供所有功能,如下圖的Main API:
将上下文區分開以後,微服務可以從原來整塊上下文獨立出來了:
微服務定義:
每個應用程式都隻做一件事
•足夠小,适合存在你的腦袋即可。
- “如果一個類大到我腦袋記不住就是實在太大“
•足夠小,你可以把它們扔掉
- 用重寫來維護
微服務類似Unix的服務:
1. 嵌入了Web容器(以往JavaEE都是服務運作在tomcat等Web容器中)
– 比如可以使用Jetty / SimpleMind
– 測試(測試甚至不重要)和易部署,脫離容器,直接是一個應用,無需那麼多Mock了。
2.打包成單個可執行的jar包
– 有自己獨立的配置
– 标準的unix rc.d 腳本
3. 可以以類似Unix背景啟動Httpd服務方式等啟動
– Unix的背景守護 Daemons看樣子工作這麼多年很好,除非你有特殊需求,否則不要重複發明輪子。
4. 每個應用都是獨立分離的,符合領域驅動設計和Conways法則的有界上下文,使用實體的實作真正分離他們。
5.如果有共同的代碼,将其成為一個底層設施的庫包。
–對待它們就像對待其他開源庫包項目一樣。
–可以将其送出到Maven中央倉庫,作為一個二進制依賴包。
6. 能夠自給自足Provisioned。
許多小應用程式的複雜性管理之道是在于讓它們自我管理。比如ServiceA和ServiceB自己實作負載平衡和自動擴充,資料庫自己實作叢集。
7. 用看門狗來堅持應用的狀态,類似Scala的Actor模型,如果有失敗,自動重新開機它們。每個應用都要向外暴露它們的運作情況,以便監視。