微服務框架lagom

1.Lagom概念介紹html

lagom框架包含一系列的能夠支持咱們從開發到部署的庫以及開發環境:
>在開發階段,能夠經過一個簡單的命令構建咱們的項目,啓動全部你的服務,而且能夠支持全部的lagom基礎設置層。當你修改了代碼,logom是有熱加載的。開發環境可讓你在幾分鐘內添加進一個新的服務或者加入一個現有的lagom開發團隊
>你可使用java或者scala建立微服務。Lagom爲服務通訊提供了一個特別的的無縫體驗。服務定位,通訊協議以及其餘的問題都被Lagom處理掉了,提供了方便和效率。同時,Lagom對於持久化是支持ES(事件源)和CQRS(命令查詢職責分離)的。
>在任意你選擇的平臺上部署。爲了簡化部署,Lagom有不少能夠開箱機用的產品組件,好比Application Monitoring(監控的)。這些產品組件提供了一種在容器環境中的簡單的方式來部署,測量,監控和管理Logam服務

設計一個達到高伸縮和麪對意想不到的失敗具備彈性微服務系統是機器苦難的,若是沒有Lagom這樣的框架,你須要去處理在高度的分佈式系統中全部複雜的線程和併發的問題,你是能夠避免這些缺陷,同時提升工做效率的。Logam容許你在現有的約束下采用響應式架構。例如你能夠想下面這樣建立微服務:
 >與遺留系統/或者替換程序的總體功能
 >使用Cassandra或者你本身選擇的數據庫和/或與其餘數據存儲集成

2.Lagom設計理念java

考慮由Jonas Bonér提出的響應式微服務的一些基礎的需求:
>隔離是彈性和靈活力的先決條件而且服務邊界之間的消息通信是異步
>自主服務經過發佈它的協議/API只能保證本身的行爲。服務須要可被尋址的,它應該是位置透明的
>如今須要的是,每個微服務都爲本身的狀態和持久化負責
以下的這些特性,促進這些最佳實踐:
>lagom默認是異步的---他的API讓服務間通訊經過一流的流的概念。全部的Lagom API爲了異步的流而使用AKKA Stream的異步的IO能力;java API使用jdk1.8的CompletionStage來處理異步計算;scala使用Future
>與傳統的中央管理的數據庫對比,Lagom傾向分佈式的持久化模式。咱們鼓勵--但不是必須--事件源的架構來持久化。Lagom的默認的持久化實體的模式是採用ES(事件源)與CQRE結合的方式。爲何事件源那麼重要呢,下面單獨解釋下:
    ES管理數據持久化:
    當咱們設計微服務時候,須要記住每個微服務都應該有本身的數據和直連的數據庫,其餘的服務使用服務API於數據進行交互。可是這裏不能在不一樣的服務間共享數據庫,由於這會致使服務
    之間的緊耦合。
    在這種狀況下,每個微服務定義一個限界上下文,相似於DDD領域驅動的限界上下文。
    爲了實現解耦的架構,Lagom的持久化促進了ES和CQRS的使用。事件源是捕獲全部的改變當作領域事件的實踐,即已經發生的不可改變的事實。舉例,在一個使用ES的系統中,當Mike從他的銀
    行帳戶中取出錢,那個事件就能夠被簡單存儲爲「¥100.00 取款」,而不是在CRUD程序中的複雜的相互做用。若是使用CRUD,那麼在包裝的事務務提交以前,可能會發生各類各樣的查詢和修改
    操做事件源ES被用於聚合根,就像是攜帶有用戶標識的用戶-Mike同樣。寫的一端徹底的約束在聚合中。這就使得很容易去思考維持不變性和驗證傳入的命令。可是有一點不一樣須要注意,當聚
    合能夠回覆經過特定的標識符查詢時候時候能夠採用這個模型,可是它不能用於服務跨多個聚合的查詢。所以,你須要根據查詢服務提定製化的數據視圖。
    lagom持久化事件流進入數據庫中,事件流處理器,其餘服務或者客戶端,讀或者可選擇的,執行,存儲時間。lagom支持persistent read-side processors(讀端持久化處理器)和
    message broker topic subscribers(消息代理主題訂閱者),你固然能夠經過raw stream of events(原生事件流)建立你本身的事件流處理器。
    若是你不想使用事件源ES和CQRS,那麼你也可使用其餘的在Lagom中的持久化模塊。若是您選擇不使用Lagom持久模塊,Lagom的持久化模塊CassandraSession提供了一個異步的API去存儲
    數據進Cassandra.可是你您能夠實現您的Lagom服務與任何數據存儲解決方案
    
    你應該選擇使用其餘比Lagom持久化模塊,記得使用異步api來實現最好的可伸縮性。若是您正在使用阻塞api,這樣JDBC、JPA,你應該仔細管理阻塞用專用的線程池的固定/有限大小的組件調用
    這些阻塞api。不要經過幾個異步的調用來串聯阻塞,例如服務API調用。
