不少开发者都表示他们基于HTTP的API是RESTful的。可是,如同Fielding在他的博客中所说,这些API可能并不都是RESTful的。Leonard Richardson为REST定义了一个成熟度模型,具体包含如下4个层次(摘自IBM):html
使用基于HTTP的协议有以下好处:
• HTTP很是简单而且你们都很熟悉。
• 可使用浏览器扩展(好比Postman)或者curl之类的命令行来测试API。
• 内置支持请求/响应模式的通讯。
• HTTP对防火墙友好的。
• 不须要中间代理,简化了系统架构。
不足之处包括:
• 只支持请求/响应模式交互。可使用HTTP通知,可是服务端必须一直发送HTTP响应才行。
• 由于客户端和服务端直接通讯(没有代理或者buffer机制),在交互期间必须都在线。
• 客户端必须知道每一个服务实例的URL。如以前那篇关于API Gateway的文章所述,这也是个烦人的问题。客户端必须使用服务实例发现机制。
开发者社区最近从新发现了RESTful API接口定义语言的价值。因而就有了一些RESTful风格的服务框架,包括RAML和Swagger。一些IDL,例如Swagger容许定义请求和响应消息的格式。其它的,例如RAML,须要使用另外的标识,例如JSON Schema。对于描述API,IDL通常都有工具来定义客户端和服务端骨架接口。
Thrift
Apache Thrift是一个颇有趣的REST的替代品。它是Facebook实现的一种高效的、支持多种编程语言的远程服务调用的框架。Thrift提供了一个C风格的IDL定义API。使用Thrift编译器能够生成客户端和服务器端代码框架。编译器能够生成多种语言的代码,包括C++、Java、Python、PHP、Ruby, Erlang和Node.js。
Thrift接口包括一个或者多个服务。服务定义相似于一个JAVA接口,是一组方法。Thrift方法能够返回响应,也能够被定义为单向的。返回值的方法其实就是请求/响应类型交互模式的实现。客户端等待响应,并可能抛出异常。单向方法对应于通知类型的交互模式,服务端并不返回响应。
Thrift支持多种消息格式:JSON、二进制和压缩二进制。二进制比JSON更高效,由于二进制解码更快。一样缘由,压缩二进制格式能够提供更高级别的压缩效率。JSON,是易读的。Thrift也能够在裸TCP和HTTP中间选择,裸TCP看起来比HTTP更加有效。然而,HTTP对防火墙,浏览器和人来讲更加友好。java
了解完HTTP和Thrift后,咱们来看下消息格式方面的问题。若是使用消息系统或者REST,就能够选择消息格式。其它的IPC机制,例如Thrift可能只支持部分消息格式,也许只有一种。不管哪一种方式,咱们必须使用一个跨语言的消息格式,这很是重要。由于指不定哪天你会使用其它语言。
有两类消息格式:文本和二进制。文本格式的例子包括JSON和XML。这种格式的优势在于不只可读,并且是自描述的。在JSON中,一个对象就是一组键值对。相似的,在XML中,属性是由名字和值构成。消费者能够从中选择感兴趣的元素而忽略其它部分。同时,小幅度的格式修改能够很容器向后兼容。
XML文档结构是由XML schema定义的。随着时间发展,开发者社区意识到JSON也须要一个相似的机制。一个选择是使用JSON Schema,要么是独立的,要么是例如Swagger的IDL。
基于文本的消息格式最大的缺点是消息会变得冗长,特别是XML。由于消息是自描述的,因此每一个消息都包含属性和值。另一个缺点是解析文本的负担过大。因此,你可能须要考虑使用二进制格式。
二进制的格式也有不少。若是使用的是Thrift RPC,那可使用二进制Thrift。若是选择消息格式,经常使用的还包括Protocol Buffers和Apache Avro。它们都提供典型的IDL来定义消息架构。一个不一样点在于Protocol Buffers使用的是加标记(tag)的字段,而Avro消费者须要知道模式(schema)来解析消息。所以,使用前者,API更容易演进。这篇博客很好的比较了Thrift、Protocol Buffers、Avro三者的区别。
总结nginx
微服务必须使用进程间通讯机制来交互。当设计服务的通讯模式时,你须要考虑几个问题:服务如何交互,每一个服务如何标识API,如何升级API,以及如何处理部分失败。微服务架构有两类IPC机制可选,异步消息机制和同步请求/响应机制。在下一篇文章中,咱们将会讨论微服务架构中的服务发现问题。
原文连接:Building Microservices: Inter-Process Communication in a Microservices Architecture(翻译:杨峰 校对:李颖杰)apache
或许不少人会说 Spring Cloud 和 Dubbo 的对比有点不公平,Dubbo 只是实现了服务治理,而 Spring Cloud 下面有 17 个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面,必定程度来讲,Dubbo 只是 Spring Cloud Netflix 中的一个子集。可是在选择框架上,方案完整度偏偏是一个须要重点关注的内容。编程
根据 Martin Fowler 对微服务架构的描述中,虽然该架构相较于单体架构有模块化解耦、可独立部署、技术多样性等诸多优势,可是因为分布式环境下解耦,也带出了很多测试与运维复杂度。json
根据微服务架构在各方面的要素,看看 Spring Cloud 和 Dubbo 都提供了哪些支持。api
以上列举了一些核心部件,大体能够理解为何以前说 Dubbo 只是相似 Netflix 的一个子集了吧。固然这里须要申明一点,Dubbo 对于上表中总结为“无”的组件不表明不能实现,而只是 Dubbo 框架自身不提供,须要另外整合以实现对应的功能,好比:浏览器
虽然,Dubbo 自身只是实现了服务治理的基础,其余为保证集群安全、可维护、可测试等特性方面都没有很好的实现,可是几乎大部分关键组件都能找到第三方开源来实现,这些组件主要来自于国内各家大型互联网企业的开源产品。安全
另外,因为 Dubbo 是基础框架,其实现的内容对于咱们实施微服务架构是否合理,也须要咱们根据自身需求去考虑是否要修改,好比 Dubbo 的服务调用是经过 RPC 实现的,可是若是仔细拜读过 Martin Fowler 的 microservices 一文,其定义的服务间通讯是 HTTP协议的 REST API。那么这两种有何区别呢?服务器
先来讲说,使用 Dubbo 的 RPC 来实现服务间调用的一些痛点:
相信这些痛点也是为何当当网在 dubbox(基于 Dubbo 的开源扩展)中增长了对 REST 支持的缘由之一。
小结:Dubbo 实现了服务治理的基础,可是要完成一个完备的微服务架构,还须要在各环节去扩展和完善以保证集群的健康,以减轻开发、测试以及运维各个环节上增长出来的压力,这样才能让各环节人员真正的专一于业务逻辑。而 Spring Cloud 依然发扬了 Spring Source 整合一切的做风,以标准化的姿态将一些微服务架构的成熟产品与框架揉为一体,并继承了 Spring Boot 简单配置、快速开发、轻松部署的特色,让本来复杂的架构工做变得相对容易上手一些(若是您读过我以前关于 Spring Cloud 的一些核心组件使用的文章,应该能体会这些让人兴奋而激动的特性,传送门)。因此,若是选择 Dubbo 请务必在各个环节作好整套解决方案的准备,否则极可能随着服务数量的增加,整个团队都将疲于应付各类架构上不足引发的困难。而若是选择 Spring Cloud,相对来讲每一个环节都已经有了对应的组件支持,可能有些也不必定能知足你全部的需求,可是其活跃的社区与高速的迭代进度也会是你能够依靠的强大后盾。
Dubbo 的文档能够说在国内开源框架中算是一流的,很是全,而且讲解的也很是深刻,因为版本已经稳定再也不更新,因此也不太会出现不一致的状况,另外提供了中文与英文两种版本,对于国内开发者来讲,阅读起来更加容易上手,这也是 Dubbo 在国内更火一些的缘由吧。
Spring Cloud 因为整合了大量组件,文档在体量上天然要比 dubbo 多不少,文档内容上还算简洁清楚,可是更多的是偏向整合,更深刻的使用方法仍是须要查看其整合组件的详细文档。另外因为 Spring Cloud 基于 Spring Boot,不少例子相较于传统 Spring 应用要简单不少(由于自动化配置,不少内容都成了约定的默认配置),这对于刚接触的开发者可能会有些不适应,比较建议了解和学习 Spring Boot 以后再使用 Spring Cloud,否则可能会出现不少只知其一;不知其二的状况。
小结:虽然 Spring Cloud 的文档量大,可是若是使用 Dubbo 去整合其余第三方组件,实际也是要去阅读大量第三方组件文档的,因此在文档量上,我以为区别不大。对于文档质量,因为 Spring Cloud 的迭代很快,不免会出现不一致的状况,因此在质量上我认为 Dubbo 更好一些。而对于文档语言上,Dubbo 天然对国内开发团队来讲更有优点。
经过上面再几个环节上的分析,相信你们对 Dubbo 和 Spring Cloud 有了一个初步的了解。就我我的对这两个框架的使用经验和理解,打个不恰当的比喻:使用 Dubbo 构建的微服务架构就像组装电脑,各环节咱们的选择自由度很高,可是最终结果颇有可能由于一条内存质量不行就点不亮了,老是让人不怎么放心,可是若是你是一名高手,那这些都不是问题;而 Spring Cloud 就像品牌机,在 Spring Source 的整合下,作了大量的兼容性测试,保证了机器拥有更高的稳定性,可是若是要在使用非原装组件外的东西,就须要对其基础有足够的了解。
从目前 Spring Cloud 的被关注度和活跃度上来看,颇有可能未来会成为微服务架构的标准框架。因此,Spring Cloud 的系列文章,我会继续写下去。也欢迎各位朋友一块儿交流,共同进步。
原文连接: 微服务架构的基础框架选择:SpringCloud仍是Dubbo
如何将一个系统拆分红SCS(自包含系统)
在进行领域驱动设计(DDD)时,为了尽量下降SCS之间的耦合,每一个SCS应该实现一个 边界上下文 。每一个系统不仅拥有一个领域模型,事实上,一个系统能够包含多个不一样的领域模型。每个模型都有一个边界上下文。例如,在电子商务系统里搜索产品的当前价格时,产品的描述和数量是很重要的。而若是要向客户发货,则还须要其余的信息:产品的重量和客户的收货地址。将系统拆分红边界上下文是构建自包含系统最为有效的方式。
能够经过对用户故事进行分组来定义边界上下文。假设咱们经过全文检索来搜索产品,那么经过分类和推荐来搜索也应该属于相同的边界上下文。固然,有时候拆分并不会有很是清楚的界线,这要取决于搜索的复杂性。
在将系统拆分红SCS时也须要考虑到 用户体验 。用户体验描述了客户与系统之间的交互步骤,好比搜索产品、结帐或注册。每个步骤均可能成为一个SCS。这些步骤之间通常只有不多的依赖。这些步骤之间有承上启下的关系:购物车在结帐时就变成了一个订单,而后完成支付。
SCS不仅处理某种特定的领域对象。例如,使用一个SCS来处理全部的客户数据就没有多大意义:不少不一样的边界上下文都会用到客户数据。因此,为客户单首创建模型并在一个单独的SCS里实现是不可能的事情。若是真的这样子作了,那么每一个须要用到客户数据的系统都会依赖它。这也就是为何在将系统拆分红SCS时须要经过用户故事、边界上下文或用户体验来驱动,这种自上而下的方法会带来低耦合的系统。
虽然在后续有必要识别出公共部分,但这不该该成为关键点。公共逻辑能够被抽取到另外一个系统里,但这意味着SCS会对这个系统产生依赖,它们之间就产生了耦合。
在微服务集成——《微服务设计》读书笔记文章中,咱们说过服务间的消息传递有几种方式,一种是请求/响应技术,另外一种是基于事件的机制。
RPC(远程过程调用)
RPC是Remote Procedure Call的简称。
这是请求/响应技术的一种,它使用本地调用的方式和远程进行交互,如SOAP、Thrift等,好比咱们常使用的WebService和Java RMI,就是这种类型。它先在本地生成桩代码,而后经过桩代码进行远程调用。
RPC会带来一些问题,如Java RMI,其耦合性较紧,同时RPC会对调用进行大量的封装和解封装,同时修改接口时会形成服务的提供方和调用方都要修改。
REST
REST是受Web启发而产生的一种架构风格,REST风格包含的内容不少,Richardson的成熟度模型(http://martinfowler.com/articles/richardsonMaturityModel.html),其中有对REST不一样风格的比较。
REST自己并无提到底层应该使用什么协议,最经常使用的是HTTP,HTTP自己提供了不少功能,这些功能对于实现REST风格很是有用,好比HTTP的动词(GET、POST、PUT等)就能很好地和资源一块儿使用。
在使用REST时,传输的数据格式是XML仍是JSON,这个没有一个定论。
基于HTTP的REST也有缺点:
1.它没法帮你生成桩代码(封装rest请求参数时须要),
2.在要求低延迟的场景下,每一个HTTP请求的封装开销多是个问题,使用TCP、UDP可能更合适。
基于事件的异步协做
这种方式主要有两个部分须要考虑:微服务发布事件消费者接收事件机制。
消息队列(如RabbitMQ)能够同进处理上述两方法的问题。生产者使用API向代理发布事件,代理能够向消费者提供订阅服务,而且在事件发生时通知消费者。这种代理甚至能够跟踪消费者的状态,如标记哪些消息是该消费者已经消费过的。这种系统一般具备较好的可伸缩性和弹性,但这么作会增长开发流程的复杂度,由于你须要一个额外的系统(即消息代理)才能开发及测试服务。
另外一种方式是使用HTTP来传播事件,ATOM是一个符合REST规范的协议,能够经过它提供资源聚合的发布服务,当服务提供方发生改变时,只须要简单地向该聚合发布一个事件便可,消费者会轮询该聚合以查看变化。它的缺点是:HTTP不擅长处理低延迟的场景,并且使用ATOM的话,用户还须要本身追踪消息是否送达及管理轮询等工做。
异步架构有其复杂性,好比,消息丢失了怎么办?消息重试失败了怎么办?消息重发了怎么办?消息请求崩溃了怎么办?咱们能够经过设置最大重试、黑名单、白名单等措施来解决这些问题。但这也意味着复杂性的增长。
参考
《微服务设计》(Sam Newman 著 / 崔力强 张骏 译)
http://www.cnblogs.com/gudi/p/6624917.html