微服务框架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参考指南)

相关文章
相关标签/搜索