>Lagom爲管理客戶端和服務端發現,提供了一個執行服務註冊和服務網關用於的內部設施的實現。能夠查看5.4 Registering and discovering services,有詳細介紹

3.在多語言系統中的Logamgit

Lagom並不期待你的系統中的每一個服務都是Lagon服務,畢竟,使用微服務的最大的優點,就是首先爲每一個微服務能夠選擇最適合的語言或者技術。Lagom的標準通訊協議習慣用法的和通用兼容設計驅
動的API讓它能夠在一個多種語言的系統工做的很好。
Lagom服務調用映將同步通訊射到標準HTTP,將流或者異步的消息映射到WebSockets。任何語言的框架支持這些協議的話,都是能夠很簡單的消費Logam服務,相反,Lagom服務能夠很容易跟任何暴露
REST API的服務交互。
一個Loagom服務的API指定了服務如何使用HTTP。REST服務調用被HTTP的URL和METHOD標識,而請求而和相應的頭部信息則是能夠自定義的。Lagom的信息是被序列化了的,默認下是用Json,使用
慣用的的一些映射庫來簡單的讓Json在線表現出來

4.開發環境概述github

經過maven或者sbt能夠很快的開發出Lagom項目。

5.Lagom構建基本思想web

若是作得好,採用活性microservice架構能夠大大提升開發組織的效率和速度。Lagom 提供靈活構建方法,支持我的及團隊的發展,而且能夠隨着時間的推移而發展。你能夠把你全部的微服務放在
當個maven項目中,每個服務均可以被分開構建,或者構建多個服務構成的一個組。
下面是咱們須要開率的一些利弊:
    >單獨構建多服務:(單一版本)
        >開發新功能每每須要同時處理多個服務.讓那些服務在相同的構建中無衝突的開發體驗。
        >然而,隨着開發人員構建的數量增長,彼此之間會減緩開發效率
    >屢次構建,對於每一個服務管着一組小的服務(維護多個版本)
        >每一個微服務均可以獨立的改變而且被隔離開來開發的也會更快。在realise的時候,依賴的服務就能夠更新以使用更新後的新的服務
        >然而,多個版本增長了複雜度,您須要發佈服務讓他們對其餘服務是可用的。實現還須要導入在某版本下的特別的依賴。 Splitting a system into multiple builds講了如何
        解決這種麻煩
    在開始的時候,他一般在同一個構建中保持全部的服務是有意義的。
    好比當一個系統整處於功能開發階段,你能夠將服務拆分,分別構建。一樣的原則也適用於團隊工做。重要的是需求與構建要同步。

6.組件技術數據庫

做爲一個完整的微服務平臺,Lagom彙集了技術的集合並在他們之上添加價值,一些庫文件,工具,以及lagom使用和支持的服務器等都在Lightbend中很成熟了。其餘的第三方資源,當您在lagom框
架下開發,您還能夠利用這些技術:
>AKKA----Lagom的持久化,發佈訂閱和節點都是在AKKA基礎上實現的。Lightbend具備即時構建,分佈式和彈性的消息驅動程序的工具集
    >跨多個服務器擴展微服務,Lagom提供的AKKA Cluster能夠提供彙集
    >在實現服務描述,Lagom服務能夠很‘簡小’或者‘流式’,創建在AKKA strams之上Lagomm服務
