微服务间的通信如何选择
2018-09-12 11:16
645 查看
Melvin Koh
如果我们想要构建一个生产就绪的系统,那么必须要权衡所有因素,其中选择微服务间的连接方法更是其中的一个难点。
作者在本文中介绍了一些常见的通信方法,并简要概述了其项目背景以及为何最终选择了RPC。
在决定微服务间连接方法前,我们需要搞清楚两个概念:
架构风格(Architectural Style)
传输协议(Transport Protocol)
REST over HTTP(S)
通过Message Broker进行消息传递
RPC (跨语言或单语言)
HTTP上有各种各样的REST,因为没有强制执行的标准。开发人员可以自由选择以JSON、XML或某种自定义格式形成请求有效负载。
REST over HTTP(S)仅意味着使用REST架构风格并通过HTTP(S)发送请求。
例如:JSON-RPC
例如:Python中的Nameko
按照RPC标准,RPC 5531:
RPC应该与传输协议无关:TCP、UDP、egal!因此,不保证可靠性
事务ID用于确保最多一次的semactics,并允许客户端应用程序匹配对呼叫的回复
超时和重新连接需要处理服务器崩溃,即使使用了面向连接的协议(TCP)
不指定服务和客户机的绑定,具体由实现人员决定
RPC实现的强制性要求:
被调用过程的唯一规范
响应消息与请求消息匹配的规定
对调用方进行服务身份验证的规定,反之亦然
例如:gRPC RPyC
以下是项目的主要要求:
没有单点故障 -> 排除消息队列传递
错误返回给调用者/客户端/消费者
提供原生体验的服务接口
由于对调用方的错误返回对我们很重要,RPC是一个很好的候选,因为许多RPC框架将服务器函数中出现的任何异常返回给RPC函数调用方。
大多数RPC框架消除了message broker的需要,因此避免了单点故障。
大多数RPC框架允许远程过程调用,如:
还有比RPC更好的选项吗?
单语言PRC框架
跨语言PRC框架
单语框架,仅支持单一编程语言。在Python中这类类别的一个很好的候选者是RPyC。RPyC具有易于使用的标准RPC功能,并使用TCP作为其传输协议。
使用RPyC(单语框架)的优点是不需要编写单独的服务接口。缺点是对不同Python版本的支持不足,当然,正如其名称所暗示的那样,缺少对跨语言的支持。
跨语言RPC框架支持多种编程语言,但成本很高。gRPC是我使用的框架之一。
gRPC由Google提供支持,涵盖了从C++、Ruby、Python到Dart的各种编程语言。为了支持多种编程语言,必须定义一个通用的服务契约,通常是协议缓冲区(.proto)文件。Service Contract使用服务器提供的参数定义函数,以及要传输的消息格式。对于gRPC,将协议缓冲区文件编译为特定语言的文件(例如Python中的.py文件),这会在您开始拥有多个版本的service contact时产生问题。这使我们很难跟踪不同版本的客户端存根和服务功能。
如果我们想要构建一个生产就绪的系统,那么必须要权衡所有因素,其中选择微服务间的连接方法更是其中的一个难点。
作者在本文中介绍了一些常见的通信方法,并简要概述了其项目背景以及为何最终选择了RPC。
在决定微服务间连接方法前,我们需要搞清楚两个概念:
架构风格(Architectural Style)
传输协议(Transport Protocol)
架构风格
在使用服务时如何形成有效负载?是有状态还是无状态?我们应该采用REST、SOAP、JSON、XML,还是其他消息格式?传输协议
我们应该用哪种传输协议?应该采用HTTP、HTTP2、消息总线、TCP socket,还是UDP?时下流行的通信方法
一些主流的选项如下:REST over HTTP(S)
通过Message Broker进行消息传递
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:
RPC应该与传输协议无关:TCP、UDP、egal!因此,不保证可靠性
事务ID用于确保最多一次的semactics,并允许客户端应用程序匹配对呼叫的回复
超时和重新连接需要处理服务器崩溃,即使使用了面向连接的协议(TCP)
不指定服务和客户机的绑定,具体由实现人员决定
RPC实现的强制性要求:
被调用过程的唯一规范
响应消息与请求消息匹配的规定
对调用方进行服务身份验证的规定,反之亦然
例如:gRPC RPyC
项目背景
我们有一个一体化Web应用(用Django编写),性能尚可接受。有些服务可以作为单独的服务解耦。我正在以渐进的方式将我们的系统架构转变为微服务架构,其中一项重要工作是决定通信方式。为什么选择RPC
有很多文章主张用REST替换RPC,说RPC是属于“石器时代”的技术,但也有人说RPC简单易用。而我的立场是中立的,要根据实际的项目来做选择。以下是项目的主要要求:
没有单点故障 -> 排除消息队列传递
错误返回给调用者/客户端/消费者
提供原生体验的服务接口
由于对调用方的错误返回对我们很重要,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框架大致可分为以下两种:单语言PRC框架
跨语言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地选择,而这些以上基本上是我在选择微服务之间的通信媒介时所考虑的问题。相关文章推荐
- 谈如何选择IM通信系统协议
- 如何选择托管机房,考察其设施和网络质量?
- 如何选择PDU电源配套机柜?
- 如何选择前端框架:ANGULAR VS EMBER VS REACT
- Service 之间如何通信?- 每天5分钟玩转 Docker 容器技术(101)
- 玩转Web之servlet(四)---B/S是如何使用http协议完成通信过程的
- 蜘蛛SEO:如何选择关键字?关键字选择技巧与策略杂谈
- 如何选择一家公司?
- 如何选择与相机相匹配的镜头以达到最佳成像性能
- Reading Club | 算法和人生选择:如何给洗好的袜子排序呢?
- 做消费者满意度调查,如何选择调查对象
- asp.net TreeView安装、使用(如何将TreeView打包发布)(带CheckBox选择框的TreeView的初始化,TreeView客户端操作:选择父节点后自动选择所有子节点,子节点选择后自动选择父节点)(TreeView节点精确定位)
- elementui日期选择,如何设置当天后的日期不能被点击;及默认展示日期效果
- (转)类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?
- 如何将查询结果显示在选择屏幕上的代码
- 如何从seo的维度来选择网站的关键词
- 如何选择开源许可证?
- servlet如何选择request.getRequestDispatcher和response.sendRedirect的使用
- ArrayList、HashTable、List、Dictionary的演化及如何选择使用
- 如何选择RDBMS关系型数据库和Nosql非关系型数据库?