微服务之间的HTTP通信
由于分布式的性质,不同组件之间的通信是通过网络进行的。我们可以修复存在许多问题的网络,我们的系统随着时间的流逝而具有弹性和可靠性。
随着分布式系统的发展,基于微服务的应用吸引了几乎每个希望随时间增长并在市场竞争中生存下来的组织的兴趣。微服务使我们能够轻松地扩展和管理系统。由于许多团队之间的不懈努力,缩短了开发时间,并且大大缩短了新功能的上市时间。
由于分布式的性质,不同组件之间的通信是通过网络进行的。影响通信的因素太多,可能是安全性,增加的延迟或正在进行的通信突然终止,从而导致基础架构成本增加。因此,要么我们可以修复存在许多问题的网络,要么可以设计我们的系统以使其随着时间的流逝而具有弹性和可靠性。
服务使用网络协议在分布式环境中相互通信。我们使系统具有弹性,可靠性和更快性的解决方案也取决于正确使用协议。对于不同的需求和不同的网络层(即OSI网络模型),我们有各种协议。当我们谈论服务到服务通信或浏览器到服务通信时,HTTP通常被用作事实上的标准。所有基于REST的服务均以此为标准。
但是,我们对HTTP的过多依赖是否正确?HTTP的创建是出于不同的目的,HTTP的创建是为了让浏览器进行后端服务器通信,以使用请求-响应模型来检索某些数据。在当今世界,它甚至被用于服务间通信,从而降低了我们系统的真实功率。
在这里,我将介绍HTTP的问题以及常见用例的可能解决方案。稍后,我将提供有关RSocket的一些详细信息,这些细节可以缓解许多现有问题,并使我们的应用程序完全响应。
HTTP是OSI网络模型中的应用程序层协议。随着时间的推移,HTTP不断发展,并提供了不同的版本供采用。让我们仔细研究它们,并可视化它们所面临的问题。
HTTP / 1.0
如果客户端服务要从另一个服务中检索某些数据,它将首先打开与之连接的连接,然后通过该连接向服务器发送请求。服务器将发送响应并关闭连接。对于每个请求,必须打开一个新连接。因此,每个请求-响应周期的大量额外开销和结果将是通信缓慢。
图1显示了客户端和服务器计算机之间HTTP / 1.0的工作。它还显示了每个请求-响应周期所需的多个连接。
HTTP / 1.1
HTTP / 1.1是对HTTP / 1.0的改进,并提供了持久连接形式的解决方案,并引入了“流水线”功能。因此,客户端可以通过单个连接发送多个请求,该请求只能在配置的时间内保持活动状态。
尽管情况相对有所改善,但这仍然存在一个问题,通常称为“线路阻塞头”。由于此问题,如果单个连接上有多个请求,则这些请求将排队到服务器中,并且仅以相同顺序进行响应。而且,如果您的客户端生成请求的速度很快,或者服务器响应速度很慢,那么这将阻止其他请求被处理。因此,网络中的拥塞导致不必要的延迟。
在由于请求#1而使请求#2面向“行头阻塞”的地方,显示HTTP / 1.1的工作方式。在服务器处理请求并以Response#1响应之前,Request#2将等待服务器端的处理。
HTTP / 2
HTTP / 2是对HTTP / 1.1的改进,并引入了“ Multiplexing ”的新功能。这允许通过单个连接将多个请求作为单独的流发送到服务器,并且服务器将通过流将响应发送回客户端。现在,这种方式的服务间通信相对更快。
如图3所示,HTTP / 2 在单个连接上使用多路复用通道。通过相同的通道发送已处理的响应,该响应可以在其他响应帧之间进行交错。任何延迟或阻止的响应都不会影响其他响应。
文本传输协议
HTTP / 1.x使用文本格式JSON,XML等进行通信,因为这些格式适用于浏览器。出于明显的原因,文本格式使服务器响应易于阅读。但是,当服务彼此通信时,它们不需要文本格式的响应即可解释。他们为什么也需要它?如果服务在对象上工作,则它将以二进制格式驻留在该计算机上,针对其处理进行了优化,然后在通过网络进行序列化之前将其转换为文本,然后在接收端再次反序列化文本并转换回二进制结构以进一步处理这是一项开销,会减慢处理速度并增加处理成本。
HTTP / 2也提供了对此类问题的改进。相反,它使用二进制协议,与文本协议相比,二进制协议解析效率更高,并且更紧凑,更不易出错。仅基于HTTP / 2构建的最新开发的gRPC使用进一步改进的二进制协议Protobuf作为序列化二进制数据的机制,因此生成的数据更简单,更小,并提高了处理速度。因为这是RPC,所以就像在客户端服务中将远程方法作为本地方法调用一样,并删除了许多用于HTTP用法的应用程序级语义的样板代码。
注意:gRPC Protobuf当前仅用于服务间通信,并且消息不可读。gRPC不适用于浏览器,但是许多浏览器都提供对HTTP / 2的支持。
到目前为止,HTTP / 2似乎解决了主要的服务间通信问题。
消息流控制
让我们考虑一个用例,在这种情况下,客户端以比服务器可以处理的速率更高的速率不断轰炸对服务器的请求。这将使服务器超负荷,并使其难以响应。我们需要在应用程序级别进行某种流量控制。
建立在HTTP / 2 和 HTTP / 2之上的gRPC使用TCP作为传输层协议,该协议仅提供字节级流控制。这种类型的流控制将无法在应用程序层限制请求。我们仍然需要应用程序级别的流量控制,或者需要实现断路器以保持系统的响应速度。而且有时我们需要实现重试逻辑以使系统更具弹性。这是构建和管理的开销,仍然由gRPC和 HTTP / 2承担 。
实时更新
另一个用例是客户一直希望自己拥有最新数据。在这种情况下,一种选择是使用HTTP并继续向服务器发送轮询请求,以在可用时获取更新。这样,将生成许多不必要的请求,从而导致不必要的流量和资源使用。
由于HTTP提供了一个单一的交互模型,即Request-Response,因此在这种情况下使用HTTP不是正确的选择。
SSE(服务器发送的事件)是一种将实时更新从服务器流传输到客户端的方法。但这是一个文本协议。
另一种选择是使用Websockets (二进制协议),它也可以使用双向通信通过单个连接为客户端提供实时更新。
由于Websocket是面向连接的,因此在一段时间内重新建立连接后,正在进行的通信中的任何间歇性断开和响应数据恢复都很难管理。
同样,Websockets也存在由于生产商或消费者使用速度相对较快而引起的问题。因此,还需要消息级别的流控制。
添加到列表中的是与使用Websockets时需要管理的应用程序级语义相关的复杂性。
我们为某些问题提供了解决方案,但仍在与其他问题进行权衡。需要一种协议来隐藏其中的所有问题和复杂性,并提供一种用于服务间通信的简单接口,并具有轻松支持所有用例的能力。
RSocket
根据Reactive Manifesto的说法,为了最佳地利用资源,分布式系统需要完全反应。这样的系统更加健壮,响应更快,更具弹性,更加灵活,并且可以更好地满足现代需求。
使用反应式编程开发的应用程序仅使服务具有反应性,并帮助服务更好地利用CPU,内存等可用资源。但是,要成为完全反应性的系统,则意味着所有相关的IO也需要也具有反应性。通常,IO与DB交互以及服务到服务的通信相关联。R2DBC(反应性关系数据库连接)和反应性NoSql驱动程序负责数据库交互和RSocket是要照顾其他以响应方式处理服务间通信的领域。对于RSocket,没有像客户端和服务器这样的东西。一旦客户端与服务器建立连接,两者将变得平等,任何人都可以发起请求,即,通信是双向的。
二进制协议
RSocket(或反应式套接字)是一种二进制协议,它将消息分解为帧,这些帧是字节流。但是,这还允许采用诸如Protobuf,AVRO甚至JSON序列化之类的任何序列化/反序列化机制。
请求多路复用
它为多个逻辑流使用单个物理连接,以在客户端和服务器之间发送数据,从而解决了“线路阻塞头”问题。
多重互动模型
RSocket提供了一个简单的通信接口,可用于多种交互模型:
Request-Response (stream of 1).
Fire-and-Forget (no response).
Request-Stream (finite stream of many).
Channel (bi-directional streams).
所有这些模型都表示异步通信,并以反应性术语的Mono / Flux形式返回延迟的结果。
RSocket是一个应用程序层协议,可以选择在不同的基础传输层协议(例如TCP,Websockets 和 Aeron)之间进行切换。 TCP是服务器-服务器变体的典型选择,Websockets对于服务器浏览器变体将更加有用,而Aeron(基于UDP)可以在吞吐量非常关键的地方使用。
应用语义
与HTTP相比,许多不必要的应用程序语义受到了限制。此外,与由于缺乏简单的应用程序语义而直接在应用程序层难以使用的TCP和Websockets相比,RSocket具有易于使用的语义。
内置流控制
可用的协议使用仅控制字节数的传输级流控制,但是RSocket提供了应用程序级消息流控制,这是现在所需要的。RSocket为客户端和服务器提供流控制:
反应性流,由请求者控制。
响应者控制的租赁语义。
会话恢复
此功能允许恢复长寿命的流,这在网络连接频繁断开,切换和重新连接时,对于移动到服务器的通信很有用。
比HTTP快
作为二进制协议和使用异步通信使得方法RSocket高达10倍快比HTTP (来源: https://www.netifi.com/rsocket)。
与gRPC相比,RSocket的性能也更好,它比HTTP / 2本身提供了性能上的改进。
RSocket的机会
这些功能清楚地表明了超越传统协议(如HTTP)的重要性,至少对于服务间通信(通常支持任何分布式系统的主干网)而言。
基于反应式编程技术堆栈的微服务可以使用反应式通信协议(即RSocket)提高性能和基础架构利用率。
当前环境中的RSocket协议有很多机会,而RSocket协议主要由HTTP主导,但有很多限制。一些示例可能是:
尽管优点不仅仅限于特定行业,但更好的流功能增加了RSocket在实时聊天应用程序,基于GPS的应用程序,带有多媒体聊天的在线教育和协作绘图中的范围。
通过服务间通信交换大量数据的任何基于云的应用程序。
在分布式系统中,希望减少延迟并提高系统速度。
在分布式系统中。希望通过提高CPU利用率并提高内存效率来降低运营成本。
在应用程序中,服务器希望查询一组特定的客户端以在运行时调试某些问题。由于双向行为,可以在现有连接上将请求从服务器发送到客户端。
在 发射后不管功能可用于非关键跟踪的目的。
图4显示了RSocket协议的可能用法,其中使用各种语言实现的多个微服务可以在选择的不同传输层上相互通信。提供应用层语义的RSocket使交互更容易。现在,微服务尚未与协议语义紧密结合,可以使用简单且一致的RSocket接口。