>Cassandra 默認的持久化
>Guice 相似於playkuangjia,Lagom使用它完成依賴的注入
>play框架
>slf4j logback日誌
>Typesafe Config Library:Lagom和它的許多組件技術是使用類型安全配置庫配置
>序列化 jackson

7.API概述api

Lagom提供了java和scala的API。java版本的API是假定你已經熟悉了新特定,例如lambda和默認方法,和Optional接口等java1.8的知識。Lagom的絕大多數是用scala實現的,可是這些實現的
細節不是你應該關係你的,你應該知識專一於java的API開發。
Lagom提供的服務接口文檔讓開發者能夠快速的定義接口並當即實現他們。
你使用的那些重要的API包括:
    >"服務API":提供了一種方法來聲明和實現服務接口以供應客戶端使用。位置透明性,客戶發現服務經過服務定位器.服務API支持異步流媒體服務之間除了同步請求-響應調用
    >消息代理API:提供了能夠經過主題進行發現數據的分佈式的發佈訂閱模型。一個話題就是一個容許服務去push或者push數據的通道。
    >持久化:爲存儲數據的服務提供了事件源持久化實體。Lagom管理持久化實體的分佈在集羣節點,使得咱們能夠切分和水平擴展。lagom管理持久化實體的分佈在集羣節點,使得咱們能夠
    切分和水平擴展。Cassandra是做爲一個數據庫提供開箱即用的,但其餘數據庫也是支持的。

8.設計你的微服務系統瀏覽器

Bonér的響應式微服務架構這本書對於微服務系統架構頗有幫助。要想有處理複雜的領域的能力,是須要時間和經驗的。Lagom提供的API能夠爲你提供實用的指導。
咱們建議先從小開始,首先,肯定一個能夠消費異步消息的簡單的微服務需求,它不須要很複雜甚至提供了大量的屬性值。部署簡單能夠下降了風險,能夠快速的成功。而後,在架構層面,
拿出一個能夠劃分的核心服務,並把它劃分進微服務系統中,當大家一次一次的碰到問題處理問題,那麼你和你的團隊的開發效率會愈來愈高效。使用想DDD這樣的思想能夠幫助你能夠你的團隊
處理企業系統固有的複雜性

替換掉大塊系統
當設計一款微服務系統來替換掉一個大的系統時候,依賴於需求額和已存在的架構,你的方案可能各不相同。例如,若是它是很好很合理設計的,你首先可能不會與遺留組件進行鏈接,並在當前專一
於遷移功能。若是合理的停機時間是不被接受的,你須要仔細計劃,從舊系統中選擇可用的老的功能以用於新的服務中。
好比,設想一個爲多個部門處理核心業務功能的企業總體應用。他也許有被會計,打折,銷售和運營鎖使用的庫存功能----每一個模塊以不一樣的方式使用着它。DDD鼓勵這樣一個龐大而笨拙的模型分解
成有限的上下文。Each Bounded Context defines a boundary that applies to a particular team, addresses specific usage, and includes the data schema and physical 
elements necessary to materialize the system for that context.(實在不知道咋翻譯了)。限界上下文可讓一個小的團隊專一於在同一時間,並行的工做在一個上文中。
在第一個實現階段,你可能會修改從發佈會計部門感興趣的一個特定用例的庫存事件來開始修改這個龐然大物的老舊工程系統。下面的圖闡釋了咱們的系統發佈事件到Kafka中,kafka是一個指定
訂閱/發佈模式的流式平臺。而且kafka能夠做爲一個集羣運行,那樣能夠提供更好的性能和可靠性。
![圖片描述][1]
接下來,就想下面的這個圖片展現的,你可能建立一個微服務,訂閱這個主題,拉取處理kafka的數據。一個微服務的多個實例能夠提供高伸縮性和容錯性。遺留功能就扔能夠在你測試或者微調的
微服務中保存下來。
![圖片描述][2]


而後,想接下來的這個圖片展現的,你可能會修改這個龐然大物般的系統,讓其調用HTTTP與新的微服務交互,來代替所有的業務邏輯都走自身體統
![圖片描述][3]

這個內部的業務邏輯從原本的龐大的系統,遷移到了新的微服務或者一組微服務中。而這也只是將功能點前移除龐大系統的一種高層次的方式

