微服务间的通讯如何选择

若是咱们想要构建一个生产就绪的系统,那么必需要权衡全部因素,其中选择微服务间的链接方法更是其中的一个难点。编程

做者在本文中介绍了一些常见的通讯方法,并简要概述了其项目背景以及为什么最终选择了RPC。服务器

在决定微服务间链接方法前,咱们须要搞清楚两个概念:网络

  1. 架构风格(Architectural Style)
  2. 传输协议(Transport Protocol)

架构风格

在使用服务时如何造成有效负载?是有状态仍是无状态?咱们应该采用REST、SOAP、JSON、XML,仍是其余消息格式?架构

传输协议

咱们应该用哪一种传输协议?应该采用HTTP、HTTP二、消息总线、TCP socket,仍是UDP?框架

时下流行的通讯方法

一些主流的选项以下:socket

  1. REST over HTTP(S)
  2. 经过Message Broker进行消息传递
  3. RPC (跨语言或单语言)

REST over HTTP(S)

自Roy Fielding提出RESTful架构自提出以来,一直都是备受欢迎的方案,特别是在Web应用的开发中。Fielding提出的约束虽然不是标准,但在声明咱们的API为RESTful以前,应该始终遵循这些约束。编程语言

HTTP上有各类各样的REST,由于没有强制执行的标准。开发人员能够自由选择以JSON、XML或某种自定义格式造成请求有效负载。分布式

REST over HTTP(S)仅意味着使用REST架构风格并经过HTTP(S)发送请求。函数

例如:JSON-RPC微服务

经过Message Broker进行消息传递

该选项基本上经过将微服务链接到集中消息总线来工做,而且服务之间的全部通讯都经过backbone发送消息来完成。

例如:Python中的Nameko

RPC (跨语言或单语言)

远程过程调用在分布式系统中并不新鲜,它经过在网络上的另外一个设备上执行函数/方法/过程来工做。

按照RPC标准,RPC 5531:

  1. RPC应该与传输协议无关:TCP、UDP、egal!所以,不保证可靠性
  2. 事务ID用于确保最多一次的semactics,并容许客户端应用程序匹配对呼叫的回复
  3. 超时和从新链接须要处理服务器崩溃,即便使用了面向链接的协议(TCP)
  4. 不指定服务和客户机的绑定,具体由实现人员决定
  5. RPC实现的强制性要求:

    • 被调用过程的惟一规范
    • 响应消息与请求消息匹配的规定
    • 对调用方进行服务身份验证的规定,反之亦然

例如:gRPC RPyC

项目背景

咱们有一个一体化Web应用(用Django编写),性能尚可接受。有些服务能够做为单独的服务解耦。我正在以渐进的方式将咱们的系统架构转变为微服务架构,其中一项重要工做是决定通讯方式。

为何选择RPC

有不少文章主张用REST替换RPC,说RPC是属于“石器时代”的技术,但也有人说RPC简单易用。而个人立场是中立的,要根据实际的项目来作选择。

如下是项目的主要要求:

  1. 没有单点故障 -> 排除消息队列传递
  2. 错误返回给调用者/客户端/消费者
  3. 提供原生体验的服务接口

因为对调用方的错误返回对咱们很重要,RPC是一个很好的候选,由于许多RPC框架将服务器函数中出现的任何异常返回给RPC函数调用方。

大多数RPC框架消除了message broker的须要,所以避免了单点故障。

大多数RPC框架容许远程过程调用,如:

import my_remote_function
try:
    my_remote_function.validate_user(my_user)
except ValueError as e:
    logging.error(e.message)

还有比RPC更好的选项吗?

RPC框架的类别

RPC框架大体可分为如下两种:

  1. 单语言PRC框架
  2. 跨语言PRC框架

单语框架,仅支持单一编程语言。在Python中这类类别的一个很好的候选者是RPyC。RPyC具备易于使用的标准RPC功能,并使用TCP做为其传输协议。

使用RPyC(单语框架)的优势是不须要编写单独的服务接口。缺点是对不一样Python版本的支持不足,固然,正如其名称所暗示的那样,缺乏对跨语言的支持。

跨语言RPC框架支持多种编程语言,但成本很高。gRPC是我使用的框架之一。

gRPC由Google提供支持,涵盖了从C++、Ruby、Python到Dart的各类编程语言。为了支持多种编程语言,必须定义一个通用的服务契约,一般是协议缓冲区(.proto)文件。Service Contract使用服务器提供的参数定义函数,以及要传输的消息格式。对于gRPC,将协议缓冲区文件编译为特定语言的文件(例如Python中的.py文件),这会在您开始拥有多个版本的service contact时产生问题。这使咱们很难跟踪不一样版本的客户端存根和服务功能。

小结

总结来讲,通讯方式须要case by case地选择,而这些以上基本上是我在选择微服务之间的通讯媒介时所考虑的问题。

相关文章
相关标签/搜索