4.2. 异步消息 – AMQP, STOMP, MQTT
异步消息就是客户端不需要一直等待服务应答,有应到后会得到通知。某些微服务需要用到异步消息,一般采用AMQP, STOMP, MQTT。
4.3. 消息格式 – JSON, XML, Thrift, ProtoBuf, Avro
消息格式是微服务中另外一个很重要的因素。SOA的web服务一般采用文本消息,基于复杂的消息格式(SOAP)和消息定义(xsd)。微服务采用简单的文本协议JSON和XML,基于HTTP的资源API风格。如果需要二进制,通过用到Thrift, ProtoBuf, Avro。
4.4. 服务约定 – 定义接口 – Swagger, RAML, Thrift IDL
如果把功能实现为服务,并发布,需要定义一套约定。单体架构中,SOA采用WSDL,WSDL过于复杂并且和SOAP紧耦合,不适合微服务。
REST设计的微服务,通常采用Swagger和RAML定义约定。
对于不是基于REST设计的微服务,比如Thrift,通常采用IDL(Interface Definition Languages),比如Thrift IDL。
5. 微服务集成 (服务间通信)
微服务架构下,应用的服务直接相互独立。在一个具体的商业应用中,需要有些机制支持微服务之间通信。因此服务间的通信机制特别重要。
6
SOA体系下,服务之间通过企业服务总线(Enterprise Service Bus)通信,许多业务逻辑在中间层(消息的路由、转换和组织)。微服务架构倾向于降低中心消息总线(类似于ESB)的依赖,将业务逻辑分布在每个具体的服务终端。
大部分微服务基于HTTP、JSON这样的标准协议,集成不同标准和格式变的不再重要。另外一个选择是采用轻量级的消息总线或者网关,有路由功能,没有复杂的业务逻辑。下面就介绍几种常见的架构方式。
5.1. 点对点方式 – 直接调用服务
点对点方式中,服务之间直接用。每个微服务都开放REST API,并且调用其它微服务的接口。
图4:通过点对点方式通信
很明显,在比较简单的微服务应用场景下,这种方式还可行,随着应用复杂度的提升,会变得越来越不可维护。这点有些类似SOA的ESB,尽量不采用点对点的集成方式。
点对点有下面几个缺点:
7
? ? ? ?
非功能的需求,比如用户授权、限制、监控,需要在每个微服务中进行实现 随着功能的演进,服务会变得越来越复杂。
不同的服务直接,客户端和服务直接没有控制功能(监控、跟踪、过滤) 直接通信在大型系统设计中,一般是反面典型。
因此,如果设计一个大型的微服务系统,尽量避免点对点的通信方式,也不能像ESB这样重量级的总线。而是一个轻量级的总线,能够提供非业务功能的抽象。这就是API网关方式。
5.2. API-网关方式
API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能个。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。
图5:通过API-网关暴露微服务
8
用我们网上商店的例子,在图5中,所有的业务接口通过API网关暴露,是所有客户端接口的唯一入口。微服务之间的通信也通过API网关。
采用网关方式有如下优势:
? 有能力为微服务接口提供网关层次的抽象。比如:微服务的接口可以各种各样,在网关层,可以对外暴露统一的规范接口。
? ? ?
轻量的消息路由、格式转换。
统一控制安全、监控、限流等非业务功能。
每个微服务会变得更加轻量,非业务功能个都在网关层统一处理,微服务只需要关注业务逻辑
目前,API网关方式应该是微服务架构中应用最广泛的设计模式。
5.3. 消息代理方式
微服务也可以集成在异步的场景下,通过队列和订阅主题,实现消息的发布和订阅。一个微服务可以是消息的发布者,把消息通过异步的方式发送到队列或者订阅主题下。作为消费者的微服务可以从队列或者主题共获取消息。通过消息中间件把服务之间的直接调用解耦。
9
图6:异步通信方式
通常异步的生产者/消费者模式,通过AMQP、MQTT等异步消息规范。
6. 数据的去中心化
单体架构中,不同功能的服务模块都把数据存储在某个中心数据库中。
图7:单体架构,用一个数据库存储所有数据
微服务方式,多个服务之间的设计相互独立,数据也应该相互独立(比如,某个微服务的数据库结构定义方式改变,可能会中断其它服务)。因此,每个微服务都应该有自己的数据库。
10