9.制定特別的微服務安全

不管你是從一個亂寫的,或者分解一個龐然大物般的大系統進微服務,下面的這些問答能夠幫助你:
問:一個服務職能作一件事嗎?
答:是的。若是你不能使用一個短句就能完整的表示一個爲服務於的完整目的,那麼你的服務可能會龐大,例如:
    >一個適當大小的服務:「這個服務在用戶之間管理者友好的關係」
    >服務執行多種功能,應該被分解掉:「這個服務管理着用戶的朋友關係,聚合全部的用戶的朋友的活動,因此它能夠被消費掉」
問:服務應該是自治的嗎?
答:一個服務應該爲本身的行爲負責。不該該依賴於其餘的服務來處理它的事情。
    例如,考慮一個訂單服務,服務的協議容許你建立一筆訂單,添加訂單的各類分類。添加支付的詳情,確認訂單的支付。然而,有一個其餘的系統處理這支付,若是這堵的服務沒有運行會
    怎麼樣呢??這種依賴性意味着訂單服務不是自治,它依賴了支付這個領域
    一個自治服務會接受確認請求不管支付服務的狀態。
    一個自治的服務應該接收確認請求,不管付款服務的狀態是什麼。他還有多是異步的方式,確保付款最終被處理完成。
問:這項服務擁有其本身的數據嗎?
答:一個服務,若是他是惟一的從數據庫中寫和讀的服務,那麼它就能夠擁有本身的數據。
若是你發現你設計的多個服務從同一個數據庫拿取數據,那麼就該考慮下設計了。選擇一個服務做爲全部者,須要其餘服務使用該服務的協議取讀取

10.內部和外部的交互服務器

如前面在第二小節討論的,服務應該被隔離而且是自治的。這樣的服務經過網絡發送消息的形式,與其餘的服務進行交互。爲了實現服務的實現性能和韌性,你應該常常一般是在在不一樣的節點
運行行多個相同的服務實例,內部的交互也是在網絡上。此外,第三方和/或遺留系統也可能爲microservice系統消耗或提供信息。
下列主題更詳細地討論這些通訊路徑:
①在微服務內部交互
在原則上類似,可是網絡上的交互和內部的交互有着不一樣的須要,Lagom提供了多種實現選項。服務間通訊必須使用鬆耦合的協議和保持隔離和自治的消息格式。協調不一樣服務之間的變動可能會很困難,並且成本高昂。您能夠利用如下的優點在您的系統中實現這一點:
    >Service calls,要不一樣步,要麼異步,容許服務去與其餘的服務使用發佈的API和標準的協議(例如HTTP協議或者說是WenSocket)進行交互。
    >發佈消息到代理,例如像時候Apache的kafka,將進一步實現解耦。Lagom的Message Broker API(消息代理代理API)提供了至少一次的語義。若是一個新實例開始發佈信息,它的消息被添加到先前發出的事件中。若是一個新實例訂閱一個主題,它們將接收全部事件、過去、當前和將來(只要它們已訂閱)。
    
單個服務的節點(統稱爲一個集羣)須要更小的耦合。他們共享相同的代碼,並由一個團隊或我的共同管理。因爲這個緣由,服務間通訊能夠能夠利用具備較少開銷和更好性能的機制。例如:
    >不少lagom的組件內部使用AKKA remoting。你能夠直接在你的服務中使用它
    >分佈式的發佈-訂閱能夠被用用於低延遲,節點之間至多一次消息。限制包括:
        1.網絡中斷會致使消息丟失。
        2.當一個新實例啓動時,加入集羣,並訂閱,它將不會收到在訂閱以前發送的消息。
    >數據庫和其餘持久性存儲能夠看做是服務通訊的節點的另外一種方式.對於使用持久實體的微服務,lagom鼓勵使用事件流,並且它還能夠運用異步的交互,並能夠經過事件日誌提供保證。

這張圖展現了在三個服務器上分佈的lagom系統中各種型的服務間和服務內通訊。在示例中,Order服務發佈到一個或多個Kafka主題,而用戶服務訂閱該信息。用戶服務使用Akka remoting與其餘用戶服務實例(集羣成員)進行通訊。經過在服務調用中流傳輸服務和用戶服務交換信息
    ![圖片描述][4]
    
