Skip to content

Latest commit

 

History

History
108 lines (58 loc) · 5.27 KB

微服务通信.md

File metadata and controls

108 lines (58 loc) · 5.27 KB

微服务通信

极客点儿

2020-08-26

之间讲过使用微服务架构是为了降低系统的复杂性。其实不然,微服务不是降低复杂性,而是将复杂性转移了,系统将绝大部分复杂性都转移到微服务之间的通信。

微服务架构实现的好坏,其通信起着至关重要的作用。接下来我们将重点关注在微服务架构中进行通信的三种方式,每一种都有其自己的利弊和权衡。

一、HTTP 通信

1. 同步 HTTP

选择服务如何相互通信时,最直接的方式往往是 HTTP。事实上,我们可以提出一个案例,即所有通信渠道都来自这个渠道。但是除此之外,服务之间的 HTTP 调用是服务到服务通信的可行选择。例如,架构中有两个服务 ServiceAServiceBServiceA 可以调用 ServiceB 来获取数据,反之亦然。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import requests


# 调用 A 服务
def request_service_a(token):

    url = 'http://0.0.0.0:5000/user/'

    params = {'user_id': 1}

    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'token=%s' % token
    }

    response = requests.get(url=url, params=params, headers=headers)

    data = response.json()
    print(data)

    if response.status_code == 200:
        return True
        
    else:
        return False


request_service_a('5e8bca1c9aa34aed6d069be331')

两个服务之间进行同步的 HTTP 调用。这是一种可行的通信模式,但它确实在两种服务之间建立了耦合。

2. 异步 HTTP

这种变化是微妙的。现在, ServiceB 不返回 saved 属性,而是返回一个 statusUrl。这意味着此服务现在正在接收来自第一个服务的请求,并且立即返回一个 URL。此 URL 可用来检查请求的进度。

将两种服务之间的通信从同步转换为异步,第一个服务不再停留等待第二个服务完成,然后再返回其工作。通过这种方法可以使服务彼此隔离,并且耦合松散。缺点是需要在第二个服务上创建额外的 HTTP 请求,它从外部进行轮询,直到请求完成。这也引入了客户端的复杂性,因为必须检查请求的进度。但是,异步通信允许服务直接保持松散耦合。

3. HTTP 通信具体实现:

  • API 调用:微服务之间互相调用,最简单的通信方式。

  • RPC:远程过程调用,由于我们架构是遵从 REST,不考虑 RPC 调用。

  • Socket:通过建立 socket 实现 HTTP 通信。

  • 缓存表:通过 Redis 或者其他缓存服务,将数据缓存到内存中。

  • 冗余表:将 ServiceA 的数据冗余到 ServiceB 中,ServiceB 可以直接使用。

  • 宽表:将所有用到的服务、表、字段等相关信息保存在一张大而全的数据表中,宽表并不遵循数据库的三范式。

二、消息队列

另一种通信模式是基于消息的通信。

HTTP 通信不同,所涉及的服务不直接相互通信。相反,服务将消息推送到其他服务订阅的消息代理。这消除了许多与 HTTP 通信相关的复杂性。

它不需要服务知道该如何相互交流,它消除了直接相互调用的服务需求。相反,所有服务都知道消息代理,并且它们将消息推送到该代理。其他服务可以订阅代理中自己关心的消息。

当然,使用此模式的两个服务之间仍然存在一些耦合。例如,ServiceBServiceA 必须就消息结构的定义以及其中包含什么达成一致。

常见的消息队列方式:

  • QueueManager:可以实现 Python Queue 通过网络访问。

  • RedisQueue:基于 Reids 实现的消息队列。

  • Flask-RQ2:基于 Flask 实现的 RedisQueue

  • RabbitMQ:高级消息队列协议的开源消息代理系统。

  • Kafka:高吞吐量的分布式发布订阅消息系统。

三、事件驱动的通信

最后一种模式是事件驱动模式。这是另一种异步方法,它看起来完全消除了服务之间的耦合。

与消息传递模式不同,事件驱动方法不需要服务必须知道公共消息结构。服务之间的通信通过各个服务产生的事件进行。

此处仍然需要消息代理,因为各个服务会将其事件写入其中。但是与消息方法不同,消费服务不需要知道事件的细节,它们对事件的发生做出反应,而不是产生能会或可能不会传递的信息。

在形式上,这通常被称为**“仅事件驱动的通信”**。每个服务都同意以某种格式将事件推送到代理,这使得通信松散耦合。服务可以监听他们关心的事件,并且提供为响应它们而需要运行的逻辑。

此模式使服务的耦合松散,因为事件中不包含任何有效负载。此方法中的每个服务都会响应事件的发生并运行其业务逻辑。

结论

这些是基于微服务的架构中所有可能的通信模式吗?当然不是。基于同步和异步模式进行通信的方式还有很多种。

但是这三个突出了支持同步与异步的优缺点。在选择时要考虑耦合因素,但也需要考虑开发和调试的具体情况与注意事项。