背景
Lagom是JAVA系下响应式 微服务框架,在阅读本文之前请先阅读微服务架构设计,Lagom与其他微服务框架相比,与众不同的特性包括:
- 目前,大多数已有的微服务框架关注于简化单个微服务的构建——这是比较容易的一部分内容。Lagom将其扩展到了微服务所构成的系统,这是大型的系统——也是较为困难的一部分内容,因为在这里我们会面临到分布式系统的复杂性。
- 通信默认是异步的——基于消息和流——但是,如果需要的话,也考虑到了使用其他的方案,如同步的REST。
- 持久化默认是基于事件的——使用事件溯源Event Sourcing和CQRS——但是,如果需要的话,也支持JPA和NoSQL这些技术。
- 完整的集成开发环境,通过这个环境,用一条命令就能管理上百的微服务。在整个服务中,支持自动化地代码热重载,并且能够与IDE以及其他工具进行集成。开发环境是基于生产环境(通过使用ConductR)的,因此支持直接在生产环境下部署和扩展
Lagom是基于Reactive理念的(这种理念定义在Reactive宣言之中)。它有很多特定的含义并且指导了Lagom的设计,其目标在于使直接做“正确的事情”变得更加容易,并为此提供了保护措施,也就是好的默认实现。但是,如果你有合理的理由并且明白自己在做什么的话,也是允许对其进行更改的。
Lagom倡导一些核心的原则,并使它们更易于实现,这些原则如下所示:
- 通过非共享的设计,实现真正的隔离:这意味着Lagom中的服务都是自我管理、松耦合以及位置可变的(对位置透明)——对于可恢复性和弹性来讲,这都是必要的需求。在Lagom中,微服务是基于如下技术构建的:
- Akka Actors:基于Actor模型实现了非共享架构(share nothing architecture),从而提供了隔离性。
- Akka Cluster:微服务系统是由一组独立且互相隔离的服务所组成的,Akka Cluster为这些服务提供了可恢复性、分区、复制、可扩展性以及负载均衡。
- ConductR:从最底层提供了隔离性,为微服务实例实现运行时管理。
- 职责单一:在Unix哲学中,有一条古老的原则:“所编写程序要只做一件事,并将其做好”,这条原则帮助很多开发人员编写的程序符合如下的特点:只有一项目标、很小但是具备定义良好的责任并且能够很容易地与其他小程序进行组合。这是很明智的,在这个更加关注微服务的时代,它会比以往更加重要。这其实与规模大小没有什么关系。微服务这个词其实很糟糕,因为它会让我们关注规模大小和代码行数。通过移除大多数的样板式代码,Lagom会试图简化设计,能够让我们关注于服务的本质,同时创建明晰的协议也会变得很容易,不管这些协议是通过异步消息、请求/响应还是通过持续的流来进行组合的。
- 服务持有其数据::每个服务不仅要有行为,还要持有它的数据,服务会一直延伸到持久层。在Lagom中,默认的持久化模型使用的是事件溯源和CQRS——使用Akka Persistence和Cassandra——它具有很强的可扩展性、易于复制和保持完全的弹性。另外,它的审计和调试也很棒,能够在任意时间点及时地重放和探查事件日志。它还避免了传统的对象-关系阻抗不匹配,过去我们都是使用像JPA和Hibernate这样的ORM技术来摆脱它所带来的困扰。也就是说,使用微服务的一个好处就是服务可以根据所要解决的问题自由选择最合适的持久化模型,也就是所谓的Polyglot Persistence。
- 始终保持异步:在Lagom中,通信和IO默认都是异步和无阻塞的,这也是Reactive系统设计的基石。它的好处在于:通过更高效地使用资源,这种方式更加划算;它有助于最小化系统中对共享资源的竞争(拥挤)——在实现可扩展性、低延迟以及高吞吐量方面,这通常是最大的负担所在;它有助于创建更加松耦合的系统,从而实现动态性、可用性和弹性。基于微服务的系统要拥抱这样的现实,那就是要能够应对如今现实世界的挑战。
技术
AKKA- --- Lagom的持久化,发布订阅和节点都是在AKKA基础上实现的。Lightbend具有即时构建,分布式和弹性的消息驱动程序的工具集 >跨多个服务器扩展微服务,Lagom提供的AKKA Cluster可以提供聚集 >在实现服务描述,Lagom服务可以很‘简小’或者‘流式’,建立在AKKA strams之上Lagomm服务
Cassandra 默认的持久化
Lightbend ConductR容器编排工具,实现弹性服务Guice 类似于playkuangjia,Lagom使用它完成依赖的注入 Play框架 SLF4J & Logback日志 Typesafe Config Library:Lagom和它的许多组件技术是使用类型安全配置库配置 序列化 jackson
相关技术链接
Lagom提供了java和scala的API。java版本的API是假定你已经熟悉了新特定,例如lambda和默认方法,和Optional接口等java1.8的知识。Lagom的绝大多数是用scala实现的,但是这些实现的
细节不是你应该关系你的,你应该知识专注于java的API开发。
Lagom提供的服务接口文档让开发者可以快速的定义接口并立即实现他们。
你使用的那些重要的API包括:
>"服务API":提供了一种方法来声明和实现服务接口以供应客户端使用。位置透明性,客户发现服务通过服务定位器.服务API支持异步流媒体服务之间除了同步请求-响应调用
>消息代理API:提供了可以通过主题进行发现数据的分布式的发布订阅模型。一个话题就是一个允许服务去push或者push数据的通道。
>持久化:为存储数据的服务提供了事件源持久化实体。Lagom管理持久化实体的分布在集群节点,使得我们可以切分和水平扩展。lagom管理持久化实体的分布在集群节点,使得我们可以
切分和水平扩展。Cassandra是作为一个数据库提供开箱即用的,但其他数据库也是支持的。
快速开始
开发环境
1. configuring Java:
* On systems running Linux
* On MacOS
* On Windows systems
java version "1.8.0_74"Java(TM) SE RuntimeEnvironment(build 1.8.0_74-b02)JavaHotSpot(TM)64-BitServer VM (build 25.74-b02, mixed mode)
2. Maven 3.2.1 or higher
To install Maven, see the official Maven installation page.
或 sbt 0.13.5 or higher
Sbt文档documentation
Maven构建安装
mvn archetype:generate -Dfilter=com.lightbend.lagom:maven-archetype-lagom-java
官方但速度比较慢,可以使用阿里云Maven镜像,配置文件参考
从maven官方找到 http://repo1.maven.org/maven2/archetype-catalog.xml
<archetype>
<groupId>com.lightbend.lagom</groupId>
<artifactId>maven-archetype-lagom-java</artifactId>
<version>1.3.3</version>
<description>maven-archetype-lagom-java</description>
</archetype>
我们使用方式如下:
mvn archetype:generate -DgroupId=com.lightbend.lagom -DartifactId=maven-archetype-lagom-java
输入
com.lightbend.lagom:maven-archetype-lagom-java
然后选择最新版本1.3.3, 最新版本可能变化,序号是15
项目结构是
cassandra-config
hello-api
hello-impl
integration-tests
pom.xml
stream-api
stream-impl
运行
mvn lagom:runAll
[info]Starting embedded Cassandra server
..........[info]Cassandra server running at 127.0.0.1:4000[info]Service locator is running at http://localhost:8000[info]Service gateway is running at http://localhost:9000...[info]Service hello-impl listening for HTTP on 0:0:0:0:0:0:0:0:24266[info]Service stream-impl listening for HTTP on 0:0:0:0:0:0:0:0:26230(Services started, press enter to stop and go back to the console...)
在浏览器运行, 看到输出说明正常了。
http://localhost:9000/api/hello/World
示例项目
在官方2个示例项目,我们选择其中一个
git clone https://github.com/lagom/activator-lagom-java-chirper.git
下载后进入目录
运行mvn lagom:runAll
开始下载其相关依赖包,时间较长,其中还包括了前端的React.js打包, 最后输出如下:
从上面我们看到Cassandra数据库监听4000端口,服务locator在8000端口,网关gateway在9000端口, UI是这样的:
模块:
Chirp service: 负责存储聊天,提供存储接口服务
Friend service: 负责用户存储,管理朋友关系
Activity Stream service: 为聊天提供流数据的支持,依赖于 Chirp与Friend 服务
Front-End service: 提供前台用户UI
项目结构
在IntelliJ IDEA中通过Maven导入, 如下图
通讯过程
通过UI的操作,我们能够抓起其通讯的HTTP请求,
1.发消息
POST http://localhost:9000/api/chirps/live/peter HTTP/1.1
Host: localhost:9000
Connection: keep-alive
Content-Length: 34
Accept: */*
Origin: http://localhost:9000
X-Requested-With: XMLHttpRequest
{"userId":"peter","message":"message"}
HTTP/1.1 200 OK
Content-Length: 0
Date: Mon, 19 Jun 2017 13:15:46 GMT
2.用户注册
POST http://localhost:9000/api/users HTTP/1.1
Host: localhost:9000
Connection: keep-alive
Content-Length: 31
Accept: */*
Origin: http://localhost:9000
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36
Content-Type: application/json
Referer: http://localhost:9000/signup
{"userId":"lucy","name":"tian"}
3.用户查询
GET http://localhost:9000/api/users/lucy HTTP/1.1
Host: localhost:9000
HTTP/1.1 200 OK
Content-Length: 44
Content-Type: application/json; charset=utf-8
Date: Mon, 19 Jun 2017 13:17:02 GMT
{"userId":"lucy","name":"tian","friends":[]}
4. 跳过网关,直接查询friend-api,注意我们访问60399端口试试
GET http://localhost:60399/api/users/lucy HTTP/1.1
Host: localhost:60399
5.增加friends
POST http://localhost:9000/api/users/lucy/friends HTTP/1.1
Host: localhost:9000
{"friendId":"peter"}
Summary
“谨慎使用微服务”这句话说的没错。在人们使用微服务时,如果不够谨慎,那么在行业生产中会造成巨大的反作用,如果没有正确使用,你会经历混乱,然后退缩,并且抗拒改变。但是,我们需要注意的是,我们需要一个能够在系统构建层面提供抽象的框架,用于封装架构最佳实践。所以,在构建微服务时遇到的错误或让你头疼的地方。
微服务的用途在于分解一个单体,但其目的不是在于分解一个单体,而是为了能让你更快的向客户和用户实现交付。它们需要更快的交付功能,能够让你的系统容错性更强,具备隔离性,以及能让你的系统随时间变得更强大,随时间发展,以及在系统的寿命周期内变得更加成熟。现在,改变发生的太快,所以快速改变系统,快速构建系统,以及修改它的能力已经成了使用微服务、以及用一致的方式管理微服务者必须注意的一个领域,它能帮助你的系统优雅地走向成熟。
响应式还需要处理容错和灵活性问题,而容错和灵活性是在构建系统时必须考虑的问题。当你仅仅进行响应式编程时,如果你在构建一个单体,或者一个响应性单体,或许你可以暂时忽略它,但是你一旦开始将系统组合起来,那些需要相互连接并协同工作的系统的容错能力、弹性和灵活性就是你必须考虑到的。不依赖一个粗粒度灾难恢复类型的解决方案,这种方案一般仅使用容器、VM或一些东西来说明自己的弹性;而应该在依赖外部容器、或VM、或云平台之前就多多少少在应用层面具备弹性,这两者之间是有些细微差别的。
--------------------------------------------------------------------------------------------------------------------------------------------
今天先到这儿,希望对您在系统架构,团队管理, 项目管理,产品管理 有参考作用 , 您可能感兴趣的文章:
互联网电商购物车架构演变案例
互联网业务场景下消息队列架构
消息系统架构设计演进
互联网电商搜索架构演化之一
企业信息化与软件工程的迷思
企业项目化管理介绍
软件项目成功之要素
人际沟通风格介绍一
精益IT组织与分享式领导
学习型组织与企业
企业创新文化与等级观念
组织目标与个人目标
初创公司人才招聘与管理
人才公司环境与企业文化
企业文化、团队文化与知识共享
高效能的团队建设
项目管理沟通计划
构建高效的研发与自动化运维
某大型电商云平台实践
互联网数据库架构设计思路
IT基础架构规划方案一(网络系统规划)
餐饮行业解决方案之客户分析流程
餐饮行业解决方案之采购战略制定与实施流程
餐饮行业解决方案之业务设计流程
供应链需求调研CheckList
企业应用之性能实时度量系统演变
如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:
作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。