在微服務系統以外與各方進行溝通
Lagom促進了異步通訊的使用,在必要時不阻止同步通訊的使用。第三方能夠從發佈到代理API的Lagom服務異步獲取數據,並享受至少一次的保證。Lagom服務還公開了第三方以同步交換數據的API。這一般映射到HTTP。Lagom服務api也經過websocket支持將數據流到外部客戶端。有關更多信息,請參見服務描述符。
與外部世界的交互可能意味着使用互聯網服務的客戶,如瀏覽器、移動應用程序或物聯網設備。在使用標準HTTP或WebSockets時,典型的客戶機不直接與單個服務通訊。一般,網絡邊界做爲一個邊界,一個受控制的通訊點充當外部世界與內部世界之間的中介。在Lagom,這個通訊點是一個服務網關。設想你的微服務系統是一箇中世紀的城市,周圍有一堵牆,只有一扇門提供進出的惟一通道。牆壁內的交流是免費和直接的,可是來自外部世界的通訊必須經過服務網關,以下圖所示:
![圖片描述][5]

11.註冊和發現服務

爲了具備彈性和可擴展性,系統必須支持位置透明性。這就能夠容許你在不一樣的主機上運行相同的微服務實例,當出現問題的時候可讓一個實例從一個主機到另外的地方,增長主機的數量以實現負載變化。在這樣的反應系統中,微服務實例一直在移動,客戶端和其餘微服務都須要一種方法來定位可用的服務實例
在開發期間,Lagom爲您的微服務系統提供如下功能:
1.服務註冊
2.客戶端服務發現
3.服務端服務發現

服務註冊:
服務註冊表與微服務實例進行協做,以維護最新的查找表。註冊表包括每一個可用的微服務實例的主機和端口。當負載變化時,系統能夠在任何位置生成或銷燬實例,同時繼續知足請求。您能夠設計一個系統,使微服務可以自動註冊,或者您可使用第三方註冊服務

當啓動一個Lagom microservice實例時,註冊者將註冊微服務的名稱,服務註冊表上的本地服務描述符的URL和名稱,這樣他們就能夠被定位了。在爲服務提供一個實例時,註冊員也必須更新服務註冊表。Lagom的開發環境提供了一個服務註冊中心和註冊中心的實現,這樣您就能夠在本地運行您的微服務。
許多可用的技術提供服務註冊中心功能,您須要選擇和/或爲您的服務開發一個服務定位器,以便在您的部署環境中運行(例如,Lagom ZooKeeper服務定位器)。你可能須要找到一種方法來將你的Lagom服務與註冊商鏈接起來。Lagom的ConductR(這個東西我會在快速開始的那個裏面講)方式的集成使得這兩個步驟無縫銜接。

客戶端一端的服務發現
引自Bonér’s 的Reactive Microservices Architecture: Design Principles for Distributed Systems書:
    一旦存儲了每一個服務的信息,就能夠經過服務註冊中心提供服務,服務註冊中心可使用一個名爲客戶端服務發現的模式來查找信息
Lagom爲每一個服務描述符建立服務客戶機,以便應用程序能夠與Lagom服務進行交互。假設一個非lagom應用程序想要使用hello服務,它可使用welcome service客戶端並簡單地調用hello方法。welcome service的客戶端想要使用服務註冊表,找到一個有效的 URL,在那個地址下welcome服務是可用和完成請求。這種方法須要使用Lagom提供的代碼。在生產中,插入服務的服務定位器將是參與此客戶端發現的一個元素。在後續的快速開始哪裏的Integrating with non-Lagom services這一節,你能夠看到更多使用狀況.

服務端發現:
引自Bonér’s 的Reactive Microservices Architecture: Design Principles for Distributed Systems書:
    另外一個策略是信息存儲和維護在一個負載均衡器[…]使用一種稱爲服務器端服務發現的模式。
