2014 年,James 和 Martin 合作发表了一篇名为Microservices 的文章,详细探讨了当时正流行起来的一种服务架构模式—microservice,并出以下定义:
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API
经过这几年的发展,微服务已经称为架构模式中最火热的名词之一,很多公司已经在实践了
传统的 Web 应用通常分为以下三个部分:
在整体式架构中,服务器部分是一个整体,有以下特点:
整体式架构适合于小型系统,但是当用户数量上升和业务逻辑复杂化了之后,它的缺点也比较明显:
微服务刚兴起的时候,许多人都觉得这只是 SOA 的另一个名字.SOA 概念的形成时间要比 Microservices 早十年左右, Martin(还是那个人)在 2005 年发表过一篇文章 对其进行阐述. 支撑 SOA 的关键是其消息传输架构—企业服务总线(ESB,Enterprise Service Bus),它是对多样系统中的服务调用者和服务提供者的解耦.
ESB 是传统中间件技术与 XML、Web 服务等技术相互结合的产物,用于实现企业应用不同消息和信息的准确、高效和安全传递.同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合
ESB 的基本功能
定义:一个微服务一般完成某个特定的功能,比如订单管理、客户管理等.每个微服务都是一个微型应用,包括商业逻辑和各种接口.有的微服务通过暴露 API 被别的微服务或者应用客户端所用;有的微服务则通过网页 UI 实现.在运行时,每个实例通常是一个云虚拟机或者 Docker 容器。
优点:
缺点:
Scale Cube 的 3D 模型,来自《The Art of Scalability》一书,
使用微服务架构之后,客户端需要与多个微服务进行通讯,如果是客户端与微服务模块间点对点直接通讯,可能会产生以下问题,
API 网关负责服务请求路由、组合及协议转换。客户端的所有请求都首先经过 API 网关,然后由它将请求路由到合适的微服务。 API 网关经常会通过调用多个微服务并合并结果来处理一个请求。它可以在 web 协议(如 HTTP 与 WebSocket)与内部使用的非 web 友好协议之间转换。
如何实现 API 网关:
服务调用,必须有支持进程间的通信,通常有两个选择:
进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法
现在有很多不同的 IPC 技术,服务间通信可以使用同步的请求/响应模式,比如基于 HTTP 的 REST 或者 Thrift. 另外,也可以选择异步的、基于消息的通信模式,比如 AMQP 或者 STOMP
REST: REST 基于 HTTP 协议,其核心概念是资源典型地代表单一业务对象或者一组业务对象,业务对象包括“消费者”或“产品”. REST 使用 HTTP 协议来控制资源,通过 URL 实现,常用的框架有 RAML 和 Swagger.使用基于 HTTP 的协议的有以下优点和缺点:
优点:
缺点:
Thrift: Apache Thrift 是一个 REST 的替代品,实现了多语言 RPC 客户端和服务端调用. Thrift 提供了一个 C 风格的 IDL(Interactive Data Language)定义 API. 通过 Thrift 编译器能够生成客户端存根和服务端框架.编译器可以生成多种语言的代码, 包括 C++、Java、Python、PHP、Ruby、Erlang 和 Node.js。
使用消息模式的时候,进程之间通过异步交换消息消息的方式通信. 客户端通过向服务端发送消息提交请求,如果服务端需要回复,则会发送另一条独立的消息给客户端. 由于异步通信,客户端不会因为等待而阻塞,相反会认为响应不会被立即收到.
当下有大量的开源消息系统可用,如 RabbitMQ、Apache Kafka、Apache ActiveMQ 等. 宏观上,它们都支持一些消息和渠道格式,并且努力提升可靠性、高性能和可扩展性.然而,细节上它们的消息模型却大相径庭. 使用消息机制有它的优缺点: 优点:
使用客户端发现模式时,客户端决定相应服务实例的网络位置,并且对请求实现负载均衡.
客户端查询服务注册表,后者是一个可用服务实例的数据库.然后使用负载均衡算法从中选择一个实例,并发出请求.
客户端通过负载均衡器向某个服务提出请求,负载均衡器查询服务注册表,并将请求转发到可用的服务实例.
如同客户端发现,服务实例在服务注册表中注册或注销.
AWS Elastic Load Balancer(ELB)是服务端发现路由的例子,ELB 通常均衡来自互联网的外部流量, 也可用来负载均衡 VPC(Virtual private cloud))的内部流量. 客户端使用 DNS 通过 ELB 发出请求(HTTP 或 TCP),ELB 在已注册的 EC2 实例或 ECS 容器之间负载均衡. 这里并没有单独的服务注册表,相反,EC2 实例和 ECS 容器注册在 ELB。
HTTP 服务器与类似 NGINX PLUS 和 NGINX 这样的负载均衡起也能用作服务端的发现均衡器
服务注册表是服务发现的核心部分,是包含服务实例的网络地址的数据库,服务注册表需要高可用而且随时更新. 客户端能够缓存从服务注册表中获取的网络地址,然而这些信息最终会过时,客户端也就无法发现服务实例. 因此,服务注册表会包含若干服务端,使用复制协议保持一致性.
参考资料