若是不能在每一個客戶機上嵌入服務定位器,則可使用服務器端服務發現。此模式使用服務網關容許客戶端使用服務描述符註冊提供的端點。在這個模型中,瀏覽器只須要知道服務網關在哪裏。當使用服務器端發現時,只有在調用被添加到ACL時才能到達服務描述符的調用。
例如,瀏覽器能夠經過請求服務網關中的/ hello / steve路徑向用戶顯示hello消息。這時服務網關將會知道哪個服務提供這個端點,並且會向服務註冊中心請求該服務的一個實例。服務註冊中心將能夠響應請求的實例的主機和端口返回。最後,服務網關將執行請求並將結果返回給瀏覽器。
爲了簡化服務器端服務發現的測試,Lagom開發環境下會啓動全部服務以及服務註冊中心和服務網關。

12.使用不可變的對象 (immutable objects)

一個從被建立了以後就不能夠被修改的不可變對象有以下的優勢:
    >基於不可變對象的代碼更清晰,更有多是正確的。涉及意外變化的錯誤根本沒法發生。
    >多個線程能夠同時安全地訪問不可變的對象。
在Lagom中,不可變對象在以下的幾個地方是必須的,例如:
    >服務請求和響應類型
    >持久的實體命令、事件和狀態
    >發佈和訂閱郵件
Lagom並不關心如何定義不可變對象。您能夠手工編寫構造函數和getter,可是咱們建議使用第三方工具來生成它們。使用第三方工具,如Immutables工具或Lombok,比手工編寫更容易,也更不易出錯,並且生成的代碼更短,更容易閱讀。
如下各節將提供關於immutables的更多信息:
    >Mutable and immutable examples(可變和不可變的例子)
    >Lombok的例子
    >Immutables tool example(Immutables 工具的例子)
Mutable and immutable examples(可變和不可變的例子):
    在一個可變對象的下面例子中,setter方法能夠用於在構建後修改對象:
    ![圖片描述][6]
簡單的不變性
Lombok example
    下面的示例展現了使用Lombok實現的用戶的定義。Lombok爲您處理如下細節
        >將屬性變爲privte和final
        >爲每個屬性建立getter方法
        >重寫equals和hashcode方法和更加友好的toString
        >建立一個滿屬性的構造器
    下面是樣例,使用的是註解方式
    ![圖片描述][7]
    上圖中的實例並無展現出Lombok的一些其餘很是有用的註解,例如@Builder或者@Wither,它們能夠幫助你建立生成器和複製方法。請注意,Lombok不是一個不可更改的庫,而是一個代碼生成庫,這意味着一些設置可能不會建立不可變的對象。例如:Lombok的@Data是等價於@Lombok的@Value。可是還會合成可變方法。當建立不可變類不要使用Lombok的@Data
    那麼如何使用Lombok呢??
    step1.加入maven
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.12</version>
        </dependency>
    step2.與IDE集成
        與IntelliJ IDEA 集成,你須要一個Lombok Plugin for IntelliJ IDEA插件,並開啓註解驅動。 (Settings / Build,Execution,Deployment / Compiler / Annotation Processors and tick Enable annotation processing)
        與eclipse集成:run運行 java -jar lombok.jar,這裏有小視頻:https://projectlombok.org/
        
        
Immutables tool example(Immutables工具樣例)
    下面是使用Immutables的用戶(如上面的ImmutableUser)的相應定義:
    ![圖片描述][8]
    mmutables generates for you:
        >構建器(在類有不少字段時很是方便)
        >正確的實現,hashCode,toString,equals
        >來基於舊的實例來複制方法來建立新實例,例如 withEmail
    使用方法step1.
        <dependency>
            <groupId>com.lightbend.lagom</groupId>
            <artifactId>lagom-javadsl-immutables_2.11</artifactId>
            <version>${lagom.version}</version>
        </dependency>
    step2.與IDE集成
        eclipse:https://www.lagomframework.com/documentation/1.3.x/java/ImmutablesInIDEs.html#Eclipse
        IDEA:https://www.lagomframework.com/documentation/1.3.x/java/ImmutablesInIDEs.html#IntelliJ-IDEA
    
    Collections:
        若是一個不可變對象包含一個集合,那麼集合也必須是不可變的。
        下面是一個具備可變集合的對象的例子:
        ![圖片描述][9]
        上述的例子,只有final的private屬性,方法不提供屬性的set方法,只提供getter方法。可是,列表對象是能夠產生原處修改的,好比咱們調用getter()方法獲取到集合,可是咱們就能夠調用集合的add方法。
        一個可能的修復將使列表防護在構造函數複製和使用 Collections.unmodifiableList 在 getter,像這樣︰
        ![圖片描述][10]
        但這種方式,進行編碼時,它是容易犯錯誤,咱們再次建議想下面這樣讓不可變的處理:
        下面的這是ImmutableUser2的定義:
        ![圖片描述][11]
        getPhoneNumbers方法將返回一個實例com.google.common.collect.ImmutableList    
    guava和PCollections
        如上面所示,不可變對象默認使用Guava immutable collections 
        Guava collections要比簡單的java.util.collections要好。可是Guava在某些操做的時候是稍顯笨重的(例如:對於當前存在的collection作一個稍微修改的拷貝)
        所以,咱們推薦pcollection,它是一個集合庫,它是爲不可變性和效率而設計的。
        上面的示例看起來像使用一個PCollection:
        ![圖片描述][12]        
        這是如何定義由空集合初始化的可選集合
        ![圖片描述][13]
        
        持久化‘collections’
        有兩種不一樣的,有可能混淆的用法的關於數據的「持久化」一次。、
        您將在pcollection文檔和其餘地方看到「持久」數據結構的引用。「」持久化「」這個單詞的意思意味着即便您構建了一個已修改的集合副本的最初的‘persists’.在本文檔的其他部分中,「持久化」指的是持久存儲,如持久化實體和下面的示例。
    進一步的閱讀:
    Immutables文檔在這裏有更多關於不可變集合的詳細信息。https://immutables.github.io/immutable.html#array-collection-and-map-attributes

13.管理數據持久性

在設計微服務時,請記住每一個服務都應該擁有它的數據並直接訪問數據庫。其餘服務應該使用服務API來與數據交互。必須在不一樣的服務之間不共享數據庫,由於這會致使服務之間過於緊密的耦合。這樣,每一個微服務都在一個清晰的邊界內運行,相似於域驅動設計中的有限上下文策略模式。
爲了實現這種分離的體系結構,Lagom的持久性模塊促進了事件源和CQRS的使用。事件源是將全部變動捕獲爲域事件的實踐,這是已經發生的事情的不可變事實。例如:在一個使用ES的系統中,當邁克把錢從他的銀行帳戶裏拿出來的時候,這一事件能夠簡單的存儲爲"取出100.00 美圓"。而不是像在CRUD應用程序中進行的複雜交互,在包裝事務提交以前,須要進行各類讀取和更新操做。
 事件源被用於聚合根,像在之前的樣例中(聚合根的信息,能夠去看個人關於聚合根的博文)的帶有惟一標識ID的客戶Mike,,write-side在聚合中保持一致。這樣就能夠很容易地解釋一些事情,好比維護不變量和驗證傳入命令。當你採用這個模型的時候的一個顯著的不一樣點,您須要注意的是,聚合能夠回答特定標識符的查詢,但不能用於服務跨多個聚合的查詢。所以,您須要建立針對服務提供的查詢定製的數據的另外一個視圖。
 Lagom將事件流持久化到數據庫中。事件流處理器、其餘服務或客戶機、讀取和選擇、操做、存儲事件。Lagom提供persistent read-side processors和 message broker topic subscribers。固然,你也可使用raw stream of event建立本身的時間流.
 若是您不想使用事件源和CQRS,您可能應該使用其餘東西,而不是在Lagom中的持久性模塊(不過,咱們建議您先閱讀事件採購的優點。)若是你選擇不使用Lagom的持久性模塊,在Lagom持久性模塊中,CassandraSession提供了用於存儲Cassandra數據的異步API。可是,您可使用任何數據存儲解決方案來實現您的Lagom服務。
 若是您選擇使用其餘東西,而不是Lagom的持久性模塊,記住要使用異步api以得到最佳的可伸縮性.若是你使用阻塞的APIs,例如JDBC或者JPA,您應該經過使用固定/有限大小的專用線程池來仔細管理阻塞api的組件。不要經過幾個異步調用(例如服務API調用)來串聯阻塞。

14.事件源ES的優點

多年來,開發人員實現持久性使用傳統的建立、讀取、更新、刪除(CRUD)模式。正如前面介紹的,若是採購模型實現持久性存儲狀態更改成歷史事件捕獲業務活動發生以前寫的數據存儲。這將事件存儲機制,容許他們被聚合,或者放在一個組與邏輯邊界。事件採購的模式之一,使併發、分佈式系統實現高性能、可伸縮性和彈性。

在一個分佈式體系結構中,事件採購提供瞭如下優勢

>在傳統的CRUD模型中,實體實例一般會表示爲一個可變對象在內存和一個可變行關係數據庫表中。這致使了臭名昭著的對象關係阻抗失配。對象關係映射器是用來填補這一鴻溝,但帶來新的複雜性。
事件源ES模型對待數據庫就像對待一個序列化時間的append-only log同樣。它並不試圖對每一個實體的狀態或直接在數據庫模式之間的關係進行建模。這大大簡化了代碼從數據庫中寫入和讀取
>一個實體如何達到其當前狀態的歷史仍在存儲事件。事務型數據和查帳式數據之間的一致性是有保證的,由於這些是相同的數據
>你如今有能力分析事件流和重要的業務信息來自它——也許甚至都不考慮當時的事件設計。你能夠在咱們的系統活動中添加新的視圖而不會使寫入方面更加複雜
>因爲全部類型的事件都都只需添加到數據存儲區,因此它能夠提升寫入性能。這裏沒有更新和刪除
>事件源系統很容易測試和調試。命令和事件能夠模擬用於測試目的。事件日誌提供了一個良好的記錄進行調試。若是在生產中檢測到一個問題,你能夠回放事件日誌在受控環境中瞭解一個實體進入很差
的狀態。

15.讀寫分離

編寫或保存數據的功能與讀取或查詢數據的功能徹底不一樣。實現讀寫分離,可以獨立地提供最好的經驗,試圖將讀和寫的操做封裝一塊兒的模型不多有好的表現。
 在CQRS模式下,寫的一端的實體集中於更新命令,而且您能夠對不一樣類型的查詢和報告做業進行優化。這種分離實現更好的可伸縮性,由於read-side能夠獨立地擴展到多個節點上,而且它一般位於須要大量可伸縮性的read-side上。
 例如:在競價系統中,「take the write」是很是重要的,答覆投標人咱們已儘快接受了投標,這意味着寫吞吐量是最重要的。一樣的應用程序可能會有一些複雜的統計視圖,或者分析師可能會使用這些數據來找出最佳的競標策略和趨勢,這些read-side用例一般須要某種表達性查詢功能和不一樣的數據模型,而不是寫端。將讀取端與寫端分離的結果是最終的一致性,對寫端的更新可能沒法當即在readside中可見。

17.部署可伸縮的彈性系統

實現真正的響應式系統:
 >將您的微服務部署到集羣中,這樣它們就能夠按要求按要求伸縮,而且在面對網絡瓶頸或故障時保持彈性,以及硬件或軟件錯誤
 >確保系統所依賴的組件(例如服務網關和message broker)不暴露單點故障。
 >使用數據存儲的功能來提供冗餘或複製
 您能夠在您的選擇的適當技術上部署,Lagom支持產品套件開箱即用。Lightbend產品套件是爲Llagom的一個完美的匹配。它提供;了以下的特性:
     >一種與打包工件分開管理配置的方法
     >跨多個節點的整合日誌。
     >自動從新啓動意外終止服務的監控系統。
     >可以輕鬆快速地伸縮自如。
     >處理網絡故障,特別是那些可能致使大腦分裂的問題。
     >自動種子節點發現,確保服務的新實例與已經運行的服務聯接相同的集羣。
     >他可以對你的服務進行滾動更新。
     >支持跨集羣的監視服務。
     >在生產前在本地測試服務的能力。

好的,下面請參考另外的文檔Lagom reference guide(Lagom參考指南)

相關文章
相關標籤/搜索